diff --git a/lib/index.d.ts b/lib/index.d.ts index d477010e..94af2cbd 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -148,6 +148,12 @@ export interface AnyAttrs { [attr: string]: any; } +export interface NavigateOptions { + // Passing this flag to navigate() will cause the matching router handler to execute, but won't update the url + // with the passed fragment. + dontUpdateUrl?: boolean; +} + export class Component< StateT, AttrsT = AnyAttrs, @@ -240,7 +246,7 @@ export class Component< * Executes the route handler matching the given URL fragment, and updates * the URL, as though the user had navigated explicitly to that address. */ - navigate(fragment: string, stateUpdate?: Partial): void; + navigate(fragment: string, stateUpdate?: Partial, navigateOptions?: NavigateOptions): void; /** Run a user-defined hook with the given parameters */ runHook: ( diff --git a/lib/router.js b/lib/router.js index 7cfa52fd..a44bbe9e 100644 --- a/lib/router.js +++ b/lib/router.js @@ -68,13 +68,15 @@ export default class Router { this.window.history[this.historyMethod] = this.origChangeStateMethod; } - navigate(fragment, stateUpdate = {}) { + navigate(fragment, stateUpdate = {}, {dontUpdateUrl = false} = {}) { fragment = stripHash(fragment); if (decodedFragmentsEqual(this.app.state.$fragment, fragment) && !Object.keys(stateUpdate).length) { return; } - stateUpdate.$fragment = fragment; + if (!dontUpdateUrl) { + stateUpdate.$fragment = fragment; + } for (const route of this.compiledRoutes) { const matches = route.expr.exec(fragment); if (matches) { diff --git a/test/browser/component.js b/test/browser/component.js index 09d7d9d0..b3b26476 100644 --- a/test/browser/component.js +++ b/test/browser/component.js @@ -321,15 +321,15 @@ describe(`Simple Component instance`, function () { context(`when applying override styles`, function () { it(`appends the overriding styles to the default styles`, async function () { - el.setAttribute(`style-override`, `:host { background: red; }`); + el.setAttribute(`style-override`, `:host { background-color: red; }`); await nextAnimationFrame(); - expect(getComponentStylesheetText(el)).to.equal(`:host { color: blue; }:host { background: red; }`); + expect(getComponentStylesheetText(el)).to.equal(`:host { color: blue; }:host { background-color: red; }`); }); it(`it applies the styles even if the component isn't attached to the DOM`, function () { el = document.createElement(`shadow-dom-app`); - el.setAttribute(`style-override`, `:host { background: red; }`); - expect(getComponentStylesheetText(el)).to.equal(`:host { color: blue; }:host { background: red; }`); + el.setAttribute(`style-override`, `:host { background-color: red; }`); + expect(getComponentStylesheetText(el)).to.equal(`:host { color: blue; }:host { background-color: red; }`); }); }); }); diff --git a/test/browser/router.js b/test/browser/router.js index 8731d919..a6cf8365 100644 --- a/test/browser/router.js +++ b/test/browser/router.js @@ -150,6 +150,14 @@ describe(`Router`, function () { await nextAnimationFrame(); expect(this.routerApp.textContent).to.equal(`Number: 42`); }); + + it(`does not update url if dontUpdateUrl is passed`, async function () { + expect(window.location.hash).to.equal(``); + this.routerApp.router.navigate(`numeric/42`, {}, {dontUpdateUrl: true}); + await retryable(() => expect(this.routerApp.textContent).to.equal(`Number: 42`)); + expect(this.routerApp.textContent).to.equal(`Number: 42`); + expect(window.location.hash).to.equal(``); + }); }); describe(`replaceHash()`, function () {