UNPKG

ember-legacy-class-transform

Version:
153 lines 4.73 kB
import { isConst, isModified, map, ReferenceCache } from '@glimmer/reference'; import { clear, Cursor } from '../../bounds'; import { Fragment } from '../../builder'; import { isComponentDefinition } from '../../component/interfaces'; import { APPEND_OPCODES, UpdatingOpcode } from '../../opcodes'; import { ConditionalReference } from '../../references'; import { cautiousInsert, isNode, isSafeString, isString, trustingInsert } from '../../upsert'; APPEND_OPCODES.add(26 /* DynamicContent */, (vm, { op1: append }) => { let opcode = vm.constants.getOther(append); opcode.evaluate(vm); }); function isEmpty(value) { return value === null || value === undefined || typeof value.toString !== 'function'; } export function normalizeTextValue(value) { if (isEmpty(value)) { return ''; } return String(value); } function normalizeTrustedValue(value) { if (isEmpty(value)) { return ''; } if (isString(value)) { return value; } if (isSafeString(value)) { return value.toHTML(); } if (isNode(value)) { return value; } return String(value); } function normalizeValue(value) { if (isEmpty(value)) { return ''; } if (isString(value)) { return value; } if (isSafeString(value) || isNode(value)) { return value; } return String(value); } export class AppendDynamicOpcode { evaluate(vm) { let reference = vm.stack.pop(); let normalized = this.normalize(reference); let value; let cache; if (isConst(reference)) { value = normalized.value(); } else { cache = new ReferenceCache(normalized); value = cache.peek(); } let stack = vm.elements(); let upsert = this.insert(vm.env.getAppendOperations(), stack, value); let bounds = new Fragment(upsert.bounds); stack.newBounds(bounds); if (cache /* i.e. !isConst(reference) */) { vm.updateWith(this.updateWith(vm, reference, cache, bounds, upsert)); } } } export class IsComponentDefinitionReference extends ConditionalReference { static create(inner) { return new IsComponentDefinitionReference(inner); } toBool(value) { return isComponentDefinition(value); } } class UpdateOpcode extends UpdatingOpcode { constructor(cache, bounds, upsert) { super(); this.cache = cache; this.bounds = bounds; this.upsert = upsert; this.tag = cache.tag; } evaluate(vm) { let value = this.cache.revalidate(); if (isModified(value)) { let { bounds, upsert } = this; let { dom } = vm; if (!this.upsert.update(dom, value)) { let cursor = new Cursor(bounds.parentElement(), clear(bounds)); upsert = this.upsert = this.insert(vm.env.getAppendOperations(), cursor, value); } bounds.update(upsert.bounds); } } toJSON() { let { _guid: guid, type, cache } = this; return { details: { lastValue: JSON.stringify(cache.peek()) }, guid, type }; } } export class OptimizedCautiousAppendOpcode extends AppendDynamicOpcode { constructor() { super(...arguments); this.type = 'optimized-cautious-append'; } normalize(reference) { return map(reference, normalizeValue); } insert(dom, cursor, value) { return cautiousInsert(dom, cursor, value); } updateWith(_vm, _reference, cache, bounds, upsert) { return new OptimizedCautiousUpdateOpcode(cache, bounds, upsert); } } class OptimizedCautiousUpdateOpcode extends UpdateOpcode { constructor() { super(...arguments); this.type = 'optimized-cautious-update'; } insert(dom, cursor, value) { return cautiousInsert(dom, cursor, value); } } export class OptimizedTrustingAppendOpcode extends AppendDynamicOpcode { constructor() { super(...arguments); this.type = 'optimized-trusting-append'; } normalize(reference) { return map(reference, normalizeTrustedValue); } insert(dom, cursor, value) { return trustingInsert(dom, cursor, value); } updateWith(_vm, _reference, cache, bounds, upsert) { return new OptimizedTrustingUpdateOpcode(cache, bounds, upsert); } } class OptimizedTrustingUpdateOpcode extends UpdateOpcode { constructor() { super(...arguments); this.type = 'optimized-trusting-update'; } insert(dom, cursor, value) { return trustingInsert(dom, cursor, value); } }