codigo0/node_modules/happy-dom/lib/history/History.js
planetazuzu 5d7a6500fe refactor: Fase 1 - Clean Architecture, refactorización modular y eliminación de duplicidades
-  Ticket 1.1: Estructura Clean Architecture en backend
-  Ticket 1.2: Schemas Zod compartidos
-  Ticket 1.3: Refactorización drugs.ts (1362 → 8 archivos modulares)
-  Ticket 1.4: Refactorización procedures.ts (3583 → 6 archivos modulares)
-  Ticket 1.5: Eliminación de duplicidades (~50 líneas)

Cambios principales:
- Creada estructura Clean Architecture en backend/src/
- Schemas Zod compartidos en backend/src/shared/schemas/
- Refactorización modular de drugs y procedures
- Utilidades genéricas en src/utils/ (filter, validation)
- Eliminados scripts obsoletos y documentación antigua
- Corregidos errores: QueryClient, import test-error-handling
- Build verificado y funcionando correctamente
2026-01-25 21:09:47 +01:00

175 lines
6.1 KiB
JavaScript

import HistoryScrollRestorationEnum from './HistoryScrollRestorationEnum.js';
import * as PropertySymbol from '../PropertySymbol.js';
import BrowserFrameURL from '../browser/utilities/BrowserFrameURL.js';
import DOMExceptionNameEnum from '../exception/DOMExceptionNameEnum.js';
/**
* History API.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/History.
*/
export default class History {
#browserFrame;
#window;
/**
* 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;
}
/**
* Returns the history length.
*
* @returns History length.
*/
get length() {
return this.#browserFrame?.[PropertySymbol.history].items.length || 0;
}
/**
* 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.#browserFrame?.[PropertySymbol.history].currentItem.state || null;
}
/**
* Returns scroll restoration.
*
* @returns Sroll restoration.
*/
get scrollRestoration() {
return (this.#browserFrame?.[PropertySymbol.history].currentItem.scrollRestoration ||
HistoryScrollRestorationEnum.auto);
}
/**
* Sets scroll restoration.
*
* @param scrollRestoration Sroll restoration.
*/
set scrollRestoration(scrollRestoration) {
switch (scrollRestoration) {
case HistoryScrollRestorationEnum.auto:
case HistoryScrollRestorationEnum.manual:
const currentItem = this.#browserFrame?.[PropertySymbol.history].currentItem;
if (currentItem) {
currentItem.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 _unused Unused.
* @param [url] URL.
*/
pushState(state, _unused, url) {
if (!this.#browserFrame || this.#window.closed) {
return;
}
const history = this.#browserFrame?.[PropertySymbol.history];
if (!history) {
return;
}
if (arguments.length < 2) {
throw new this.#window.TypeError(`Failed to execute 'pushState' on 'History': 2 arguments required, but only ${arguments.length} present.`);
}
const location = this.#window[PropertySymbol.location];
const newURL = url ? BrowserFrameURL.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.toString()}' cannot be created in a document with origin '${location.origin}' and URL '${location.href}'.`, DOMExceptionNameEnum.securityError);
}
history.currentItem.popState = true;
history.push({
title: this.#window.document.title,
href: newURL.href,
state,
popState: true,
scrollRestoration: history.currentItem.scrollRestoration,
method: history.currentItem.method || 'GET',
formData: history.currentItem.formData || null
});
location[PropertySymbol.setURL](this.#browserFrame, history.currentItem.href);
}
/**
* This method modifies the current history entry, replacing it with a new state.
*
* @param state State.
* @param _unused Unused.
* @param [url] URL.
*/
replaceState(state, _unused, url) {
if (!this.#browserFrame || this.#window.closed) {
return;
}
const history = this.#browserFrame?.[PropertySymbol.history];
if (!history) {
return;
}
if (arguments.length < 2) {
throw new this.#window.TypeError(`Failed to execute 'pushState' on 'History': 2 arguments required, but only ${arguments.length} present.`);
}
const location = this.#window[PropertySymbol.location];
const newURL = url ? BrowserFrameURL.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.toString()}' cannot be created in a document with origin '${location.origin}' and URL '${location.href}'.`, DOMExceptionNameEnum.securityError);
}
history.replace({
title: this.#window.document.title,
href: newURL.href,
state,
popState: history.currentItem.popState,
scrollRestoration: history.currentItem.scrollRestoration,
method: history.currentItem.method,
formData: history.currentItem.formData
});
if (url) {
location[PropertySymbol.setURL](this.#browserFrame, history.currentItem.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;
}
}
//# sourceMappingURL=History.js.map