"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const HistoryScrollRestorationEnum_js_1 = __importDefault(require("./HistoryScrollRestorationEnum.cjs")); const PropertySymbol = __importStar(require("../PropertySymbol.cjs")); const BrowserFrameURL_js_1 = __importDefault(require("../browser/utilities/BrowserFrameURL.cjs")); const DOMExceptionNameEnum_js_1 = __importDefault(require("../exception/DOMExceptionNameEnum.cjs")); /** * History API. * * Reference: * https://developer.mozilla.org/en-US/docs/Web/API/History. */ class History { #browserFrame; #window; #currentHistoryItem; /** * Constructor. * * @param browserFrame Browser frame. * @param window Owner window. */ constructor(browserFrame, window) { if (!browserFrame) { throw new TypeError('Illegal constructor'); } this.#browserFrame = browserFrame; this.#window = window; const history = browserFrame[PropertySymbol.history]; for (let i = history.length - 1; i >= 0; i--) { if (history[i].isCurrent) { this.#currentHistoryItem = history[i]; break; } } } /** * Returns the history length. * * @returns History length. */ get length() { return this.#browserFrame[PropertySymbol.history].length; } /** * Returns an any value representing the state at the top of the history stack. This is a way to look at the state without having to wait for a popstate event. * * @returns State. */ get state() { return this.#currentHistoryItem.state; } /** * Returns scroll restoration. * * @returns Sroll restoration. */ get scrollRestoration() { return this.#currentHistoryItem.scrollRestoration; } /** * Sets scroll restoration. * * @param scrollRestoration Sroll restoration. */ set scrollRestoration(scrollRestoration) { switch (scrollRestoration) { case HistoryScrollRestorationEnum_js_1.default.auto: case HistoryScrollRestorationEnum_js_1.default.manual: this.#currentHistoryItem.scrollRestoration = scrollRestoration; break; } } /** * Goes to the previous page in session history. */ back() { if (!this.#window.closed) { this.#browserFrame.goBack(); } } /** * Goes to the next page in session history. */ forward() { if (!this.#window.closed) { this.#browserFrame.goForward(); } } /** * Load a specific page from the session history. * * @param delta Delta. * @param _delta */ go(delta) { if (!this.#window.closed) { this.#browserFrame.goSteps(delta); } } /** * Pushes the given data onto the session history stack. * * @param state State. * @param title Title. * @param [url] URL. */ pushState(state, title, url) { if (this.#window.closed) { return; } const history = this.#browserFrame[PropertySymbol.history]; if (!history) { return; } const location = this.#window[PropertySymbol.location]; const newURL = url ? BrowserFrameURL_js_1.default.getRelativeURL(this.#browserFrame, url) : location; if (url && newURL.origin !== location.origin) { throw new this.#window.DOMException(`Failed to execute 'pushState' on 'History': A history state object with URL '${url}' cannot be created in a document with origin '${location.origin}' and URL '${location.href}'.`, DOMExceptionNameEnum_js_1.default.securityError); } let previousHistoryItem; for (let i = history.length - 1; i >= 0; i--) { if (history[i].isCurrent) { previousHistoryItem = history[i]; previousHistoryItem.isCurrent = false; // We need to remove all history items after the current one. history.length = i + 1; break; } } const newHistoryItem = { title: title || this.#window.document.title, href: newURL.href, state: JSON.parse(JSON.stringify(state)), scrollRestoration: this.#currentHistoryItem.scrollRestoration, method: previousHistoryItem?.method || 'GET', formData: previousHistoryItem?.formData || null, isCurrent: true }; history.push(newHistoryItem); location[PropertySymbol.setURL](this.#browserFrame, newHistoryItem.href); this.#currentHistoryItem = newHistoryItem; } /** * This method modifies the current history entry, replacing it with a new state. * * @param state State. * @param title Title. * @param [url] URL. */ replaceState(state, title, url) { if (this.#window.closed) { return; } const history = this.#browserFrame[PropertySymbol.history]; if (!history) { return; } const location = this.#window[PropertySymbol.location]; const newURL = url ? BrowserFrameURL_js_1.default.getRelativeURL(this.#browserFrame, url) : location; if (url && newURL.origin !== location.origin) { throw new this.#window.DOMException(`Failed to execute 'pushState' on 'History': A history state object with URL '${url}' cannot be created in a document with origin '${location.origin}' and URL '${location.href}'.`, DOMExceptionNameEnum_js_1.default.securityError); } for (let i = history.length - 1; i >= 0; i--) { if (history[i].isCurrent) { const newHistoryItem = { title: title || this.#window.document.title, href: newURL.href, state: JSON.parse(JSON.stringify(state)), scrollRestoration: history[i].scrollRestoration, method: history[i].method, formData: history[i].formData, isCurrent: true }; history[i] = newHistoryItem; this.#currentHistoryItem = newHistoryItem; break; } } if (url) { location[PropertySymbol.setURL](this.#browserFrame, this.#currentHistoryItem.href); } } /** * Destroys the history. * * This will make sure that the History API can't access page data from the next history item. */ [PropertySymbol.destroy]() { this.#browserFrame = null; } } exports.default = History; //# sourceMappingURL=History.cjs.map