UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

131 lines (130 loc) 4.66 kB
import { getGetter, getSetter } from "../util/class.js"; import { clearURIParams, getURIParam, getURIParams, omitURIParams, requireURIParam, withURIParam, withURIParams, } from "../util/uri.js"; import { getURL, isURLActive, isURLProud, requireURL } from "../util/url.js"; import { BusyStore } from "./BusyStore.js"; /** Store a URL, e.g. `https://top.com/a/b/c` */ export class URLStore extends BusyStore { base; // Override to convert possible URL to URL. constructor(url, base) { const baseURL = getURL(base); super(requireURL(url, baseURL, URLStore)); this.base = baseURL; } // Override to convert possible URL to URL (relative to `this.base`). _convert(value, caller) { return requireURL(value, this.base, caller); } // Override for fast equality. _equal(a, b) { return a.href === b.href; } get href() { return this.value.href; } set href(href) { this.value = href; } get origin() { return this.value.origin; } get protocol() { return this.value.protocol; } get username() { return this.value.username; } get password() { return this.value.password; } get hostname() { return this.value.hostname; } get host() { return this.value.host; } get port() { return this.value.port; } get pathname() { return this.value.pathname; } /** Get the URL params as a string. */ get search() { return this.value.search; } /** Get the URL params as a dictionary. */ get params() { return getURIParams(this.value.searchParams, getGetter(this, "params")); } /** Return a single param in this URL, or `undefined` if it could not be found. */ getParam(key) { return getURIParam(this.value.searchParams, key); } /** Require a single param in this URL, or throw `RequiredError` if it could not be found. */ requireParam(key) { return requireURIParam(this.value.searchParams, key, getSetter(this, "requireParam")); } /** Set all params in this URL (all current params are cleared). */ setParams(params) { this.value = withURIParams(clearURIParams(this.value, this.setParams), params, this.setParams); } /** Set a single named param in this URL. */ setParam(key, value) { this.value = withURIParam(this.value, key, value, this.setParam); } /** Update several params in this URL (merged with current params). */ updateParams(params) { this.value = withURIParams(this.value, params, this.updateParams); } /** Delete one or more params in this URL. */ deleteParam(key, ...keys) { this.value = omitURIParams(this.value, key, ...keys); } /** Delete one or more params in this URL. */ deleteParams(key, ...keys) { this.value = omitURIParams(this.value, key, ...keys); } /** Clear all params from this URL. */ clearParams() { this.value = clearURIParams(this.value, this.clearParams); } /** Return the current URL with an additional param. */ withParam(key, value) { return withURIParam(this.value, key, value, this.withParam); } /** Return the current URL with an additional param. */ withParams(params) { return withURIParams(this.value, params, this.withParams); } /** Return the current URL with an additional param. */ omitParams(...keys) { return omitURIParams(this.value, ...keys); } /** Return the current URL with an additional param. */ omitParam(key) { return omitURIParams(this.value, key); } /** * Is `target` active relative to this store's URL? * - Active means `target` resolves to the exact same URL as this store's current value. * * @param target URL (or relative path resolved against this store's `base`) to test. */ isActive(target) { return isURLActive(this.value, requireURL(target, this.base, this.isActive)); } /** * Is `target` proud relative to this store's URL? * - Proud means this store's URL is `target` or a descendant of `target` — i.e. `target` sits at or above the current URL in the hierarchy. * - Useful for marking a menu item as "current branch" when the user is somewhere deeper in its sub-tree. * * @param target URL (or relative path resolved against this store's `base`) to test. */ isProud(target) { return isURLProud(this.value, requireURL(target, this.base, this.isProud)); } toString() { return this.href; } }