UNPKG

@surface/custom-element

Version:

Provides support of directives and data binding on custom elements.

92 lines (91 loc) 3.84 kB
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; } }