ember-legacy-class-transform
Version:
The default blueprint for ember-cli addons.
153 lines • 4.73 kB
JavaScript
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);
}
}