Skip to content

Commit

Permalink
feat: push and replace without navigation callback
Browse files Browse the repository at this point in the history
Add feature to support replace and
push without getting a callback
to the server for the change.

fixes #19613
  • Loading branch information
caalador committed Aug 1, 2024
1 parent 8a1309e commit a1ea12a
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,27 @@ public void pushState(JsonValue state, String location) {
Optional.ofNullable(location).map(Location::new).orElse(null));
}

/**
* Invokes <code>history.pushState</code> in the browser with the given
* parameters. This is a shorthand method for
* {@link History#pushState(JsonValue, Location)}, creating {@link Location}
* from the string provided.
*
* @param state
* the JSON state to push to the history stack, or
* <code>null</code> to only change the location
* @param location
* the new location to set in the browser, or <code>null</code>
* to only change the JSON state
* @param callback
* {@code true} if the change should make a return call to the
* server
*/
public void pushState(JsonValue state, String location, boolean callback) {
pushState(state,
Optional.ofNullable(location).map(Location::new).orElse(null), callback);
}

/**
* Invokes <code>history.pushState</code> in the browser with the given
* parameters.
Expand All @@ -182,14 +203,32 @@ public void pushState(JsonValue state, String location) {
* to only change the JSON state
*/
public void pushState(JsonValue state, Location location) {
pushState(state,location,false);
}

