Helper functions for common operations including path manipulation, async operations, debouncing, gesture handling, and DOM utilities.
Functions for working with property paths in data binding and observation.
/**
* Get value at a property path on an object
*/
function get(object: any, path: string): any;
/**
* Set value at a property path on an object
*/
function set(object: any, path: string, value: any): void;
/**
* Check if a string represents a property path
*/
function isPath(path: string): boolean;
/**
* Get root property name from a path
*/
function root(path: string): string;
/**
* Check if a path is an ancestor of another path
*/
function isAncestor(base: string, path: string): boolean;
/**
* Check if a path is a descendant of another path
*/
function isDescendant(base: string, path: string): boolean;
/**
* Translate a path relative to another path
*/
function translate(base: string, newBase: string, path: string): string;
/**
* Check if a path matches a pattern (supports wildcards)
*/
function matches(base: string, path: string): boolean;
/**
* Normalize a property path
*/
function normalize(path: string): string;
/**
* Split property path into array of path parts
*/
function split(path: string): string[];Usage Examples:
import { get, set, isPath } from '@polymer/polymer/lib/utils/path.js';
const obj = {
user: {
profile: {
name: 'Alice',
settings: {
theme: 'dark'
}
},
posts: [
{ title: 'First Post', likes: 5 },
{ title: 'Second Post', likes: 10 }
]
}
};
// Get values using paths
console.log(get(obj, 'user.profile.name')); // 'Alice'
console.log(get(obj, 'user.posts.0.title')); // 'First Post'
// Set values using paths
set(obj, 'user.profile.name', 'Bob');
set(obj, 'user.posts.1.likes', 15);
// Check if string is a path
console.log(isPath('user.name')); // true
console.log(isPath('simple')); // false
// Path manipulation
import { root, isAncestor, translate } from '@polymer/polymer/lib/utils/path.js';
console.log(root('user.profile.name')); // 'user'
console.log(isAncestor('user', 'user.profile.name')); // true
console.log(translate('old.path', 'new.path', 'old.path.prop')); // 'new.path.prop'Async interfaces for different timing mechanisms.
/**
* Async interface for timeout-based operations
*/
interface AsyncInterface {
/** Run function after delay */
run(fn: () => void, delay?: number): number;
/** Cancel scheduled function */
cancel(handle: number): void;
}
/**
* Timeout-based async interface
*/
const timeOut: AsyncInterface;
/**
* Animation frame-based async interface
*/
const animationFrame: AsyncInterface;
/**
* Idle period-based async interface
*/
const idlePeriod: AsyncInterface;
/**
* Microtask-based async interface
*/
const microTask: AsyncInterface;Usage Examples:
import { timeOut, animationFrame, microTask } from '@polymer/polymer/lib/utils/async.js';
// Timeout-based async
const timeoutHandle = timeOut.run(() => {
console.log('Executed after 1000ms');
}, 1000);
// Cancel if needed
timeOut.cancel(timeoutHandle);
// Animation frame timing
const animationHandle = animationFrame.run(() => {
console.log('Executed on next animation frame');
});
// Microtask timing
const microtaskHandle = microTask.run(() => {
console.log('Executed on next microtask');
});Debouncing utility for batching rapid function calls.
/**
* Debouncer class for batching function calls
*/
class Debouncer {
/** Create debouncer with async interface */
constructor(asyncModule: AsyncInterface);
/** Debounce a function call */
debounce(fn: () => void): void;
/** Cancel pending debounced call */
cancel(): void;
/** Immediately flush pending call */
flush(): void;
/** Check if debouncer is active */
isActive(): boolean;
}
/**
* Enqueue debouncer for automatic flushing
*/
function enqueueDebouncer(debouncer: Debouncer): void;
/**
* Flush all enqueued debouncers
*/
function flushDebouncers(): void;Usage Examples:
import { Debouncer, enqueueDebouncer, flushDebouncers } from '@polymer/polymer/lib/utils/debounce.js';
import { timeOut } from '@polymer/polymer/lib/utils/async.js';
class MyElement extends PolymerElement {
constructor() {
super();
this._debouncer = null;
}
_debouncedMethod() {
this._debouncer = Debouncer.debounce(
this._debouncer,
timeOut.after(100),
() => {
console.log('Debounced execution');
this._actualWork();
}
);
enqueueDebouncer(this._debouncer);
}
_actualWork() {
// Heavy work that should be debounced
console.log('Doing expensive operation');
}
// Call multiple times rapidly - only executes once
rapidCalls() {
this._debouncedMethod();
this._debouncedMethod();
this._debouncedMethod(); // Only the last call will execute after delay
}
}Functions for flushing pending operations.
/**
* Flush all pending Polymer operations
*/
function flush(): void;Usage Examples:
import { flush } from '@polymer/polymer/lib/utils/flush.js';
// Force all pending property changes and template updates
flush();
// Useful in tests to ensure synchronous updates
element.someProperty = 'new value';
flush(); // Ensures all bindings are updated immediatelyCross-platform gesture recognition and event handling.
/**
* Gesture recognizer registry
*/
interface GestureRecognizer {
name: string;
deps: string[];
flow: {
start: (e: Event, state: any) => void;
move: (e: Event, state: any) => void;
end: (e: Event, state: any) => void;
};
emits: string[];
}
/**
* Gesture system interface
*/
interface Gestures {
/** Array of registered recognizers */
recognizers: GestureRecognizer[];
/** Add gesture event listener */
addListener(node: Node, evType: string, handler: (e: Event) => void): void;
/** Remove gesture event listener */
removeListener(node: Node, evType: string, handler: (e: Event) => void): void;
/** Register gesture recognizer */
register(recog: GestureRecognizer): void;
/** Find deepest element at coordinates */
deepTargetFind(x: number, y: number): Element;
/** Set touch-action CSS property */
setTouchAction(node: Node, value: string): void;
/** Prevent gesture default behavior */
prevent(evName: string): void;
/** Reset mouse event cancellation */
resetMouseCanceller(): void;
}
/**
* Main gestures object
*/
const gestures: Gestures;Usage Examples:
import { gestures } from '@polymer/polymer/lib/utils/gestures.js';
class GestureElement extends PolymerElement {
ready() {
super.ready();
// Add gesture listeners
gestures.addListener(this, 'tap', this._handleTap.bind(this));
gestures.addListener(this, 'track', this._handleTrack.bind(this));
// Prevent default touch behaviors
gestures.setTouchAction(this, 'none');
}
_handleTap(e) {
console.log('Tap at:', e.detail.x, e.detail.y);
}
_handleTrack(e) {
switch (e.detail.state) {
case 'start':
console.log('Track started');
break;
case 'track':
console.log('Tracking:', e.detail.dx, e.detail.dy);
break;
case 'end':
console.log('Track ended');
break;
}
}
}String case conversion utilities.
/**
* Convert dash-case to camelCase
*/
function dashToCamelCase(dash: string): string;
/**
* Convert camelCase to dash-case
*/
function camelToDashCase(camel: string): string;Usage Examples:
import { dashToCamelCase, camelToDashCase } from '@polymer/polymer/lib/utils/case-map.js';
console.log(dashToCamelCase('my-property')); // 'myProperty'
console.log(dashToCamelCase('data-binding-example')); // 'dataBindingExample'
console.log(camelToDashCase('myProperty')); // 'my-property'
console.log(camelToDashCase('dataBindingExample')); // 'data-binding-example'Array manipulation and observation utilities.
/**
* Calculate splice operations needed to transform one array to another
*/
function calculateSplices(current: any[], previous: any[]): Splice[];
interface Splice {
index: number;
removed: any[];
addedCount: number;
object: any[];
type: 'splice';
}Observer for flattened DOM tree changes (considering shadow DOM).
/**
* Observer for changes to flattened node tree
*/
class FlattenedNodesObserver {
/** Create observer for a node */
constructor(target: Node, callback: (info: FlattenedNodesInfo) => void);
/** Start observing */
connect(): void;
/** Stop observing */
disconnect(): void;
/** Force synchronous update */
flush(): void;
}
interface FlattenedNodesInfo {
target: Node;
addedNodes: Node[];
removedNodes: Node[];
}Functions for scheduling work relative to rendering.
/**
* Schedule callback before next render
*/
function beforeNextRender(element: Element, fn: () => void): void;
/**
* Schedule callback after next render
*/
function afterNextRender(element: Element, fn: () => void): void;Usage Examples:
import { beforeNextRender, afterNextRender } from '@polymer/polymer/lib/utils/render-status.js';
class RenderElement extends PolymerElement {
ready() {
super.ready();
// Schedule work before next render
beforeNextRender(this, () => {
console.log('Before render - good for DOM measurements');
const rect = this.getBoundingClientRect();
});
// Schedule work after next render
afterNextRender(this, () => {
console.log('After render - DOM is updated');
this.focusFirstInput();
});
}
focusFirstInput() {
const input = this.shadowRoot.querySelector('input');
if (input) input.focus();
}
}URL resolution utilities for relative paths and CSS.
/**
* Resolve relative URL against base URL
*/
function resolveUrl(url: string, base?: string): string;
/**
* Resolve URLs in CSS text
*/
function resolveCss(cssText: string, baseUrl: string): string;
/**
* Extract path from URL
*/
function pathFromUrl(url: string): string;Usage Examples:
import { resolveUrl, resolveCss, pathFromUrl } from '@polymer/polymer/lib/utils/resolve-url.js';
// Resolve relative URLs
console.log(resolveUrl('image.png', 'https://example.com/assets/'));
// 'https://example.com/assets/image.png'
// Resolve CSS URLs
const css = 'background: url(../images/bg.png);';
const resolved = resolveCss(css, 'https://example.com/styles/');
// 'background: url(https://example.com/images/bg.png);'
// Extract path from URL
console.log(pathFromUrl('https://example.com/path/to/file.js'));
// 'https://example.com/path/to/'Global configuration functions for Polymer behavior.
/**
* Set the root path for resolving URLs
*/
function setRootPath(path: string): void;
/**
* Set DOM value sanitization function
*/
function setSanitizeDOMValue(fn: (value: any, name: string, type: string, node: Element) => any): void;
/**
* Get current DOM value sanitization function
*/
function getSanitizeDOMValue(): (value: any, name: string, type: string, node: Element) => any;
/**
* Enable/disable passive touch gesture handling
*/
function setPassiveTouchGestures(usePassive: boolean): void;
/**
* Enable/disable strict template policy
*/
function setStrictTemplatePolicy(useStrictPolicy: boolean): void;
/**
* Set whether templates can be created from dom-module
*/
function setAllowTemplateFromDomModule(allowDomModule: boolean): void;
/**
* Enable/disable legacy optimizations
*/
function setLegacyOptimizations(useLegacyOptimizations: boolean): void;
/**
* Enable/disable legacy warnings
*/
function setLegacyWarnings(useLegacyWarnings: boolean): void;
/**
* Enable/disable synchronous initial render
*/
function setSyncInitialRender(useSyncInitialRender: boolean): void;Usage Examples:
import {
setRootPath,
setSanitizeDOMValue,
setPassiveTouchGestures
} from '@polymer/polymer/lib/utils/settings.js';
// Configure root path for URL resolution
setRootPath('/my-app/');
// Set up DOM sanitization
setSanitizeDOMValue((value, name, type, node) => {
if (type === 'property' && name === 'innerHTML') {
return sanitizeHTML(value); // Your sanitization logic
}
return value;
});
// Enable passive touch gestures for better scroll performance
setPassiveTouchGestures(true);Utilities for gathering and processing styles from templates and modules.
/**
* Get styles from multiple modules
*/
function stylesFromModules(moduleIds: string[]): CSSResult[];
/**
* Get styles from a single module
*/
function stylesFromModule(moduleId: string): CSSResult[];
/**
* Get styles from a template element
*/
function stylesFromTemplate(template: HTMLTemplateElement, baseURI?: string): CSSResult[];
/**
* Get CSS text from multiple modules
*/
function cssFromModules(moduleIds: string[]): string;
/**
* Get CSS text from a single module
*/
function cssFromModule(moduleId: string): string;
/**
* Get CSS text from a template element
*/
function cssFromTemplate(template: HTMLTemplateElement, baseURI?: string): string;Usage Examples:
import {
stylesFromModules,
cssFromTemplate
} from '@polymer/polymer/lib/utils/style-gather.js';
class StyledElement extends PolymerElement {
static get template() {
const template = html`
<style include="shared-styles theme-styles">
:host {
display: block;
}
</style>
<div>Styled content</div>
`;
// Process styles from included modules
const moduleStyles = stylesFromModules(['shared-styles', 'theme-styles']);
return template;
}
}ShadyDOM compatibility utilities.
/**
* Wrap a node for ShadyDOM compatibility
*/
const wrap: <T extends Node>(node: T) => T;Usage Examples:
import { wrap } from '@polymer/polymer/lib/utils/wrap.js';
// Wrap nodes when using ShadyDOM
const wrappedElement = wrap(someElement);
wrappedElement.appendChild(wrap(childNode));Registration and instance tracking utilities.
/**
* Array of all registered element constructors
*/
const registrations: PolymerElementConstructor[];
/**
* Current instance count
*/
let instanceCount: number;
/**
* Increment global instance count
*/
function incrementInstanceCount(): void;
/**
* Register an element constructor
*/
function register(prototype: any): void;
/**
* Dump registration information
*/
function dumpRegistrations(): void;interface AsyncInterface {
run(fn: () => void, delay?: number): number;
cancel(handle: number): void;
}
interface GestureRecognizer {
name: string;
deps: string[];
flow: {
start: (e: Event, state: any) => void;
move: (e: Event, state: any) => void;
end: (e: Event, state: any) => void;
};
emits: string[];
}
interface Splice {
index: number;
removed: any[];
addedCount: number;
object: any[];
type: 'splice';
}