UNPKG

@legumeinfo/web-components

Version:

Web Components for the Legume Information System and other AgBio databases

105 lines 3.83 kB
/** * A controller that allows components to interact with URL query string * parameters in a manner that triggers changes in the component's template when * parameter values change. */ export class LisQueryStringParametersController { /** * @param host - The component that's using the controller. */ constructor(host) { /** @ignore */ this._preUpdateListeners = []; /** @ignore */ this._listeners = []; (this.host = host).addController(this); } /** @ignore */ hostConnected() { window.addEventListener('popstate', this._popState.bind(this)); } /** @ignore */ hostDisconnected() { window.removeEventListener('popstate', this._popState.bind(this)); } /** * Gets the value of a URL query string parameter. This is reactive when used * inside a component template. * * @param name - The name of the parameter to get the value of. * @param defaultValue - The default value to return if the parameter isn't * in the query string. * * @returns The value of the parameter or the default value provided. */ getParameter(name, defaultValue = '') { const params = new URLSearchParams(window.location.search); const value = params.get(name); if (value !== null) { return decodeURIComponent(value); } return defaultValue; } /** * Updates the URL query string parameters. * * @param parameters - An object mapping parameter names to the values to * assign them. */ setParameters(parameters) { // don't update the query string if there's nothing to update if (!this._differentValues(parameters)) { return; } // push the new params onto the browser's history stack const queryString = '?' + Object.entries(parameters) .map(([key, value]) => `${key}=${encodeURIComponent(value)}`) .join('&'); history.pushState(parameters, '', queryString); } /** * Adds a listener to the {@link !popstate | `'popstate'`} event that will be executed * before the host's DOM is updated. * * @param listener - The listener to subscribe to the event. */ addPreUpdateListener(listener) { // each listener is called in the scope of the host this._preUpdateListeners.push(listener.bind(this.host)); } /** * Adds a listener to the {@link !popstate | `'popstate'`} event that will be executed * after the host's DOM is updated. * * @param listener - The listener to subscribe to the event. */ addListener(listener) { // each listener is called in the scope of the host this._listeners.push(listener.bind(this.host)); } /** @ignore */ // determines if any of the given parameters have different values than the URL parameters _differentValues(parameters) { const params = new URLSearchParams(window.location.search); return Object.entries(parameters).some(([key, value]) => encodeURIComponent(value) !== params.get(key)); } /** @ignore */ // calls all listeners of the popstate event _popState(event) { // call each pre update listener this._preUpdateListeners.forEach((listener) => { listener(event); }); // redraw the host this.host.requestUpdate(); // wait for the redraw to complete in case any listeners rely on state from the template this.host.updateComplete.then(() => { // call each listener this._listeners.forEach((listener) => { listener(event); }); }); } } //# sourceMappingURL=lis-query-string-parameters-controller.js.map