@surface/custom-element
Version:
Provides support of directives and data binding on custom elements.
92 lines (91 loc) • 3.84 kB
JavaScript
import { assert } from "@surface/core";
import TemplateEvaluationError from "./errors/template-evaluation-error.js";
import TemplateObservationError from "./errors/template-observation-error.js";
import TemplateParseError from "./errors/template-parse-error.js";
import DataBind from "./reactivity/data-bind.js";
export function buildStackTrace(stackTrace) {
return stackTrace.map((entry, i) => entry.map(value => " ".repeat(i) + value).join("\n")).join("\n");
}
export function classMap(classes) {
return Object.entries(classes)
.filter(x => x[1])
.map(x => x[0])
.join(" ");
}
export function disposeTree(node) {
node.dispose?.();
for (const child of Array.from(node.childNodes)) {
disposeTree(child);
}
}
export function scapeBrackets(value) {
return value.replace(/(?<!\\)\\{/g, "{").replace(/\\\\{/g, "\\");
}
export function stringToCSSStyleSheet(source) {
const sheet = new CSSStyleSheet();
sheet.replaceSync(source);
sheet.toString = () => source;
return sheet;
}
export function styleMap(rules) {
return Object.entries(rules)
.map(([key, value]) => `${key}: ${value}`)
.join("; ");
}
export function throwTemplateEvaluationError(message, stackTrace) {
throw new TemplateEvaluationError(message, buildStackTrace(stackTrace));
}
export function throwTemplateObservationError(message, stackTrace) {
throw new TemplateObservationError(message, buildStackTrace(stackTrace));
}
export function throwTemplateParseError(message, stackTrace) {
throw new TemplateParseError(message, buildStackTrace(stackTrace));
}
export function tryEvaluateExpression(scope, expression, rawExpression, stackTrace) {
try {
return expression.evaluate(scope);
}
catch (error) {
assert(error instanceof Error);
throwTemplateEvaluationError(`Evaluation error in ${rawExpression}: ${error.message}`, stackTrace);
}
}
export function tryEvaluateExpressionByTraceable(scope, traceable) {
return tryEvaluateExpression(scope, traceable.expression, traceable.rawExpression, traceable.stackTrace);
}
export function tryEvaluateKeyExpressionByTraceable(scope, traceable) {
return tryEvaluateExpression(scope, traceable.keyExpression, traceable.rawKeyExpression, traceable.stackTrace);
}
export function tryEvaluatePattern(scope, pattern, value, rawExpression, stackTrace) {
try {
return pattern.evaluate(scope, value);
}
catch (error) {
assert(error instanceof Error);
throwTemplateEvaluationError(`Evaluation error in ${rawExpression}: ${error.message}`, stackTrace);
}
}
export function tryEvaluatePatternByTraceable(scope, value, traceable) {
return tryEvaluatePattern(scope, traceable.pattern, value, traceable.rawExpression, traceable.stackTrace);
}
export function tryObserve(scope, observables, listener, rawExpression, stackTrace, lazy) {
try {
return DataBind.observe(scope, observables, listener, lazy);
}
catch (error) {
assert(error instanceof Error);
throwTemplateObservationError(`Observation error in ${rawExpression}: ${error.message}`, stackTrace);
}
}
export function tryObserveByObservable(scope, observable, listener, lazy) {
return tryObserve(scope, observable.observables, listener, observable.rawExpression, observable.stackTrace, lazy);
}
export function tryObserveKeyByObservable(scope, observable, listener, lazy) {
return tryObserve(scope, observable.keyObservables, listener, observable.rawKeyExpression, observable.stackTrace, lazy);
}
export function* enumerateRange(start, end) {
let simbling = null;
while ((simbling = start.nextSibling) && simbling != end) {
yield simbling;
}
}