UNPKG

ember-material-icons

Version:

Google Material icons for your ember-cli app

354 lines (272 loc) 9.7 kB
import { SymbolTable } from '@glimmer/interfaces'; import { Blocks, Inlines, populateBuiltins } from './syntax/functions'; import { Constants } from './opcodes'; import * as Simple from './dom/interfaces'; import { DOMChanges, DOMTreeConstruction } from './dom/helper'; import { Reference, PathReference, OpaqueIterable } from '@glimmer/reference'; import { UNDEFINED_REFERENCE, ConditionalReference } from './references'; import { defaultManagers, AttributeManager } from './dom/attribute-managers'; import { PartialDefinition } from './partial'; import { Component, ComponentManager, ComponentDefinition } from './component/interfaces'; import { ModifierManager } from './modifier/interfaces'; import { Option, Destroyable, Opaque, HasGuid, ensureGuid, expect, assert } from '@glimmer/util'; import { TemplateMeta } from '@glimmer/wire-format'; import { EvaluatedArgs } from './compiled/expressions/args'; import { InlineBlock } from './scanner'; import { PublicVM } from './vm/append'; export type ScopeSlot = PathReference<Opaque> | InlineBlock | EvaluatedArgs; export interface DynamicScope { get(key: string): PathReference<Opaque>; set(key: string, reference: PathReference<Opaque>): PathReference<Opaque>; child(): DynamicScope; } export class Scope { static root(self: PathReference<Opaque>, size = 0) { let refs: PathReference<Opaque>[] = new Array(size + 1); for (let i = 0; i <= size; i++) { refs[i] = UNDEFINED_REFERENCE; } return new Scope(refs).init({ self }); } // the 0th slot is `self` private slots: ScopeSlot[]; private callerScope: Option<Scope> = null; constructor(references: ScopeSlot[], callerScope: Option<Scope> = null) { this.slots = references; this.callerScope = callerScope; } init({ self }: { self: PathReference<Opaque> }): this { this.slots[0] = self; return this; } getSelf(): PathReference<Opaque> { return this.slots[0] as PathReference<Opaque>; } getSymbol(symbol: number): PathReference<Opaque> { return this.slots[symbol] as PathReference<Opaque>; } getBlock(symbol: number): InlineBlock { return this.slots[symbol] as InlineBlock; } getPartialArgs(symbol: number): EvaluatedArgs { return this.slots[symbol] as EvaluatedArgs; } bindSymbol(symbol: number, value: PathReference<Opaque>) { this.slots[symbol] = value; } bindBlock(symbol: number, value: InlineBlock) { this.slots[symbol] = value; } bindPartialArgs(symbol: number, value: EvaluatedArgs) { this.slots[symbol] = value; } bindCallerScope(scope: Scope) { this.callerScope = scope; } getCallerScope(): Option<Scope> { return this.callerScope; } child(): Scope { return new Scope(this.slots.slice(), this.callerScope); } } class Transaction { public scheduledInstallManagers: ModifierManager<Opaque>[] = []; public scheduledInstallModifiers: Object[] = []; public scheduledUpdateModifierManagers: ModifierManager<Opaque>[] = []; public scheduledUpdateModifiers: Object[] = []; public createdComponents: Component[] = []; public createdManagers: ComponentManager<Component>[] = []; public updatedComponents: Component[] = []; public updatedManagers: ComponentManager<Component>[] = []; public destructors: Destroyable[] = []; didCreate<T>(component: T, manager: ComponentManager<T>) { this.createdComponents.push(component); this.createdManagers.push(manager); } didUpdate<T>(component: T, manager: ComponentManager<T>) { this.updatedComponents.push(component); this.updatedManagers.push(manager); } scheduleInstallModifier<T>(modifier: T, manager: ModifierManager<T>) { this.scheduledInstallManagers.push(manager); this.scheduledInstallModifiers.push(modifier); } scheduleUpdateModifier<T>(modifier: T, manager: ModifierManager<T>) { this.scheduledUpdateModifierManagers.push(manager); this.scheduledUpdateModifiers.push(modifier); } didDestroy(d: Destroyable) { this.destructors.push(d); } commit() { let { createdComponents, createdManagers } = this; for (let i=0; i<createdComponents.length; i++) { let component = createdComponents[i]; let manager = createdManagers[i]; manager.didCreate(component); } let { updatedComponents, updatedManagers } = this; for (let i=0; i<updatedComponents.length; i++) { let component = updatedComponents[i]; let manager = updatedManagers[i]; manager.didUpdate(component); } let { destructors } = this; for (let i=0; i<destructors.length; i++) { destructors[i].destroy(); } let { scheduledInstallManagers, scheduledInstallModifiers } = this; for (let i = 0; i < scheduledInstallManagers.length; i++) { let manager = scheduledInstallManagers[i]; let modifier = scheduledInstallModifiers[i]; manager.install(modifier); } let { scheduledUpdateModifierManagers, scheduledUpdateModifiers } = this; for (let i = 0; i < scheduledUpdateModifierManagers.length; i++) { let manager = scheduledUpdateModifierManagers[i]; let modifier = scheduledUpdateModifiers[i]; manager.update(modifier); } } } export class Opcode { public offset = 0; constructor(private array: Uint32Array | Array<number>) {} get type() { return this.array[this.offset]; } get op1() { return this.array[this.offset + 1]; } get op2() { return this.array[this.offset + 2]; } get op3() { return this.array[this.offset + 3]; } } export class Program { [key: number]: never; private opcodes: number[] = []; private _offset = 0; private _opcode: Opcode; constructor() { this._opcode = new Opcode(this.opcodes); } get next(): number { return this._offset; } get current(): number { return this._offset - 4; } opcode(offset: number): Opcode { this._opcode.offset = offset; return this._opcode; } set(pos: number, type: number, op1 = 0, op2 = 0, op3 = 0) { this.opcodes[pos] = type; this.opcodes[pos + 1] = op1; this.opcodes[pos + 2] = op2; this.opcodes[pos + 3] = op3; } push(type: number, op1 = 0, op2 = 0, op3 = 0): number { let offset = this._offset; this.opcodes[this._offset++] = type; this.opcodes[this._offset++] = op1; this.opcodes[this._offset++] = op2; this.opcodes[this._offset++] = op3; return offset; } } export abstract class Environment { protected updateOperations: DOMChanges; protected appendOperations: DOMTreeConstruction; private _macros: Option<{ blocks: Blocks, inlines: Inlines }> = null; private _transaction: Option<Transaction> = null; public constants: Constants = new Constants(); public program = new Program(); constructor({ appendOperations, updateOperations }: { appendOperations: DOMTreeConstruction, updateOperations: DOMChanges }) { this.appendOperations = appendOperations; this.updateOperations = updateOperations; } toConditionalReference(reference: Reference<Opaque>): Reference<boolean> { return new ConditionalReference(reference); } abstract iterableFor(reference: Reference<Opaque>, args: EvaluatedArgs): OpaqueIterable; abstract protocolForURL(s: string): string; getAppendOperations(): DOMTreeConstruction { return this.appendOperations; } getDOM(): DOMChanges { return this.updateOperations; } getIdentity(object: HasGuid): string { return ensureGuid(object) + ''; } begin() { assert(!this._transaction, 'Cannot start a nested transaction'); this._transaction = new Transaction(); } private get transaction(): Transaction { return expect(this._transaction, 'must be in a transaction'); } didCreate<T>(component: T, manager: ComponentManager<T>) { this.transaction.didCreate(component, manager); } didUpdate<T>(component: T, manager: ComponentManager<T>) { this.transaction.didUpdate(component, manager); } scheduleInstallModifier<T>(modifier: T, manager: ModifierManager<T>) { this.transaction.scheduleInstallModifier(modifier, manager); } scheduleUpdateModifier<T>(modifier: T, manager: ModifierManager<T>) { this.transaction.scheduleUpdateModifier(modifier, manager); } didDestroy(d: Destroyable) { this.transaction.didDestroy(d); } commit() { this.transaction.commit(); this._transaction = null; } attributeFor(element: Simple.Element, attr: string, isTrusting: boolean, namespace?: string): AttributeManager { return defaultManagers(element, attr, isTrusting, namespace === undefined ? null : namespace); } macros(): { blocks: Blocks, inlines: Inlines } { let macros = this._macros; if (!macros) { this._macros = macros = populateBuiltins(); } return macros; } abstract hasHelper(helperName: string, blockMeta: TemplateMeta): boolean; abstract lookupHelper(helperName: string, blockMeta: TemplateMeta): Helper; abstract hasModifier(modifierName: string, blockMeta: TemplateMeta): boolean; abstract lookupModifier(modifierName: string, blockMeta: TemplateMeta): ModifierManager<Opaque>; abstract hasComponentDefinition(tagName: string, symbolTable: SymbolTable): boolean; abstract getComponentDefinition(tagName: string, symbolTable: SymbolTable): ComponentDefinition<Opaque>; abstract hasPartial(partialName: string, symbolTable: SymbolTable): boolean; abstract lookupPartial(PartialName: string, symbolTable: SymbolTable): PartialDefinition<TemplateMeta>; } export default Environment; export interface Helper { (vm: PublicVM, args: EvaluatedArgs, symbolTable: SymbolTable): PathReference<Opaque>; }