Element creation, type checking, and node manipulation utilities. Provides factory methods, type guards, and specialized utilities for working with different types of DOM nodes including Shadow DOM support.
Factory methods for creating SugarElement instances from various sources.
/**
* Create element from HTML tag name
* @param tag - HTML tag name (e.g., 'div', 'span', 'button')
* @param scope - Document to create element in
* @returns Typed SugarElement for the specific tag
*/
function fromTag<K extends keyof HTMLElementFullTagNameMap>(
tag: K,
scope?: Document
): SugarElement<HTMLElementFullTagNameMap[K]>;
/**
* Create element(s) from HTML string
* @param html - HTML string to parse
* @param scope - Document to create elements in
* @returns SugarElement wrapping the created node
*/
function fromHtml<E extends Node = Node & ChildNode>(
html: string,
scope?: Document
): SugarElement<E>;
/**
* Create text node with specified content
* @param text - Text content for the node
* @param scope - Document to create text node in
* @returns SugarElement wrapping text node
*/
function fromText(text: string, scope?: Document): SugarElement<Text>;
/**
* Wrap existing DOM node in SugarElement
* @param node - Native DOM node or Window to wrap
* @returns SugarElement preserving original type
*/
function fromDom<T extends Node | Window>(node: T): SugarElement<T>;
/**
* Find element at specific coordinates
* @param docElm - Document element to search within
* @param x - X coordinate
* @param y - Y coordinate
* @returns Element at coordinates, if any
*/
function fromPoint(docElm: SugarElement<Document>, x: number, y: number): Optional<SugarElement<Element>>;Usage Examples:
import { SugarElement } from "@ephox/sugar";
// Create specific HTML elements
const div = SugarElement.fromTag('div'); // SugarElement<HTMLDivElement>
const input = SugarElement.fromTag('input'); // SugarElement<HTMLInputElement>
const button = SugarElement.fromTag('button'); // SugarElement<HTMLButtonElement>
// Create from HTML
const card = SugarElement.fromHtml('<div class="card"><h2>Title</h2></div>');
// Create text node
const greeting = SugarElement.fromText('Hello, World!');
// Wrap existing DOM nodes
const body = SugarElement.fromDom(document.body);
const currentWindow = SugarElement.fromDom(window);
// Find element under mouse cursor
const elementUnderMouse = SugarElement.fromPoint(SugarElement.fromDom(document), 100, 200);Factory methods for creating multiple elements efficiently.
/**
* Create multiple elements from HTML string
* @param html - HTML string containing multiple elements
* @param scope - Document to create elements in
* @returns Tuple of created elements with preserved types
*/
function fromHtml<T extends Node[]>(html: string, scope?: Document): ElementTuple<T>;
/**
* Create multiple elements from array of tag names
* @param tags - Array of HTML tag names
* @param scope - Document to create elements in
* @returns Array of SugarElements
*/
function fromTags(tags: string[], scope?: Document): SugarElement<HTMLElement>[];
/**
* Create multiple text nodes
* @param texts - Array of text content strings
* @param scope - Document to create nodes in
* @returns Array of SugarElement text nodes
*/
function fromText(texts: string[], scope?: Document): SugarElement<Text>[];
/**
* Wrap multiple DOM nodes in SugarElements
* @param nodes - Array-like collection of DOM nodes
* @returns Array of SugarElements preserving types
*/
function fromDom<T extends (Node | Window)>(nodes: ArrayLike<T>): SugarElement<T>[];Create document fragments for efficient DOM manipulation.
/**
* Create document fragment containing multiple elements
* @param elements - Array of SugarElements to include in fragment
* @param scope - Document to create fragment in
* @returns SugarElement wrapping DocumentFragment
*/
function fromElements(
elements: SugarElement<Node>[],
scope?: Document
): SugarElement<DocumentFragment>;Type guard functions for safely working with different node types.
/**
* Check if node is an Element
* @param element - Node to check
* @returns Type guard for Element nodes
*/
function isElement(element: SugarElement<Node>): element is SugarElement<Element>;
/**
* Check if node is an HTMLElement
* @param element - Node to check
* @returns Type guard for HTMLElement nodes
*/
function isHTMLElement(element: SugarElement<Node>): element is SugarElement<HTMLElement>;
/**
* Check if node is a Text node
* @param element - Node to check
* @returns Type guard for Text nodes
*/
function isText(element: SugarElement<Node>): element is SugarElement<Text>;
/**
* Check if node is a Document
* @param element - Node to check
* @returns Type guard for Document nodes
*/
function isDocument(element: SugarElement<Node>): element is SugarElement<Document>;
/**
* Check if node is a DocumentFragment
* @param element - Node to check
* @returns Type guard for DocumentFragment nodes
*/
function isDocumentFragment(element: SugarElement<Node>): element is SugarElement<DocumentFragment>;
/**
* Check if node is a Comment
* @param element - Node to check
* @returns Type guard for Comment nodes
*/
function isComment(element: SugarElement<Node>): element is SugarElement<Comment>;
/**
* Create type guard for specific HTML tag
* @param tag - HTML tag name to check for
* @returns Type guard function for that specific tag
*/
function isTag<K extends keyof HTMLElementFullTagNameMap>(
tag: K
): (e: SugarElement<Node>) => e is SugarElement<HTMLElementFullTagNameMap[K]>;Usage Examples:
import { SugarNode } from "@ephox/sugar";
function processNode(node: SugarElement<Node>) {
if (SugarNode.isElement(node)) {
// node is now typed as SugarElement<Element>
console.log('Element tag:', node.dom.tagName);
} else if (SugarNode.isText(node)) {
// node is now typed as SugarElement<Text>
console.log('Text content:', node.dom.textContent);
} else if (SugarNode.isComment(node)) {
// node is now typed as SugarElement<Comment>
console.log('Comment:', node.dom.data);
}
}
// Check for specific tags
const isButton = SugarNode.isTag('button');
if (isButton(someElement)) {
// someElement is now typed as SugarElement<HTMLButtonElement>
someElement.dom.disabled = true;
}Access common node properties in a type-safe manner.
/**
* Get node name (tag name for elements, lowercased)
* @param element - Node to get name from
* @returns Node name in lowercase
*/
function name(element: SugarElement<Node>): string;
/**
* Get node type constant
* @param element - Node to get type from
* @returns Node type number (1=Element, 3=Text, etc.)
*/
function type(element: SugarElement<Node>): number;
/**
* Get node value (for text/comment nodes)
* @param element - Node to get value from
* @returns Node value or null
*/
function value(element: SugarElement<Node>): string | null;Access document and document parts.
/**
* Get current document
* @returns SugarElement wrapping current document
*/
function getDocument(): SugarElement<Document>;
/**
* Get document body element
* @returns SugarElement wrapping document body
*/
function body(): SugarElement<HTMLElement>;
/**
* Get body element from specific document
* @param doc - Document to get body from
* @returns SugarElement wrapping body element
*/
function getBody(doc: SugarElement<Document>): SugarElement<HTMLElement>;
/**
* Check if element is within document body
* @param element - Element to check
* @returns True if element is in document body
*/
function inBody(element: SugarElement<Node>): boolean;
/**
* Get document head element
* @returns SugarElement wrapping document head
*/
function head(): SugarElement<HTMLHeadElement>;
/**
* Get head element from specific document
* @param doc - Document to get head from
* @returns SugarElement wrapping head element
*/
function getHead(doc: SugarElement<Document>): SugarElement<HTMLHeadElement>;Specialized utilities for working with text and comment nodes.
/**
* Get text content from text node
* @param element - Text node to read from
* @returns Text content string
*/
function get(element: SugarElement<Text>): string;
/**
* Safely get text content from any node
* @param element - Node to read from (may not be text)
* @returns Text content if node is text, otherwise empty Optional
*/
function getOption(element: SugarElement<Node>): Optional<string>;
/**
* Set text content of text node
* @param element - Text node to modify
* @param value - New text content
*/
function set(element: SugarElement<Text>, value: string): void;
/**
* Get comment text from comment node
* @param element - Comment node to read from
* @returns Comment text string
*/
function get(element: SugarElement<Comment>): string;
/**
* Safely get comment text from any node
* @param element - Node to read from (may not be comment)
* @returns Comment text if node is comment, otherwise empty Optional
*/
function getOption(element: SugarElement<Node>): Optional<string>;
/**
* Set comment text
* @param element - Comment node to modify
* @param value - New comment text
*/
function set(element: SugarElement<Comment>, value: string): void;
/**
* Find all comment nodes within a parent
* @param node - Parent node to search within
* @param filterOpt - Optional filter function for comment text
* @returns Array of found comment nodes
*/
function find(
node: SugarElement<Node>,
filterOpt: Optional<(n: string | null) => boolean>
): SugarElement<Comment>[];Utilities for working with Shadow DOM when available.
/**
* Check if node is a shadow root
* @param dos - Node to check
* @returns Type guard for ShadowRoot
*/
function isShadowRoot(dos: SugarElement<Node>): dos is SugarElement<ShadowRoot>;
/**
* Check if Shadow DOM is supported in current browser
* @returns True if Shadow DOM is available
*/
function isSupported(): boolean;
/**
* Get root node (document or shadow root) for element
* @param e - Element to find root for
* @returns Root document or shadow root
*/
function getRootNode(e: SugarElement<Node>): RootNode;
/**
* Create element within specific root context
* @param dos - Root node (document or shadow root)
* @param tag - HTML tag name to create
* @returns Created element within the root context
*/
function createElement<K extends keyof HTMLElementFullTagNameMap>(
dos: RootNode,
tag: K
): SugarElement<HTMLElementFullTagNameMap[K]>;
/**
* Get appropriate container for styles (head or shadow root)
* @param dos - Root node
* @returns Container for adding styles
*/
function getStyleContainer(dos: RootNode): SugarElement<HTMLHeadElement | ShadowRoot>;
/**
* Get appropriate container for content (body or shadow root)
* @param dos - Root node
* @returns Container for adding content
*/
function getContentContainer(dos: RootNode): SugarElement<HTMLElement | ShadowRoot>;
/**
* Check if element is within a shadow root
* @param e - Element to check
* @returns True if element is in shadow tree
*/
function isInShadowRoot(e: SugarElement<Node>): boolean;
/**
* Get shadow root containing element
* @param e - Element to find shadow root for
* @returns Shadow root if element is in shadow tree
*/
function getShadowRoot(e: SugarElement<Node>): Optional<SugarElement<ShadowRoot>>;
/**
* Get shadow host element for shadow root
* @param e - Shadow root element
* @returns Host element that contains the shadow root
*/
function getShadowHost(e: SugarElement<ShadowRoot>): SugarElement<Element>;
/**
* Get original event target (handles Shadow DOM event retargeting)
* @param event - DOM event
* @returns Original event target before Shadow DOM retargeting
*/
function getOriginalEventTarget(event: Event): Optional<EventTarget>;
/**
* Check if shadow root is open mode
* @param sr - Shadow root to check
* @returns True if shadow root is open
*/
function isOpenShadowRoot(sr: SugarElement<ShadowRoot>): boolean;
/**
* Check if shadow root is closed mode
* @param sr - Shadow root to check
* @returns True if shadow root is closed
*/
function isClosedShadowRoot(sr: SugarElement<ShadowRoot>): boolean;
/**
* Check if element is host of open shadow root
* @param element - Element to check
* @returns True if element hosts open shadow root
*/
function isOpenShadowHost(element: SugarElement<Element>): boolean;Utilities for testing and debugging SugarElement instances.
/**
* Create equality instance for testing SugarElements
* @returns Eq instance for element comparison in tests
*/
function eqElement<T extends Node>(): Eq<SugarElement<T>>;
/**
* Create pretty print instance for SugarElements
* @returns Pprint instance for element display in tests
*/
function pprintElement<T extends Node>(): Pprint<SugarElement<T>>;
/**
* Create testable instance for SugarElements
* @returns Testable instance for element testing framework
*/
function tElement<T extends Node>(): Testable<SugarElement<T>>;// DOM Node type constants
const ELEMENT = 1;
const ATTRIBUTE = 2;
const TEXT = 3;
const CDATA_SECTION = 4;
const ENTITY_REFERENCE = 5;
const ENTITY = 6;
const PROCESSING_INSTRUCTION = 7;
const COMMENT = 8;
const DOCUMENT = 9;
const DOCUMENT_TYPE = 10;
const DOCUMENT_FRAGMENT = 11;
const NOTATION = 12;// Primary wrapper interface
interface SugarElement<T = any> {
readonly dom: T;
}
// Root node type for Shadow DOM
type RootNode = SugarElement<Document | ShadowRoot>;
// Element tuple for multiple element creation
type ElementTuple<T extends Node[]> = {
[K in keyof T]: SugarElement<T[K]>
};
// Testing framework types from @ephox/dispute
interface Eq<T> {
eq: (a: T, b: T) => boolean;
}
interface Pprint<T> {
pprint: (t: T) => string;
}
interface Testable<T> {
// Testing framework interface
}