diff --git a/DESIGN_GUIDELINES.md b/DESIGN_GUIDELINES.md index fd8d3f3bd13..fffe8bc6dbd 100644 --- a/DESIGN_GUIDELINES.md +++ b/DESIGN_GUIDELINES.md @@ -31,9 +31,10 @@ holds `private final UI ui`, and all `executeJs` calls go through `ui.getElement()` or `ui.getPage()`. Follow the `Page` / `History` pattern. Enforce single-instance creation in the constructor if needed. -If the facade hands out a stateful handle (e.g. `Geolocation.track()` -returning a `GeolocationTracker`), make the handle's constructor -**package-private** so application code cannot bypass the facade. +If the facade hands out a stateful handle (e.g. +`Geolocation.watchPosition()` returning a `GeolocationWatcher`), make the +handle's constructor **package-private** so application code cannot bypass +the facade. ### Keep internal mutators off user-facing classes diff --git a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/Geolocation.java b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/Geolocation.java index bd852174c9c..101a86403a3 100644 --- a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/Geolocation.java +++ b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/Geolocation.java @@ -42,21 +42,21 @@ *
* Two usage modes: *
* Button locate = new Button("Use my location");
* locate.addClickListener(
- * e -> e.getUI().getGeolocation()
- * .get(pos -> showNearest(pos.coords().latitude(),
+ * e -> e.getUI().getGeolocation().getPosition(
+ * pos -> showNearest(pos.coords().latitude(),
* pos.coords().longitude()),
- * err -> showManualEntry()));
+ * err -> showManualEntry()));
*
*
* - * Tracking example: + * Watching example: * *
- * GeolocationTracker tracker = UI.getCurrent().getGeolocation().track(this);
+ * GeolocationWatcher watcher = UI.getCurrent().getGeolocation()
+ * .watchPosition(this);
* Signal.effect(this, () -> {
- * switch (tracker.valueSignal().get()) {
+ * switch (watcher.valueSignal().get()) {
* case GeolocationPending p -> {
* // waiting for first reading
* }
@@ -183,8 +184,8 @@ private static GeolocationClient resolveClient(UI ui) {
* browser reports an error instead {@code onError} is invoked with the
* {@link GeolocationError}. The pair mirrors the W3C
* {@code getCurrentPosition(success, error)} signature and matches
- * {@link GeolocationTracker#addPositionListener
- * GeolocationTracker.addPositionListener}, so callers can share the same
+ * {@link GeolocationWatcher#addPositionListener
+ * GeolocationWatcher.addPositionListener}, so callers can share the same
* handler shape between one-shot and watch APIs.
*
* The call returns immediately. The browser may show a permission dialog on
@@ -198,9 +199,9 @@ private static GeolocationClient resolveClient(UI ui) {
* invoked with the error if the browser reports one; not
* {@code null}
*/
- public void get(SerializableConsumer onSuccess,
+ public void getPosition(SerializableConsumer onSuccess,
SerializableConsumer onError) {
- get(onSuccess, onError, null);
+ getPosition(onSuccess, onError, null);
}
/**
@@ -222,14 +223,14 @@ public void get(SerializableConsumer onSuccess,
* accuracy / timeout / cache-age tuning, or {@code null} to use
* the browser defaults
*/
- public void get(SerializableConsumer onSuccess,
+ public void getPosition(SerializableConsumer onSuccess,
SerializableConsumer onError,
@Nullable GeolocationOptions options) {
Objects.requireNonNull(onSuccess, "onSuccess callback cannot be null");
Objects.requireNonNull(onError, "onError callback cannot be null");
client.get(options).whenComplete((outcome, error) -> {
if (error != null) {
- LOGGER.debug("Geolocation get() failed", error);
+ LOGGER.debug("Geolocation getPosition() failed", error);
onError.accept(new GeolocationError(
GeolocationErrorCode.UNKNOWN.code(),
"Client-side geolocation bridge failure"));
@@ -247,8 +248,8 @@ public void get(SerializableConsumer onSuccess,
* component's lifecycle.
*
* The browser reports new positions whenever it detects movement. Each
- * report is delivered to the returned tracker's
- * {@link GeolocationTracker#valueSignal() valueSignal()} signal on the UI
+ * report is delivered to the returned watcher's
+ * {@link GeolocationWatcher#valueSignal() valueSignal()} signal on the UI
* thread. The initial value is {@link GeolocationPending} until the first
* reading arrives, then transitions to {@link GeolocationPosition} (updated
* on every subsequent reading) or {@link GeolocationError}.
@@ -256,52 +257,52 @@ public void get(SerializableConsumer onSuccess,
* The underlying browser watch is automatically cancelled when
* {@code owner} detaches, so the application does not need to write cleanup
* code for navigation. For cancelling while the view is still attached
- * (e.g. a "Stop tracking" button), call {@link GeolocationTracker#stop()}
- * on the returned tracker.
+ * (e.g. a "Stop watching" button), call {@link GeolocationWatcher#stop()}
+ * on the returned watcher.
*
* Permission-revoke caveat. If the user revokes geolocation
* permission while a watch is active and then grants it again, the browser
* silently stops delivering position updates to the existing watch — this
* is the W3C Geolocation API's documented behavior across browsers, not a
* Flow-specific limitation. To recover after a revoke/regrant cycle, call
- * {@link GeolocationTracker#stop()} followed by
- * {@link GeolocationTracker#resume()}, which installs a fresh browser
+ * {@link GeolocationWatcher#stop()} followed by
+ * {@link GeolocationWatcher#resume()}, which installs a fresh browser
* watch. Applications that want this to happen automatically can subscribe
* to {@link #availabilitySignal()} with {@code Signal.effect(owner, ...)}
* and trigger the stop/resume when the availability transitions back to
* {@link GeolocationAvailability#GRANTED GRANTED}.
*
* @param owner
- * the component that owns this tracking session; detaching the
+ * the component that owns this watching session; detaching the
* component automatically stops the watch
- * @return a tracker whose {@link GeolocationTracker#valueSignal()} reports
- * progress and whose {@link GeolocationTracker#stop()} cancels the
+ * @return a watcher whose {@link GeolocationWatcher#valueSignal()} reports
+ * progress and whose {@link GeolocationWatcher#stop()} cancels the
* watch
*/
- public GeolocationTracker track(Component owner) {
- return track(owner, null);
+ public GeolocationWatcher watchPosition(Component owner) {
+ return watchPosition(owner, null);
}
/**
* Starts continuously watching the user's position with tuning options,
* tied to the owner component's lifecycle. Behaves like
- * {@link #track(Component)} but lets the caller request high accuracy, set
- * a failure timeout, or accept cached readings. See
+ * {@link #watchPosition(Component)} but lets the caller request high
+ * accuracy, set a failure timeout, or accept cached readings. See
* {@link GeolocationOptions} for the available settings.
*
* @param owner
- * the component that owns this tracking session; detaching the
+ * the component that owns this watching session; detaching the
* component automatically stops the watch
* @param options
* accuracy / timeout / cache-age tuning, or {@code null} to use
* the browser defaults
- * @return a tracker whose {@link GeolocationTracker#valueSignal()} reports
- * progress and whose {@link GeolocationTracker#stop()} cancels the
+ * @return a watcher whose {@link GeolocationWatcher#valueSignal()} reports
+ * progress and whose {@link GeolocationWatcher#stop()} cancels the
* watch
*/
- public GeolocationTracker track(Component owner,
+ public GeolocationWatcher watchPosition(Component owner,
@Nullable GeolocationOptions options) {
- return new GeolocationTracker(owner, options, client);
+ return new GeolocationWatcher(owner, options, client);
}
/**
@@ -317,8 +318,8 @@ public GeolocationTracker track(Component owner,
*
* The signal starts as {@link GeolocationAvailability#UNKNOWN UNKNOWN},
* transitions to the value reported during the initial client bootstrap,
- * and updates on every {@link #get} / {@link #track} outcome and on browser
- * permission-change events where supported.
+ * and updates on every {@link #getPosition} / {@link #watchPosition}
+ * outcome and on browser permission-change events where supported.
*
* Reliability caveats. The value is best-effort, not authoritative —
* it reflects what the browser last reported, and can be briefly stale in
@@ -337,15 +338,15 @@ public GeolocationTracker track(Component owner,
* correctly.
*
On Firefox, permission changes the user makes in browser settings are
* not reliably propagated back — the signal can stay stale until the next
- * {@link #get} or {@link #track} call.
+ * {@link #getPosition} or {@link #watchPosition} call.
* On Chromium, the value updates promptly when the user flips the site
* permission, but there is still a small propagation delay between the
* browser event and the cache update.
*
* Treat the value as a hint for pre-rendering decisions (e.g. auto-fetching
* on return visits, hiding controls in unsupported contexts). For critical
- * paths, call {@link #get} and handle the authoritative result in the
- * callback.
+ * paths, call {@link #getPosition} and handle the authoritative result in
+ * the callback.
*
* @return the availability signal
*/
diff --git a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationAvailability.java b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationAvailability.java
index eeddc8332f2..ce280a21133 100644
--- a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationAvailability.java
+++ b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationAvailability.java
@@ -21,9 +21,9 @@
*
* Returned by {@link Geolocation#availabilitySignal()}. Reading the value does
* not show a permission dialog — it reports whether a dialog would
- * appear on the next {@link Geolocation#get} or {@link Geolocation#track} call,
- * or whether the call would fail regardless because the feature is unusable in
- * this context.
+ * appear on the next {@link Geolocation#getPosition} or
+ * {@link Geolocation#watchPosition} call, or whether the call would fail
+ * regardless because the feature is unusable in this context.
*
* Typical usage:
*
@@ -39,8 +39,8 @@
public enum GeolocationAvailability {
/**
* The user has previously granted permission for this origin. A subsequent
- * {@link Geolocation#get} or {@link Geolocation#track} call will proceed
- * without showing a dialog.
+ * {@link Geolocation#getPosition} or {@link Geolocation#watchPosition} call
+ * will proceed without showing a dialog.
*/
GRANTED,
@@ -53,8 +53,9 @@ public enum GeolocationAvailability {
DENIED,
/**
- * Permission has not yet been decided. The next {@link Geolocation#get} or
- * {@link Geolocation#track} call will show the browser's permission dialog.
+ * Permission has not yet been decided. The next
+ * {@link Geolocation#getPosition} or {@link Geolocation#watchPosition} call
+ * will show the browser's permission dialog.
*/
PROMPT,
diff --git a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationClient.java b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationClient.java
index fc859d89472..8ec4081f852 100644
--- a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationClient.java
+++ b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationClient.java
@@ -104,7 +104,7 @@ Registration subscribeAvailability(
void close();
/**
- * Handle to a tracker watch session. The handle is alive while the
+ * Handle to a watcher watch session. The handle is alive while the
* underlying watch is active; calling {@link #stop()} idempotently tears it
* down.
*/
diff --git a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationError.java b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationError.java
index 1b2d03b070a..8b53e053626 100644
--- a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationError.java
+++ b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationError.java
@@ -20,13 +20,13 @@
* {@link GeolocationPosition}.
*
* This is one of the three possible values of a
- * {@link GeolocationTracker#valueSignal()} signal, and the value passed to the
- * error callback of {@link Geolocation#get Geolocation.get}. Typical
- * application code switches on {@link #errorCode()} to react to the specific
- * reason:
+ * {@link GeolocationWatcher#valueSignal()} signal, and the value passed to the
+ * error callback of {@link Geolocation#getPosition Geolocation.getPosition}.
+ * Typical application code switches on {@link #errorCode()} to react to the
+ * specific reason:
*
*
- * ui.getGeolocation().get(pos -> showNearest(pos), err -> {
+ * ui.getGeolocation().getPosition(pos -> showNearest(pos), err -> {
* switch (err.errorCode()) {
* case PERMISSION_DENIED ->
* showExplanation("Location is blocked for this site.");
diff --git a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationOptions.java b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationOptions.java
index 8429340ae6e..e974b093284 100644
--- a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationOptions.java
+++ b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationOptions.java
@@ -23,8 +23,8 @@
/**
* Tuning knobs for a geolocation request — controls the accuracy / battery /
- * speed / freshness trade-off of a single {@link Geolocation#get} or
- * {@link Geolocation#track} call.
+ * speed / freshness trade-off of a single {@link Geolocation#getPosition} or
+ * {@link Geolocation#watchPosition} call.
*
* Every field is optional. A {@code null} field means "let the browser decide":
* high accuracy defaults to {@code false}, timeout defaults to no timeout at
diff --git a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationOutcome.java b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationOutcome.java
index 8620b15d715..9cd151f9fcd 100644
--- a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationOutcome.java
+++ b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationOutcome.java
@@ -23,8 +23,8 @@
*
* Used as the result type of the internal {@link GeolocationClient#get} future,
* where the sum-type encoding keeps Pending out of the contract. Application
- * code rarely references this type directly: {@link Geolocation#get
- * Geolocation.get} delivers the position or the error through separate
+ * code rarely references this type directly: {@link Geolocation#getPosition
+ * Geolocation.getPosition} delivers the position or the error through separate
* callbacks.
*/
public sealed interface GeolocationOutcome extends GeolocationResult
diff --git a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationPending.java b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationPending.java
index 94596841170..99fba8bc047 100644
--- a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationPending.java
+++ b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationPending.java
@@ -16,10 +16,11 @@
package com.vaadin.flow.component.geolocation;
/**
- * The initial state of a newly started tracking session, held by
- * {@link GeolocationTracker#valueSignal()} until the browser reports its first
- * position or error. One-shot {@link Geolocation#get} requests never produce
- * this value — they deliver a position or an error through separate callbacks.
+ * The initial state of a newly started watching session, held by
+ * {@link GeolocationWatcher#valueSignal()} until the browser reports its first
+ * position or error. One-shot {@link Geolocation#getPosition} requests never
+ * produce this value — they deliver a position or an error through separate
+ * callbacks.
*/
public record GeolocationPending() implements GeolocationResult {
}
diff --git a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationPosition.java b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationPosition.java
index 8f44321cb5a..4b37454a624 100644
--- a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationPosition.java
+++ b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationPosition.java
@@ -22,8 +22,8 @@
* moment in time they were taken.
*
* This is one of the three possible values of a
- * {@link GeolocationTracker#valueSignal()} signal, and the value passed to the
- * success callback of {@link Geolocation#get Geolocation.get}.
+ * {@link GeolocationWatcher#valueSignal()} signal, and the value passed to the
+ * success callback of {@link Geolocation#getPosition Geolocation.getPosition}.
*
* @param coords
* the latitude/longitude and related fields; see
diff --git a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationResult.java b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationResult.java
index deacba3a6e8..4f78d46afd3 100644
--- a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationResult.java
+++ b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationResult.java
@@ -18,18 +18,18 @@
import java.io.Serializable;
/**
- * Anything a tracker can currently hold — a successful reading, an error, or
+ * Anything a watcher can currently hold — a successful reading, an error, or
* the initial "waiting for first reading" state.
*
- * Held by the signal exposed by {@link GeolocationTracker#valueSignal()}. A
+ * Held by the signal exposed by {@link GeolocationWatcher#valueSignal()}. A
* {@code GeolocationResult} is always exactly one of three things:
*
* - {@link GeolocationPending} — the initial state of a newly started
- * tracker, before the browser has reported anything.
+ * watcher, before the browser has reported anything.
* - {@link GeolocationPosition} — a successful reading.
* - {@link GeolocationError} — the browser reported an error.
*
- * One-shot {@link Geolocation#get} requests never produce
+ * One-shot {@link Geolocation#getPosition} requests never produce
* {@link GeolocationPending}; they deliver the position and the error through
* separate callbacks instead.
*
@@ -38,7 +38,7 @@
* at compile time.
*
*
- * switch (tracker.valueSignal().get()) {
+ * switch (watcher.valueSignal().get()) {
* case GeolocationPending p -> showSpinner();
* case GeolocationPosition pos -> map.setCenter(pos.coords());
* case GeolocationError err -> showError(err.message());
diff --git a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationTracker.java b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationWatcher.java
similarity index 86%
rename from flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationTracker.java
rename to flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationWatcher.java
index a81e15611ba..8965f4c71e0 100644
--- a/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationTracker.java
+++ b/flow-server/src/main/java/com/vaadin/flow/component/geolocation/GeolocationWatcher.java
@@ -29,24 +29,24 @@
import com.vaadin.flow.signals.local.ValueSignal;
/**
- * A handle to a geolocation tracking session, returned by
- * {@link Geolocation#track(Component)} /
- * {@link Geolocation#track(Component, GeolocationOptions)}.
+ * A handle to a geolocation watching session, returned by
+ * {@link Geolocation#watchPosition(Component)} /
+ * {@link Geolocation#watchPosition(Component, GeolocationOptions)}.
*
* Exposes the latest {@link GeolocationResult} as a reactive signal via
- * {@link #valueSignal()}, and lets the application cancel tracking via
+ * {@link #valueSignal()}, and lets the application cancel watching via
* {@link #stop()} or resume it via {@link #resume()}. The underlying browser
* watch is also cancelled automatically when the owning component detaches, so
* most applications never need to call {@code stop()} explicitly — it is
- * provided for "Stop tracking" buttons and similar mid-view cancellation.
+ * provided for "Stop watching" buttons and similar mid-view cancellation.
*
- * A tracker is reusable: after {@link #stop()} you can call {@link #resume()}
- * to resume tracking on the same handle, and any effects or bindings subscribed
+ * A watcher is reusable: after {@link #stop()} you can call {@link #resume()}
+ * to resume watching on the same handle, and any effects or bindings subscribed
* to {@link #valueSignal()} continue to work. Bind a toggle button's state to
* {@link #activeSignal()} to let the UI react to start/stop without tracking
* your own flag.
*/
-public class GeolocationTracker implements Serializable {
+public class GeolocationWatcher implements Serializable {
private final ValueSignal valueSignal = new ValueSignal<>(
new GeolocationPending());
@@ -68,7 +68,7 @@ public class GeolocationTracker implements Serializable {
private GeolocationClient.@Nullable WatchHandle handle;
private @Nullable Registration detachRegistration;
- GeolocationTracker(Component owner, @Nullable GeolocationOptions options,
+ GeolocationWatcher(Component owner, @Nullable GeolocationOptions options,
GeolocationClient client) {
this.owner = owner;
this.options = options;
@@ -77,7 +77,7 @@ public class GeolocationTracker implements Serializable {
}
/**
- * Returns a read-only signal that holds the most recent tracking result.
+ * Returns a read-only signal that holds the most recent watching result.
*
* Combine with {@code Signal.effect(owner, ...)} or an attach listener to
* run code whenever the value changes — the effect re-runs automatically on
@@ -102,17 +102,17 @@ public Signal valueSignal() {
}
/**
- * Returns a read-only signal that indicates whether the tracker is
+ * Returns a read-only signal that indicates whether the watcher is
* currently receiving updates. Flips to {@code true} on {@link #resume()}
* and to {@code false} on {@link #stop()} (or when the owner detaches).
*
* Subscribe with {@code Signal.effect(owner, ...)} to bind a toggle
- * button's label/state to the tracker without tracking a separate flag.
+ * button's label/state to the watcher without tracking a separate flag.
* Inside a reactive context, call {@code activeSignal().get()} to
* subscribe; outside a reactive context, call {@code activeSignal().peek()}
* for a snapshot.
*
- * @return a read-only signal reporting whether tracking is active
+ * @return a read-only signal reporting whether watching is active
*/
public Signal activeSignal() {
return activeSignalReadOnly;
@@ -159,12 +159,12 @@ public Registration addPositionListener(
* Starts, or resumes, the underlying browser watch.
*
* Called automatically from the constructor so that a freshly created
- * tracker is immediately active. Call again after {@link #stop()} to resume
- * tracking on the same handle — any effects or bindings subscribed to
+ * watcher is immediately active. Call again after {@link #stop()} to resume
+ * watching on the same handle — any effects or bindings subscribed to
* {@link #valueSignal()} stay attached and start receiving new updates.
*
* The signal is reset to {@link GeolocationPending} on every resume.
- * Calling {@code resume()} on an already-running tracker is a no-op.
+ * Calling {@code resume()} on an already-running watcher is a no-op.
*/
public void resume() {
if (activeSignal.peek()) {
@@ -206,13 +206,13 @@ private void handleResult(GeolocationResult result) {
*
* The browser stops reporting position updates and {@link #valueSignal()}
* stops changing. The last value remains readable. This is the way to end
- * tracking from application code (e.g. a "Stop" button) — leaving the view
+ * watching from application code (e.g. a "Stop" button) — leaving the view
* automatically calls this method, so there is no need to call it from a
* detach listener.
*
- * Idempotent and always safe: calling it twice, or calling it on a tracker
+ * Idempotent and always safe: calling it twice, or calling it on a watcher
* whose owner has already detached, does nothing extra. After
- * {@code stop()} the tracker can be resumed with {@link #resume()}.
+ * {@code stop()} the watcher can be resumed with {@link #resume()}.
*/
public void stop() {
if (!activeSignal.peek()) {
@@ -230,10 +230,10 @@ public void stop() {
}
/**
- * Returns the active watch handle, or {@code null} if the tracker is not
+ * Returns the active watch handle, or {@code null} if the watcher is not
* currently active.
*
- * @return the active watch handle, or {@code null} if the tracker has been
+ * @return the active watch handle, or {@code null} if the watcher has been
* stopped or auto-cancelled
*/
GeolocationClient.@Nullable WatchHandle handle() {
diff --git a/flow-server/src/test/java/com/vaadin/flow/component/geolocation/GeolocationClientSeamTest.java b/flow-server/src/test/java/com/vaadin/flow/component/geolocation/GeolocationClientSeamTest.java
index 6318914ca65..11eef640495 100644
--- a/flow-server/src/test/java/com/vaadin/flow/component/geolocation/GeolocationClientSeamTest.java
+++ b/flow-server/src/test/java/com/vaadin/flow/component/geolocation/GeolocationClientSeamTest.java
@@ -70,7 +70,7 @@ void lookupFactory_resolvedAtConstruction_clientReceivesGetCalls() {
.thenReturn(unused -> fake);
UI freshUi = new MockUI();
- freshUi.getGeolocation().get(pos -> {
+ freshUi.getGeolocation().getPosition(pos -> {
}, err -> {
});
@@ -83,7 +83,7 @@ void setClient_routesGetThroughInstalledClient() {
FakeClient fake = new FakeClient();
ui.getGeolocation().setClient(fake);
- ui.getGeolocation().get(pos -> {
+ ui.getGeolocation().getPosition(pos -> {
}, err -> {
});
@@ -103,36 +103,36 @@ void setClient_closesPreviousClient() {
}
@Test
- void track_handleComesFromCurrentClient() {
+ void watchPosition_handleComesFromCurrentClient() {
FakeClient fake = new FakeClient();
ui.getGeolocation().setClient(fake);
TestComponent owner = new TestComponent();
ui.add(owner);
- GeolocationTracker tracker = ui.getGeolocation().track(owner);
+ GeolocationWatcher watcher = ui.getGeolocation().watchPosition(owner);
- GeolocationClient.WatchHandle handle = tracker.handle();
- assertNotNull(handle, "tracker should expose its watch handle");
+ GeolocationClient.WatchHandle handle = watcher.handle();
+ assertNotNull(handle, "watcher should expose its watch handle");
assertSame(fake.lastWatchHandle, handle,
"handle should be the one returned by client.startWatch");
}
@Test
- void track_handleIsNullAfterStop() {
+ void watchPosition_handleIsNullAfterStop() {
FakeClient fake = new FakeClient();
ui.getGeolocation().setClient(fake);
TestComponent owner = new TestComponent();
ui.add(owner);
- GeolocationTracker tracker = ui.getGeolocation().track(owner);
- tracker.stop();
+ GeolocationWatcher watcher = ui.getGeolocation().watchPosition(owner);
+ watcher.stop();
- assertNull(tracker.handle(),
+ assertNull(watcher.handle(),
"handle() should return null after stop()");
}
@Test
- void get_onErrorReceivesUnknownErrorWhenClientFutureFailsExceptionally() {
+ void getPosition_onErrorReceivesUnknownErrorWhenClientFutureFailsExceptionally() {
FakeClient fake = new FakeClient();
fake.nextGetResult = CompletableFuture
.failedFuture(new RuntimeException(
@@ -141,7 +141,7 @@ void get_onErrorReceivesUnknownErrorWhenClientFutureFailsExceptionally() {
AtomicReference<@Nullable GeolocationPosition> position = new AtomicReference<>();
AtomicReference<@Nullable GeolocationError> error = new AtomicReference<>();
- ui.getGeolocation().get(position::set, error::set);
+ ui.getGeolocation().getPosition(position::set, error::set);
GeolocationError err = error.get();
assertNotNull(err, "onError must fire even when the JS bridge fails");
diff --git a/flow-server/src/test/java/com/vaadin/flow/component/geolocation/GeolocationTest.java b/flow-server/src/test/java/com/vaadin/flow/component/geolocation/GeolocationTest.java
index 8de2b73d68b..93afb00353d 100644
--- a/flow-server/src/test/java/com/vaadin/flow/component/geolocation/GeolocationTest.java
+++ b/flow-server/src/test/java/com/vaadin/flow/component/geolocation/GeolocationTest.java
@@ -149,14 +149,14 @@ void newGeolocation_throwsWhenAlreadyCreated() {
assertThrows(IllegalStateException.class, () -> new Geolocation(ui));
}
- // --- get() tests ---
+ // --- getPosition() tests ---
@Test
- void get_executesPromiseJs() {
+ void getPosition_executesPromiseJs() {
TestComponent component = new TestComponent();
ui.add(component);
- ui.getGeolocation().get(pos -> {
+ ui.getGeolocation().getPosition(pos -> {
}, err -> {
});
@@ -167,13 +167,13 @@ void get_executesPromiseJs() {
}
@Test
- void get_onSuccessReceivesPositionAndOnErrorIsSilent() {
+ void getPosition_onSuccessReceivesPositionAndOnErrorIsSilent() {
TestComponent component = new TestComponent();
ui.add(component);
List positions = new ArrayList<>();
List errors = new ArrayList<>();
- ui.getGeolocation().get(positions::add, errors::add);
+ ui.getGeolocation().getPosition(positions::add, errors::add);
resolvePromise(ui,
resultJson(position(60.1699, 24.9384, 10.0), null, "GRANTED"));
@@ -185,13 +185,13 @@ void get_onSuccessReceivesPositionAndOnErrorIsSilent() {
}
@Test
- void get_onErrorReceivesErrorAndOnSuccessIsSilent() {
+ void getPosition_onErrorReceivesErrorAndOnSuccessIsSilent() {
TestComponent component = new TestComponent();
ui.add(component);
List positions = new ArrayList<>();
List errors = new ArrayList<>();
- ui.getGeolocation().get(positions::add, errors::add);
+ ui.getGeolocation().getPosition(positions::add, errors::add);
resolvePromise(ui, resultJson(null, error(1, "denied"), "DENIED"));
@@ -202,11 +202,11 @@ void get_onErrorReceivesErrorAndOnSuccessIsSilent() {
}
@Test
- void get_updatesAvailabilityFromResponse() {
+ void getPosition_updatesAvailabilityFromResponse() {
TestComponent component = new TestComponent();
ui.add(component);
- ui.getGeolocation().get(pos -> {
+ ui.getGeolocation().getPosition(pos -> {
}, err -> {
});
resolvePromise(ui,
@@ -216,19 +216,20 @@ void get_updatesAvailabilityFromResponse() {
ui.getInternals().getGeolocationAvailabilitySignal().peek());
}
- // --- track() tests ---
+ // --- watchPosition() tests ---
@Test
- void track_registersListenersAndExecutesWatchJs() {
+ void watchPosition_registersListenersAndExecutesWatchJs() {
TestComponent component = new TestComponent();
ui.add(component);
- GeolocationTracker tracker = ui.getGeolocation().track(component);
+ GeolocationWatcher watcher = ui.getGeolocation()
+ .watchPosition(component);
- assertNotNull(tracker);
- assertNotNull(tracker.valueSignal());
+ assertNotNull(watcher);
+ assertNotNull(watcher.valueSignal());
assertInstanceOf(GeolocationPending.class,
- tracker.valueSignal().peek());
+ watcher.valueSignal().peek());
List invocations = ui
.dumpPendingJsInvocations();
@@ -237,11 +238,12 @@ void track_registersListenersAndExecutesWatchJs() {
}
@Test
- void track_signalSurfacesUnknownErrorWhenWatchExecuteJsFails() {
+ void watchPosition_signalSurfacesUnknownErrorWhenWatchExecuteJsFails() {
TestComponent component = new TestComponent();
ui.add(component);
- GeolocationTracker tracker = ui.getGeolocation().track(component);
+ GeolocationWatcher watcher = ui.getGeolocation()
+ .watchPosition(component);
PendingJavaScriptInvocation watchInvocation = ui
.dumpPendingJsInvocations().stream()
@@ -251,25 +253,26 @@ void track_signalSurfacesUnknownErrorWhenWatchExecuteJsFails() {
watchInvocation.completeExceptionally(
JacksonUtils.createNode("module not loaded"));
- GeolocationResult value = tracker.valueSignal().peek();
+ GeolocationResult value = watcher.valueSignal().peek();
GeolocationError err = assertInstanceOf(GeolocationError.class, value,
"watch executeJs failure must surface as a GeolocationError"
- + " on the tracker's valueSignal");
+ + " on the watcher's valueSignal");
assertEquals(GeolocationErrorCode.UNKNOWN, err.errorCode());
assertFalse(err.message().contains("module not loaded"),
"synthesized message must not leak the wrapped client text;"
+ " the cause is logged at DEBUG instead");
- assertTrue(tracker.activeSignal().peek(),
+ assertTrue(watcher.activeSignal().peek(),
"activeSignal stays true on infra failure — its contract"
+ " is tied to resume()/stop(), not data flow");
}
@Test
- void track_signalUpdatesOnPositionEvent() {
+ void watchPosition_signalUpdatesOnPositionEvent() {
TestComponent component = new TestComponent();
ui.add(component);
- GeolocationTracker tracker = ui.getGeolocation().track(component);
+ GeolocationWatcher watcher = ui.getGeolocation()
+ .watchPosition(component);
ObjectNode eventData = JacksonUtils.createObjectNode();
ObjectNode detail = JacksonUtils.createObjectNode();
@@ -289,8 +292,8 @@ void track_signalUpdatesOnPositionEvent() {
eventData);
assertInstanceOf(GeolocationPosition.class,
- tracker.valueSignal().peek());
- GeolocationPosition pos = (GeolocationPosition) tracker.valueSignal()
+ watcher.valueSignal().peek());
+ GeolocationPosition pos = (GeolocationPosition) watcher.valueSignal()
.peek();
assertEquals(60.1699, pos.coords().latitude());
assertEquals(24.9384, pos.coords().longitude());
@@ -303,11 +306,12 @@ void track_signalUpdatesOnPositionEvent() {
}
@Test
- void track_signalUpdatesOnErrorEvent() {
+ void watchPosition_signalUpdatesOnErrorEvent() {
TestComponent component = new TestComponent();
ui.add(component);
- GeolocationTracker tracker = ui.getGeolocation().track(component);
+ GeolocationWatcher watcher = ui.getGeolocation()
+ .watchPosition(component);
ObjectNode eventData = JacksonUtils.createObjectNode();
ObjectNode detail = JacksonUtils.createObjectNode();
@@ -318,8 +322,8 @@ void track_signalUpdatesOnErrorEvent() {
fireEvent(component.getElement(), "vaadin-geolocation-error",
eventData);
- assertInstanceOf(GeolocationError.class, tracker.valueSignal().peek());
- GeolocationError error = (GeolocationError) tracker.valueSignal()
+ assertInstanceOf(GeolocationError.class, watcher.valueSignal().peek());
+ GeolocationError error = (GeolocationError) watcher.valueSignal()
.peek();
assertEquals(GeolocationErrorCode.PERMISSION_DENIED.code(),
error.code());
@@ -327,11 +331,12 @@ void track_signalUpdatesOnErrorEvent() {
}
@Test
- void track_stateTransitionsFromErrorToPosition() {
+ void watchPosition_stateTransitionsFromErrorToPosition() {
TestComponent component = new TestComponent();
ui.add(component);
- GeolocationTracker tracker = ui.getGeolocation().track(component);
+ GeolocationWatcher watcher = ui.getGeolocation()
+ .watchPosition(component);
ObjectNode errEventData = JacksonUtils.createObjectNode();
ObjectNode errDetail = JacksonUtils.createObjectNode();
@@ -340,7 +345,7 @@ void track_stateTransitionsFromErrorToPosition() {
errEventData.set("event.detail", errDetail);
fireEvent(component.getElement(), "vaadin-geolocation-error",
errEventData);
- assertInstanceOf(GeolocationError.class, tracker.valueSignal().peek());
+ assertInstanceOf(GeolocationError.class, watcher.valueSignal().peek());
ObjectNode posEventData = JacksonUtils.createObjectNode();
ObjectNode posDetail = JacksonUtils.createObjectNode();
@@ -355,15 +360,15 @@ void track_stateTransitionsFromErrorToPosition() {
posEventData);
assertInstanceOf(GeolocationPosition.class,
- tracker.valueSignal().peek());
+ watcher.valueSignal().peek());
}
@Test
- void track_autoStopsOnDetach() {
+ void watchPosition_autoStopsOnDetach() {
TestComponent component = new TestComponent();
ui.add(component);
- ui.getGeolocation().track(component);
+ ui.getGeolocation().watchPosition(component);
ElementListenerMap listenerMap = component.getElement().getNode()
.getFeature(ElementListenerMap.class);
@@ -391,7 +396,8 @@ void stop_removesListenersAndQueuesClearWatch() {
TestComponent component = new TestComponent();
ui.add(component);
- GeolocationTracker tracker = ui.getGeolocation().track(component);
+ GeolocationWatcher watcher = ui.getGeolocation()
+ .watchPosition(component);
ElementListenerMap listenerMap = component.getElement().getNode()
.getFeature(ElementListenerMap.class);
@@ -399,7 +405,7 @@ void stop_removesListenersAndQueuesClearWatch() {
.isEmpty());
ui.dumpPendingJsInvocations();
- tracker.stop();
+ watcher.stop();
assertTrue(listenerMap.getExpressions("vaadin-geolocation-position")
.isEmpty());
@@ -417,13 +423,14 @@ void stop_isIdempotent() {
TestComponent component = new TestComponent();
ui.add(component);
- GeolocationTracker tracker = ui.getGeolocation().track(component);
+ GeolocationWatcher watcher = ui.getGeolocation()
+ .watchPosition(component);
ui.dumpPendingJsInvocations();
- tracker.stop();
+ watcher.stop();
ui.dumpPendingJsInvocations();
- assertDoesNotThrow(tracker::stop);
+ assertDoesNotThrow(watcher::stop);
List invocations = ui
.dumpPendingJsInvocations();
assertTrue(invocations.stream().noneMatch(inv -> inv.getInvocation()
@@ -435,11 +442,12 @@ void stop_afterDetach_isNoOp() {
TestComponent component = new TestComponent();
ui.add(component);
- GeolocationTracker tracker = ui.getGeolocation().track(component);
+ GeolocationWatcher watcher = ui.getGeolocation()
+ .watchPosition(component);
ui.remove(component);
ui.dumpPendingJsInvocations();
- assertDoesNotThrow(tracker::stop);
+ assertDoesNotThrow(watcher::stop);
List invocations = ui
.dumpPendingJsInvocations();
assertTrue(invocations.stream().noneMatch(inv -> inv.getInvocation()
@@ -451,21 +459,22 @@ void resume_restartsAfterStop() {
TestComponent component = new TestComponent();
ui.add(component);
- GeolocationTracker tracker = ui.getGeolocation().track(component);
+ GeolocationWatcher watcher = ui.getGeolocation()
+ .watchPosition(component);
ElementListenerMap listenerMap = component.getElement().getNode()
.getFeature(ElementListenerMap.class);
- tracker.stop();
+ watcher.stop();
assertTrue(listenerMap.getExpressions("vaadin-geolocation-position")
.isEmpty());
ui.dumpPendingJsInvocations();
- tracker.resume();
+ watcher.resume();
assertFalse(listenerMap.getExpressions("vaadin-geolocation-position")
.isEmpty());
assertInstanceOf(GeolocationPending.class,
- tracker.valueSignal().peek());
+ watcher.valueSignal().peek());
List invocations = ui
.dumpPendingJsInvocations();
assertTrue(invocations.stream().anyMatch(inv -> inv.getInvocation()
@@ -477,10 +486,11 @@ void resume_isNoOpWhenActive() {
TestComponent component = new TestComponent();
ui.add(component);
- GeolocationTracker tracker = ui.getGeolocation().track(component);
+ GeolocationWatcher watcher = ui.getGeolocation()
+ .watchPosition(component);
ui.dumpPendingJsInvocations();
- tracker.resume();
+ watcher.resume();
List invocations = ui
.dumpPendingJsInvocations();
@@ -493,14 +503,15 @@ void active_signalReflectsResumeAndStop() {
TestComponent component = new TestComponent();
ui.add(component);
- GeolocationTracker tracker = ui.getGeolocation().track(component);
- assertTrue(tracker.activeSignal().peek());
+ GeolocationWatcher watcher = ui.getGeolocation()
+ .watchPosition(component);
+ assertTrue(watcher.activeSignal().peek());
- tracker.stop();
- assertFalse(tracker.activeSignal().peek());
+ watcher.stop();
+ assertFalse(watcher.activeSignal().peek());
- tracker.resume();
- assertTrue(tracker.activeSignal().peek());
+ watcher.resume();
+ assertTrue(watcher.activeSignal().peek());
}
// --- addPositionListener() tests ---
@@ -510,10 +521,11 @@ void addPositionListener_dispatchesPositionAndError() {
TestComponent component = new TestComponent();
ui.add(component);
- GeolocationTracker tracker = ui.getGeolocation().track(component);
+ GeolocationWatcher watcher = ui.getGeolocation()
+ .watchPosition(component);
List positions = new ArrayList<>();
List errors = new ArrayList<>();
- tracker.addPositionListener(positions::add, errors::add);
+ watcher.addPositionListener(positions::add, errors::add);
ObjectNode posData = JacksonUtils.createObjectNode();
ObjectNode posDetail = JacksonUtils.createObjectNode();
@@ -545,9 +557,10 @@ void addPositionListener_registrationStopsDelivery() {
TestComponent component = new TestComponent();
ui.add(component);
- GeolocationTracker tracker = ui.getGeolocation().track(component);
+ GeolocationWatcher watcher = ui.getGeolocation()
+ .watchPosition(component);
List positions = new ArrayList<>();
- Registration registration = tracker.addPositionListener(positions::add,
+ Registration registration = watcher.addPositionListener(positions::add,
err -> {
});
@@ -574,13 +587,14 @@ void addPositionListener_survivesStopResume() {
TestComponent component = new TestComponent();
ui.add(component);
- GeolocationTracker tracker = ui.getGeolocation().track(component);
+ GeolocationWatcher watcher = ui.getGeolocation()
+ .watchPosition(component);
List positions = new ArrayList<>();
- tracker.addPositionListener(positions::add, err -> {
+ watcher.addPositionListener(positions::add, err -> {
});
- tracker.stop();
- tracker.resume();
+ watcher.stop();
+ watcher.resume();
ObjectNode posData = JacksonUtils.createObjectNode();
ObjectNode posDetail = JacksonUtils.createObjectNode();
@@ -603,15 +617,16 @@ void addPositionListener_pendingIsSilent() {
TestComponent component = new TestComponent();
ui.add(component);
- GeolocationTracker tracker = ui.getGeolocation().track(component);
+ GeolocationWatcher watcher = ui.getGeolocation()
+ .watchPosition(component);
List positions = new ArrayList<>();
List errors = new ArrayList<>();
- tracker.addPositionListener(positions::add, errors::add);
+ watcher.addPositionListener(positions::add, errors::add);
// resume() resets the signal to Pending — listeners must stay silent
// since they only see real outcomes.
- tracker.stop();
- tracker.resume();
+ watcher.stop();
+ watcher.resume();
assertTrue(positions.isEmpty());
assertTrue(errors.isEmpty());
diff --git a/flow-tests/test-root-context/src/main/java/com/vaadin/flow/uitest/ui/GeolocationView.java b/flow-tests/test-root-context/src/main/java/com/vaadin/flow/uitest/ui/GeolocationView.java
index abcd8381986..a0e394093c1 100644
--- a/flow-tests/test-root-context/src/main/java/com/vaadin/flow/uitest/ui/GeolocationView.java
+++ b/flow-tests/test-root-context/src/main/java/com/vaadin/flow/uitest/ui/GeolocationView.java
@@ -18,7 +18,7 @@
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.geolocation.GeolocationOptions;
import com.vaadin.flow.component.geolocation.GeolocationPosition;
-import com.vaadin.flow.component.geolocation.GeolocationTracker;
+import com.vaadin.flow.component.geolocation.GeolocationWatcher;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.NativeButton;
import com.vaadin.flow.router.Route;
@@ -27,7 +27,7 @@
@Route(value = "com.vaadin.flow.uitest.ui.GeolocationView", layout = ViewTestLayout.class)
public class GeolocationView extends AbstractDivView {
- private GeolocationTracker tracker;
+ private GeolocationWatcher watcher;
private int trackUpdateCount;
@Override
@@ -105,7 +105,7 @@ protected void onShow() {
""");
NativeButton getButton = createButton("Get Position", "getButton",
- e -> e.getUI().getGeolocation().get(pos -> {
+ e -> e.getUI().getGeolocation().getPosition(pos -> {
Div out = new Div();
out.setId("getResult");
out.setText("lat=" + pos.coords().latitude() + ", lon="
@@ -122,7 +122,8 @@ protected void onShow() {
// Uses the mock's "maximumAge == 9999 → error" trigger to exercise
// the error branch.
NativeButton getErrorButton = createButton("Get Position (error)",
- "getErrorButton", e -> e.getUI().getGeolocation().get(pos -> {
+ "getErrorButton",
+ e -> e.getUI().getGeolocation().getPosition(pos -> {
Div out = new Div();
out.setId("getErrorResult");
out.setText("unexpected position: " + pos.coords());
@@ -137,11 +138,11 @@ protected void onShow() {
NativeButton trackButton = createButton("Track Position", "trackButton",
e -> {
- tracker = UI.getCurrent().getGeolocation().track(this);
+ watcher = e.getUI().getGeolocation().watchPosition(this);
trackUpdateCount = 0;
getElement().addEventListener("vaadin-geolocation-position",
ev -> {
- var value = tracker.valueSignal().peek();
+ var value = watcher.valueSignal().peek();
if (value instanceof GeolocationPosition pos) {
trackUpdateCount++;
Div out = new Div();
@@ -156,8 +157,8 @@ protected void onShow() {
NativeButton stopButton = createButton("Stop tracking", "stopButton",
e -> {
- if (tracker != null) {
- tracker.stop();
+ if (watcher != null) {
+ watcher.stop();
Div out = new Div();
out.setId("stopResult");
out.setText("stopped after " + trackUpdateCount