export function main() { setupReflector(); var appInjector = new Injector([]); var bindings = [A, B, C]; var proto = new ProtoElementInjector(null, 0, bindings); var elementInjector = proto.instantiate(null,null); function instantiate (_) { for (var i = 0; i < ITERATIONS; ++i) { var ei = proto.instantiate(null, null); ei.instantiateDirectives(appInjector, null, null); } } function instantiateDirectives (_) { for (var i = 0; i < ITERATIONS; ++i) { elementInjector.clearDirectives(); elementInjector.instantiateDirectives(appInjector, null, null); } } DOM.on(DOM.querySelector(document, '#instantiate'), 'click', instantiate); DOM.on(DOM.querySelector(document, '#instantiateDirectives'), 'click', instantiateDirectives); }
addParent(newElement:CompileElement) { var currEl = this._current.element; var newEl = newElement.element; DOM.parentElement(currEl).insertBefore(newEl, currEl); DOM.appendChild(newEl, currEl); this.internalProcess(this._results, this._currentStepIndex+1, this._parent, newElement); this._parent = newElement; }
function initBaseline() { var tree = DOM.createElement('tree'); DOM.appendChild(DOM.querySelector(document, 'baseline'), tree); baselineRootTreeComponent = new BaseLineTreeComponent(tree); bindAction('#baselineDestroyDom', baselineDestroyDom); bindAction('#baselineCreateDom', baselineCreateDom); bindAction('#baselineUpdateDomProfile', profile(baselineCreateDom, noop, 'baseline-update')); bindAction('#baselineCreateDomProfile', profile(baselineCreateDom, baselineDestroyDom, 'baseline-create')); }
constructor(element) { this.element = element; var clone = DOM.clone(BASELINE_TREE_TEMPLATE.content.firstChild); var shadowRoot = this.element.createShadowRoot(); DOM.appendChild(shadowRoot, clone); var child = clone.firstChild; this.value = new BaseLineInterpolation(child); child = DOM.nextSibling(child); this.left = new BaseLineIf(child); child = DOM.nextSibling(child); this.right = new BaseLineIf(child); }
// public so that we can compile in sync in performance tests. compileAllLoaded(templateCache, component:AnnotatedType, templateRoot:Element = null):ProtoView { var rootProtoView = this._compilerCache.get(component.type); if (isPresent(rootProtoView)) { return rootProtoView; } if (isBlank(templateRoot)) { // TODO: read out the cache if templateRoot = null. Could contain: // - templateRoot string // - precompiled template // - ProtoView var annotation:any = component.annotation; templateRoot = DOM.createTemplate(annotation.template.inline); } var pipeline = new CompilePipeline(this.createSteps(component)); var compileElements = pipeline.process(templateRoot); rootProtoView = compileElements[0].inheritedProtoView; // Save the rootProtoView before we recurse so that we are able // to compile components that use themselves in their template. this._compilerCache.set(component.type, rootProtoView); for (var i=0; i<compileElements.length; i++) { var ce = compileElements[i]; if (isPresent(ce.componentDirective)) { ce.inheritedElementBinder.nestedProtoView = this.compileAllLoaded(templateCache, ce.componentDirective, null); } } return rootProtoView; }
_parseTextNode(pipelineElement, node, nodeIndex) { var expression = interpolationToExpression(node.nodeValue); if (isPresent(expression)) { DOM.setText(node, ' '); pipelineElement.addTextNodeBinding(nodeIndex, this._parser.parseBinding(expression)); } }
bind(appElementToken).toFactory((appComponentAnnotatedType, appDocument) => { var selector = appComponentAnnotatedType.annotation.selector; var element = DOM.querySelector(appDocument, selector); if (isBlank(element)) { throw new BaseException(`The app selector "${selector}" did not match any elements`); } return element; }, [appComponentAnnotatedTypeToken, appDocumentToken]),
function textInViewPort() { var out = ''; // skipping starting filler, insert-me and final filler. for (var i = 2; i < dom.childNodes.length - 1; i++) { if (i != 2) out += ' '; out += DOM.getInnerHTML(dom.childNodes[i]); } return out; }
update(value:TreeNode) { var newCondition = isPresent(value); if (this.condition !== newCondition) { this.condition = newCondition; if (isPresent(this.component)) { this.component.element.remove(); this.component = null; } if (this.condition) { var element = DOM.firstChild(DOM.clone(BASELINE_IF_TEMPLATE).content); this.anchor.parentNode.insertBefore(element, DOM.nextSibling(this.anchor)); this.component = new BaseLineTreeComponent(DOM.firstChild(element)); } } if (isPresent(this.component)) { this.component.update(value); } }
process(parent:CompileElement, current:CompileElement, control:CompileControl) { var element = current.element; var childNodes = DOM.templateAwareRoot(element).childNodes; for (var i=0; i<childNodes.length; i++) { var node = childNodes[i]; if (node.nodeType === Node.TEXT_NODE) { this._parseTextNode(current, node, i); } } }
classList():List<string> { if (isBlank(this._classList)) { this._classList = ListWrapper.create(); var elClassList = DOM.classList(this.element); for (var i = 0; i < elClassList.length; i++) { ListWrapper.push(this._classList, elClassList[i]); } } return this._classList; }
_process(results, parent:CompileElement, element:Element) { var current = new CompileElement(element); this._control.internalProcess(results, 0, parent, current); var childNodes = DOM.templateAwareRoot(element).childNodes; for (var i=0; i<childNodes.length; i++) { var node = childNodes[i]; if (node.nodeType === Node.ELEMENT_NODE) { this._process(results, current, node); } } }
_process(results, parent:CompileElement, current:CompileElement) { var additionalChildren = this._control.internalProcess(results, 0, parent, current); if (current.compileChildren) { var node = DOM.templateAwareRoot(current.element).firstChild; while (isPresent(node)) { // compiliation can potentially move the node, so we need to store the // next sibling before recursing. var nextNode = DOM.nextSibling(node); if (node.nodeType === Node.ELEMENT_NODE) { this._process(results, current, new CompileElement(node)); } node = nextNode; } } if (isPresent(additionalChildren)) { for (var i=0; i<additionalChildren.length; i++) { this._process(results, current, additionalChildren[i]); } } }
process(parent:CompileElement, current:CompileElement, control:CompileControl) { var element = current.element; if (isBlank(parent) || (current.element instanceof TemplateElement)) { current.isViewRoot = true; } else { var templateBindings = MapWrapper.get(current.attrs(), 'template'); if (isPresent(templateBindings)) { current.isViewRoot = true; var templateElement = DOM.createTemplate(''); var newParentElement = new CompileElement(templateElement); this._parseTemplateBindings(templateBindings, newParentElement); control.addParent(newParentElement); } } }
export function main() { setupReflector(); var bindings = [A, B, C, D, E]; var injector = new Injector(bindings); var D_KEY = Key.get(D); var E_KEY = Key.get(E); var childInjector = injector. createChild([]). createChild([]). createChild([]). createChild([]). createChild([]); function getByToken (_) { for (var i = 0; i < 20000; ++i) { injector.get(D); injector.get(E); } } function getByKey(_) { for (var i = 0; i < 20000; ++i) { injector.get(D_KEY); injector.get(E_KEY); } } function getChild (_) { for (var i = 0; i < 20000; ++i) { childInjector.get(D); childInjector.get(E); } } function instantiate (_) { for (var i = 0; i < 5000; ++i) { var child = injector.createChild([E]); child.get(E); } } DOM.on(DOM.querySelector(document, '#getByToken'), 'click', getByToken); DOM.on(DOM.querySelector(document, '#getByKey'), 'click', getByKey); DOM.on(DOM.querySelector(document, '#getChild'), 'click', getChild); DOM.on(DOM.querySelector(document, '#instantiate'), 'click', instantiate); }
process(parent:CompileElement, current:CompileElement, control:CompileControl) { var hasBindings = (isPresent(current.textNodeBindings) && MapWrapper.size(current.textNodeBindings)>0) || (isPresent(current.propertyBindings) && MapWrapper.size(current.propertyBindings)>0) || (isPresent(current.variableBindings) && MapWrapper.size(current.variableBindings)>0) || (isPresent(current.eventBindings) && MapWrapper.size(current.eventBindings)>0) || (isPresent(current.decoratorDirectives) && current.decoratorDirectives.length > 0) || isPresent(current.templateDirective) || isPresent(current.componentDirective); if (hasBindings) { var element = current.element; DOM.addClass(element, NG_BINDING_CLASS); current.hasBindings = true; } }
_parseTextNode(pipelineElement, node, nodeIndex) { // TODO: escape fixed string quotes // TODO: add braces around the expression // TODO: suppress empty strings // TODO: add stringify formatter var parts = StringWrapper.split(node.nodeValue, INTERPOLATION_REGEXP); if (parts.length > 1) { for (var i=0; i<parts.length; i++) { if (i%2 === 0) { // fixed string parts[i] = "'" + parts[i] + "'"; } else { // expression parts[i] = "" + parts[i] + ""; } } DOM.setText(node, ' '); pipelineElement.addTextNodeBinding(nodeIndex, parts.join('+')); } }
process(parent:CompileElement, current:CompileElement, control:CompileControl) { var element = current.element; if (isPresent(current.templateDirective)) { var templateElement = DOM.createTemplate(''); var templateBoundProperties = MapWrapper.create(); var nonTemplateBoundProperties = MapWrapper.create(); this._splitElementPropertyBindings(current, templateBoundProperties, nonTemplateBoundProperties); var newParentElement = new CompileElement(templateElement); newParentElement.propertyBindings = templateBoundProperties; newParentElement.templateDirective = current.templateDirective; control.addParent(newParentElement); // disconnect child view from their parent view element.remove(); current.templateDirective = null; current.propertyBindings = nonTemplateBoundProperties; current.isViewRoot = true; } else if (isBlank(parent)) { current.isViewRoot = true; } }
// public so that we can compile in sync in performance tests. compileWithCache(cache, component:AnnotatedType, templateRoot:Element = null):ProtoView { if (isBlank(templateRoot)) { // TODO: read out the cache if templateRoot = null. Could contain: // - templateRoot string // - precompiled template // - ProtoView var annotation:any = component.annotation; templateRoot = DOM.createTemplate(annotation.template.inline); } var pipeline = new CompilePipeline(this.createSteps(component)); var compileElements = pipeline.process(templateRoot); var rootProtoView = compileElements[0].inheritedProtoView; // TODO: put the rootProtoView into the cache to support recursive templates! for (var i=0; i<compileElements.length; i++) { var ce = compileElements[i]; if (isPresent(ce.componentDirective)) { ce.inheritedElementBinder.nestedProtoView = this.compileWithCache(cache, ce.componentDirective, null); } } return rootProtoView; }
static moveViewNodesAfterSibling(sibling, view) { for (var i = view.nodes.length - 1; i >= 0; --i) { DOM.insertAfter(sibling, view.nodes[i]); } }
static moveViewNodesIntoParent(parent, view) { for (var i = 0; i < view.nodes.length; ++i) { DOM.appendChild(parent, view.nodes[i]); } }
getAttribute(name:string) { return normalizeBlank(DOM.getAttribute(this.domElement, name)); }
attrs():Map<string,string> { if (isBlank(this._attrs)) { this._attrs = DOM.attributeMap(this.element); } return this._attrs; }
constructor(value, left, right) { this.value = value; this.left = left; this.right = right; } } function buildTree(maxDepth, values, curDepth) { if (maxDepth === curDepth) return new TreeNode('', null, null); return new TreeNode( values[curDepth], buildTree(maxDepth, values, curDepth+1), buildTree(maxDepth, values, curDepth+1)); } var BASELINE_TREE_TEMPLATE = DOM.createTemplate( '<span>_<template class="ng-binding"></template><template class="ng-binding"></template></span>'); var BASELINE_IF_TEMPLATE = DOM.createTemplate( '<span template="ng-if"><tree></tree></span>'); // http://jsperf.com/nextsibling-vs-childnodes class BaseLineTreeComponent { element:Element; value:BaseLineInterpolation; left:BaseLineIf; right:BaseLineIf; constructor(element) { this.element = element; var clone = DOM.clone(BASELINE_TREE_TEMPLATE.content.firstChild); var shadowRoot = this.element.createShadowRoot(); DOM.appendChild(shadowRoot, clone);
update(value:string) { if (this.value !== value) { this.value = value; DOM.setText(this.textNode, value + ' '); } }
static removeViewNodesFromParent(parent, view) { for (var i = view.nodes.length - 1; i >= 0; --i) { DOM.removeChild(parent, view.nodes[i]); } }
function createElement(html) { return DOM.createTemplate(html).content.firstChild; }
function _injectorBindings(appComponentType) { return ListWrapper.concat([bind(appDocumentToken).toValue(DOM.defaultDoc())], documentDependentBindings(appComponentType)); }