Standard browser APIs including Storage, History, Location, Permissions, and various observer interfaces. Provides essential browser functionality for web applications.
Local and session storage interface.
/**
* Local and session storage interface
*/
class Storage {
/** Number of items */
readonly length: number;
/** Get item value */
getItem(key: string): string | null;
/** Set item value */
setItem(key: string, value: string): void;
/** Remove item */
removeItem(key: string): void;
/** Clear all items */
clear(): void;
/** Get key by index */
key(index: number): string | null;
/** Array-like access */
[key: string]: any;
}Browser history management.
/**
* Browser history management
*/
class History {
/** History length */
readonly length: number;
/** Scroll restoration behavior */
scrollRestoration: ScrollRestoration;
/** Current state */
readonly state: any;
/** Go back */
back(): void;
/** Go forward */
forward(): void;
/** Go to specific entry */
go(delta?: number): void;
/** Push new state */
pushState(data: any, title: string, url?: string | null): void;
/** Replace current state */
replaceState(data: any, title: string, url?: string | null): void;
}
type ScrollRestoration = 'auto' | 'manual';URL location information and manipulation.
/**
* URL location information and manipulation
*/
class Location {
/** Full URL */
href: string;
/** URL origin */
readonly origin: string;
/** URL protocol */
protocol: string;
/** URL host */
host: string;
/** URL hostname */
hostname: string;
/** URL port */
port: string;
/** URL pathname */
pathname: string;
/** URL search parameters */
search: string;
/** URL hash */
hash: string;
/** Assign new URL */
assign(url: string): void;
/** Replace current URL */
replace(url: string): void;
/** Reload page */
reload(): void;
/** Convert to string */
toString(): string;
}Observe DOM mutations.
/**
* Observe DOM mutations
*/
class MutationObserver {
constructor(callback: MutationCallback);
/** Start observing */
observe(target: Node, options?: MutationObserverInit): void;
/** Stop observing */
disconnect(): void;
/** Take pending records */
takeRecords(): MutationRecord[];
}
type MutationCallback = (mutations: MutationRecord[], observer: MutationObserver) => void;
interface MutationObserverInit {
childList?: boolean;
attributes?: boolean;
characterData?: boolean;
subtree?: boolean;
attributeOldValue?: boolean;
characterDataOldValue?: boolean;
attributeFilter?: string[];
}
/**
* Mutation record data
*/
class MutationRecord {
/** Mutation type */
readonly type: MutationType;
/** Target node */
readonly target: Node;
/** Added nodes */
readonly addedNodes: NodeList;
/** Removed nodes */
readonly removedNodes: NodeList;
/** Previous sibling */
readonly previousSibling: Node | null;
/** Next sibling */
readonly nextSibling: Node | null;
/** Attribute name */
readonly attributeName: string | null;
/** Attribute namespace */
readonly attributeNamespace: string | null;
/** Old value */
readonly oldValue: string | null;
}
type MutationType = 'childList' | 'attributes' | 'characterData';Observe element intersections.
/**
* Observe element intersections
*/
class IntersectionObserver {
constructor(callback: IntersectionObserverCallback, options?: IntersectionObserverInit);
/** Root element */
readonly root: Element | null;
/** Root margin */
readonly rootMargin: string;
/** Threshold values */
readonly thresholds: ReadonlyArray<number>;
/** Start observing element */
observe(target: Element): void;
/** Stop observing element */
unobserve(target: Element): void;
/** Disconnect observer */
disconnect(): void;
/** Take records */
takeRecords(): IntersectionObserverEntry[];
}
type IntersectionObserverCallback = (entries: IntersectionObserverEntry[], observer: IntersectionObserver) => void;
interface IntersectionObserverInit {
root?: Element | null;
rootMargin?: string;
threshold?: number | number[];
}
/**
* Intersection observer entry
*/
class IntersectionObserverEntry {
/** Bounding client rect */
readonly boundingClientRect: DOMRectReadOnly;
/** Intersection ratio */
readonly intersectionRatio: number;
/** Intersection rect */
readonly intersectionRect: DOMRectReadOnly;
/** Is intersecting */
readonly isIntersecting: boolean;
/** Root bounds */
readonly rootBounds: DOMRectReadOnly | null;
/** Target element */
readonly target: Element;
/** Time stamp */
readonly time: number;
}Observe element size changes.
/**
* Observe element size changes
*/
class ResizeObserver {
constructor(callback: ResizeObserverCallback);
/** Start observing element */
observe(target: Element, options?: ResizeObserverOptions): void;
/** Stop observing element */
unobserve(target: Element): void;
/** Disconnect observer */
disconnect(): void;
}
type ResizeObserverCallback = (entries: ResizeObserverEntry[], observer: ResizeObserver) => void;
interface ResizeObserverOptions {
box?: ResizeObserverBoxOptions;
}
type ResizeObserverBoxOptions = 'border-box' | 'content-box' | 'device-pixel-content-box';Screen information.
/**
* Screen information
*/
class Screen {
/** Screen width */
readonly width: number;
/** Screen height */
readonly height: number;
/** Available width */
readonly availWidth: number;
/** Available height */
readonly availHeight: number;
/** Color depth */
readonly colorDepth: number;
/** Pixel depth */
readonly pixelDepth: number;
}Text selection management.
/**
* Text selection management
*/
class Selection {
/** Anchor node */
readonly anchorNode: Node | null;
/** Anchor offset */
readonly anchorOffset: number;
/** Focus node */
readonly focusNode: Node | null;
/** Focus offset */
readonly focusOffset: number;
/** Is collapsed */
readonly isCollapsed: boolean;
/** Range count */
readonly rangeCount: number;
/** Selection type */
readonly type: string;
/** Add range */
addRange(range: Range): void;
/** Remove range */
removeRange(range: Range): void;
/** Remove all ranges */
removeAllRanges(): void;
/** Get range at index */
getRangeAt(index: number): Range;
/** Collapse selection */
collapse(node: Node | null, offset?: number): void;
/** Extend selection */
extend(node: Node, offset: number): void;
/** Select all content */
selectAllChildren(node: Node): void;
/** Delete from document */
deleteFromDocument(): void;
/** Convert to string */
toString(): string;
}Permissions management.
/**
* Permissions management
*/
class Permissions {
/** Query permission */
query(permissionDesc: PermissionDescriptor): Promise<PermissionStatus>;
}
interface PermissionDescriptor {
name: PermissionName;
}
type PermissionName = 'geolocation' | 'camera' | 'microphone' | 'notifications';
/**
* Permission status
*/
class PermissionStatus extends EventTarget {
/** Permission state */
readonly state: PermissionState;
/** Permission name */
readonly name: PermissionName;
/** State change handler */
onchange: ((event: Event) => void) | null;
}
type PermissionState = 'granted' | 'denied' | 'prompt';import { Window } from "happy-dom";
const window = new Window();
// Store data
window.localStorage.setItem('user', JSON.stringify({ name: 'John', age: 30 }));
window.localStorage.setItem('theme', 'dark');
// Retrieve data
const userJson = window.localStorage.getItem('user');
const user = userJson ? JSON.parse(userJson) : null;
const theme = window.localStorage.getItem('theme');
console.log('User:', user);
console.log('Theme:', theme);
// Remove item
window.localStorage.removeItem('theme');
// Clear all
window.localStorage.clear();import { Window, MutationObserver } from "happy-dom";
const window = new Window();
const document = window.document;
// Create observer
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
console.log('Mutation type:', mutation.type);
console.log('Target:', mutation.target);
if (mutation.type === 'childList') {
console.log('Added nodes:', mutation.addedNodes.length);
console.log('Removed nodes:', mutation.removedNodes.length);
} else if (mutation.type === 'attributes') {
console.log('Attribute changed:', mutation.attributeName);
console.log('Old value:', mutation.oldValue);
}
});
});
// Start observing
observer.observe(document.body, {
childList: true,
attributes: true,
attributeOldValue: true,
subtree: true
});
// Make some changes
const div = document.createElement('div');
div.textContent = 'New content';
document.body.appendChild(div);
div.setAttribute('class', 'test-class');
// Stop observing
observer.disconnect();import { Window } from "happy-dom";
const window = new Window();
const history = window.history;
const location = window.location;
// Push new state
history.pushState(
{ page: 'home', data: 'some data' },
'Home Page',
'/home'
);
console.log('Current URL:', location.href);
console.log('Current state:', history.state);
// Replace current state
history.replaceState(
{ page: 'home', updated: true },
'Updated Home',
'/home'
);
// Navigate
history.back();
history.forward();
history.go(-2);