/**
* Invokes <code>history.pushState</code> in the browser with the given
* parameters.
*
* @param state
* the JSON state to push to the history stack, or
* <code>null</code> to only change the location
* @param location
* the new location to set in the browser, or <code>null</code>
* to only change the JSON state
* @param callback
* {@code true} if the change should make a return call to the
* server
*/
public void pushState(JsonValue state, Location location, boolean callback) {
final String pathWithQueryParameters = getPathWithQueryParameters(
location);
// Second parameter is title which is currently ignored according to
// https://developer.mozilla.org/en-US/docs/Web/API/History_API
if (ui.getSession().getConfiguration().isReactEnabled()) {
ui.getPage().executeJs(
"window.dispatchEvent(new CustomEvent('vaadin-navigate', { detail: { state: $0, url: $1, replace: false } }));",
state, pathWithQueryParameters);
"window.dispatchEvent(new CustomEvent('vaadin-navigate', { detail: { state: $0, url: $1, replace: false, callback: $2 } }));",
state, pathWithQueryParameters, callback);
} else {
ui.getPage().executeJs(
"setTimeout(() => { window.history.pushState($0, '', $1); window.dispatchEvent(new CustomEvent('vaadin-navigated')); })",
Expand All @@ -215,6 +254,27 @@ public void replaceState(JsonValue state, String location) {
Optional.ofNullable(location).map(Location::new).orElse(null));
}

/**
* Invokes <code>history.replaceState</code> in the browser with the given
* parameters. This is a shorthand method for
* {@link History#replaceState(JsonValue, Location)}, creating
* {@link Location} from the string provided.
*
* @param state
* the JSON state to push to the history stack, or
* <code>null</code> to only change the location
* @param location
* the new location to set in the browser, or <code>null</code>
* to only change the JSON state
* @param callback
* {@code true} if the change should make a return call to the
* server
*/
public void replaceState(JsonValue state, String location, boolean callback) {
replaceState(state,
Optional.ofNullable(location).map(Location::new).orElse(null), callback);
}

/**
* Invokes <code>history.replaceState</code> in the browser with the given
* parameters.
Expand All @@ -227,14 +287,32 @@ public void replaceState(JsonValue state, String location) {
* to only change the JSON state
*/
public void replaceState(JsonValue state, Location location) {
replaceState(state, location, true);
}

/**
* Invokes <code>history.replaceState</code> in the browser with the given
* parameters.
*
* @param state
* the JSON state to push to the history stack, or
* <code>null</code> to only change the location
* @param location
* the new location to set in the browser, or <code>null</code>
* to only change the JSON state
* @param callback
* {@code true} if the change should make a return call to the
* server
*/
public void replaceState(JsonValue state, Location location, boolean callback) {
final String pathWithQueryParameters = getPathWithQueryParameters(
location);
// Second parameter is title which is currently ignored according to
// https://developer.mozilla.org/en-US/docs/Web/API/History_API
if (ui.getSession().getConfiguration().isReactEnabled()) {
ui.getPage().executeJs(
"window.dispatchEvent(new CustomEvent('vaadin-navigate', { detail: { state: $0, url: $1, replace: true } }));",
state, pathWithQueryParameters);
"window.dispatchEvent(new CustomEvent('vaadin-navigate', { detail: { state: $0, url: $1, replace: true, callback: $2 } }));",
state, pathWithQueryParameters, callback);
} else {
ui.getPage().executeJs(
"setTimeout(() => { window.history.replaceState($0, '', $1); window.dispatchEvent(new CustomEvent('vaadin-navigated')); })",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ function Flow() {
navigate(path);
}, [navigate]);

const vaadinNavigateEventHandler = useCallback((event: CustomEvent<{state: unknown, url: string, replace?: boolean}>) => {
const vaadinNavigateEventHandler = useCallback((event: CustomEvent<{state: unknown, url: string, replace?: boolean, callback: boolean}>) => {
const path = '/' + event.detail.url;
navigated.current = !event.detail.replace;
navigated.current = !event.detail.callback;
navigate(path, { state: event.detail.state, replace: event.detail.replace});
}, [navigate]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
public class JavaScriptBootstrapUITest {

private static final String CLIENT_PUSHSTATE_TO = "setTimeout(() => { window.history.pushState($0, '', $1); window.dispatchEvent(new CustomEvent('vaadin-navigated')); })";
private static final String REACT_PUSHSTATE_TO = "window.dispatchEvent(new CustomEvent('vaadin-navigate', { detail: { state: $0, url: $1, replace: false } }));";
private static final String REACT_PUSHSTATE_TO = "window.dispatchEvent(new CustomEvent('vaadin-navigate', { detail: { state: $0, url: $1, replace: false, callback: $2 } }));";

private MockServletServiceSessionSetup mocks;
private UI ui;
Expand Down Expand Up @@ -501,7 +501,7 @@ public void server_should_not_doClientRoute_when_navigatingToServer() {
} else {
assertEquals(CLIENT_PUSHSTATE_TO, execJs.getValue());
}
assertEquals(2, execValues.length);
assertEquals(3, execValues.length);
assertNull(execValues[0]);
assertEquals("dirty", execValues[1]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ public PendingJavaScriptResult executeJs(String expression,
private static final String PUSH_STATE_JS = "setTimeout(() => { window.history.pushState($0, '', $1); window.dispatchEvent(new CustomEvent('vaadin-navigated')); })";
private static final String REPLACE_STATE_JS = "setTimeout(() => { window.history.replaceState($0, '', $1); window.dispatchEvent(new CustomEvent('vaadin-navigated')); })";

private static final String PUSH_STATE_REACT = "window.dispatchEvent(new CustomEvent('vaadin-navigate', { detail: { state: $0, url: $1, replace: false } }));";
private static final String REPLACE_STATE_REACT = "window.dispatchEvent(new CustomEvent('vaadin-navigate', { detail: { state: $0, url: $1, replace: true } }));";
private static final String PUSH_STATE_REACT = "window.dispatchEvent(new CustomEvent('vaadin-navigate', { detail: { state: $0, url: $1, replace: false, callback: $2 } }));";
private static final String REPLACE_STATE_REACT = "window.dispatchEvent(new CustomEvent('vaadin-navigate', { detail: { state: $0, url: $1, replace: true, callback: $2 } }));";

@Before
public void setup() {
Expand Down

0 comments on commit a1ea12a

Please sign in to comment.