// Attention: This is on the hot path, so don't use closures or default values!
function queryBoundElements(templateContent, isSingleElementChild) {
    var result;
    var dynamicElementList;
    var elementIdx = 0;
    if (isSingleElementChild) {
        var rootElement = dom_adapter_1.DOM.firstChild(templateContent);
        var rootHasBinding = dom_adapter_1.DOM.hasClass(rootElement, exports.NG_BINDING_CLASS);
        dynamicElementList = dom_adapter_1.DOM.getElementsByClassName(rootElement, exports.NG_BINDING_CLASS);
        result = collection_1.ListWrapper.createFixedSize(dynamicElementList.length + (rootHasBinding ? 1 : 0));
        if (rootHasBinding) {
            result[elementIdx++] = rootElement;
        }
    }
    else {
        dynamicElementList = dom_adapter_1.DOM.querySelectorAll(templateContent, exports.NG_BINDING_CLASS_SELECTOR);
        result = collection_1.ListWrapper.createFixedSize(dynamicElementList.length);
    }
    for (var i = 0; i < dynamicElementList.length; i++) {
        result[elementIdx++] = dynamicElementList[i];
    }
    return result;
}
 DomRenderer.prototype._createView = function (protoView, inplaceElement) {
     var rootElementClone;
     var elementsWithBindingsDynamic;
     var viewRootNodes;
     if (lang_1.isPresent(inplaceElement)) {
         rootElementClone = inplaceElement;
         elementsWithBindingsDynamic = [];
         viewRootNodes = [inplaceElement];
     }
     else if (protoView.isTemplateElement) {
         rootElementClone = dom_adapter_1.DOM.importIntoDoc(dom_adapter_1.DOM.content(protoView.element));
         elementsWithBindingsDynamic =
             dom_adapter_1.DOM.querySelectorAll(rootElementClone, util_1.NG_BINDING_CLASS_SELECTOR);
         var childNode = dom_adapter_1.DOM.firstChild(rootElementClone);
         // TODO(perf): Should be fixed size, since we could pre-compute in in DomProtoView
         viewRootNodes = [];
         // Note: An explicit loop is the fastest way to convert a DOM array into a JS array!
         while (childNode != null) {
             collection_1.ListWrapper.push(viewRootNodes, childNode);
             childNode = dom_adapter_1.DOM.nextSibling(childNode);
         }
     }
     else {
         rootElementClone = dom_adapter_1.DOM.importIntoDoc(protoView.element);
         elementsWithBindingsDynamic = dom_adapter_1.DOM.getElementsByClassName(rootElementClone, util_1.NG_BINDING_CLASS);
         viewRootNodes = [rootElementClone];
     }
     var elementsWithBindings = collection_1.ListWrapper.createFixedSize(elementsWithBindingsDynamic.length);
     for (var binderIdx = 0; binderIdx < elementsWithBindingsDynamic.length; ++binderIdx) {
         elementsWithBindings[binderIdx] = elementsWithBindingsDynamic[binderIdx];
     }
     var binders = protoView.elementBinders;
     var boundTextNodes = [];
     var boundElements = collection_1.ListWrapper.createFixedSize(binders.length);
     var contentTags = collection_1.ListWrapper.createFixedSize(binders.length);
     for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
         var binder = binders[binderIdx];
         var element;
         var childNodes;
         if (binderIdx === 0 && protoView.rootBindingOffset === 1) {
             // Note: if the root element was a template,
             // the rootElementClone is a document fragment,
             // which will be empty as soon as the view gets appended
             // to a parent. So we store null in the boundElements array.
             element = protoView.isTemplateElement ? null : rootElementClone;
             childNodes = dom_adapter_1.DOM.childNodes(rootElementClone);
         }
         else {
             element = elementsWithBindings[binderIdx - protoView.rootBindingOffset];
             childNodes = dom_adapter_1.DOM.childNodes(element);
         }
         boundElements[binderIdx] = element;
         // boundTextNodes
         var textNodeIndices = binder.textNodeIndices;
         for (var i = 0; i < textNodeIndices.length; i++) {
             collection_1.ListWrapper.push(boundTextNodes, childNodes[textNodeIndices[i]]);
         }
         // contentTags
         var contentTag = null;
         if (lang_1.isPresent(binder.contentTagSelector)) {
             contentTag = new content_tag_1.Content(element, binder.contentTagSelector);
         }
         contentTags[binderIdx] = contentTag;
     }
     var view = new view_1.DomView(protoView, viewRootNodes, boundTextNodes, boundElements, contentTags);
     for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
         var binder = binders[binderIdx];
         var element = boundElements[binderIdx];
         // lightDoms
         var lightDom = null;
         if (lang_1.isPresent(binder.componentId)) {
             lightDom = this._shadowDomStrategy.constructLightDom(view, boundElements[binderIdx]);
         }
         view.lightDoms[binderIdx] = lightDom;
         // init contentTags
         var contentTag = contentTags[binderIdx];
         if (lang_1.isPresent(contentTag)) {
             var destLightDom = view.getDirectParentLightDom(binderIdx);
             contentTag.init(destLightDom);
         }
         // events
         if (lang_1.isPresent(binder.eventLocals) && lang_1.isPresent(binder.localEvents)) {
             for (var i = 0; i < binder.localEvents.length; i++) {
                 this._createEventListener(view, element, binderIdx, binder.localEvents[i].name, binder.eventLocals);
             }
         }
     }
     return view;
 };
 DomRenderer.prototype._createView = function (protoView, inplaceElement) {
     var rootElementClone;
     var elementsWithBindingsDynamic;
     var viewRootNodes;
     if (lang_1.isPresent(inplaceElement)) {
         rootElementClone = inplaceElement;
         elementsWithBindingsDynamic = [];
         viewRootNodes = [inplaceElement];
     }
     else if (protoView.isTemplateElement) {
         rootElementClone = dom_adapter_1.DOM.importIntoDoc(dom_adapter_1.DOM.content(protoView.element));
         elementsWithBindingsDynamic =
             dom_adapter_1.DOM.querySelectorAll(rootElementClone, util_1.NG_BINDING_CLASS_SELECTOR);
         viewRootNodes = collection_1.ListWrapper.createFixedSize(protoView.rootNodeCount);
         // Note: An explicit loop is the fastest way to convert a DOM array into a JS array!
         var childNode = dom_adapter_1.DOM.firstChild(rootElementClone);
         for (var i = 0; i < protoView.rootNodeCount; i++, childNode = dom_adapter_1.DOM.nextSibling(childNode)) {
             viewRootNodes[i] = childNode;
         }
     }
     else {
         rootElementClone = dom_adapter_1.DOM.importIntoDoc(protoView.element);
         elementsWithBindingsDynamic = dom_adapter_1.DOM.getElementsByClassName(rootElementClone, util_1.NG_BINDING_CLASS);
         viewRootNodes = [rootElementClone];
     }
     var binders = protoView.elementBinders;
     var boundTextNodes = collection_1.ListWrapper.createFixedSize(protoView.boundTextNodeCount);
     var boundElements = collection_1.ListWrapper.createFixedSize(binders.length);
     var boundTextNodeIdx = 0;
     for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
         var binder = binders[binderIdx];
         var element;
         var childNodes;
         if (binderIdx === 0 && protoView.rootBindingOffset === 1) {
             // Note: if the root element was a template,
             // the rootElementClone is a document fragment,
             // which will be empty as soon as the view gets appended
             // to a parent. So we store null in the boundElements array.
             element = protoView.isTemplateElement ? null : rootElementClone;
             childNodes = dom_adapter_1.DOM.childNodes(rootElementClone);
         }
         else {
             element = elementsWithBindingsDynamic[binderIdx - protoView.rootBindingOffset];
             childNodes = dom_adapter_1.DOM.childNodes(element);
         }
         // boundTextNodes
         var textNodeIndices = binder.textNodeIndices;
         for (var i = 0; i < textNodeIndices.length; i++) {
             boundTextNodes[boundTextNodeIdx++] = childNodes[textNodeIndices[i]];
         }
         // contentTags
         var contentTag = null;
         if (lang_1.isPresent(binder.contentTagSelector)) {
             contentTag = new content_tag_1.Content(element, binder.contentTagSelector);
         }
         boundElements[binderIdx] = new element_1.DomElement(binder, element, contentTag);
     }
     var view = new view_1.DomView(protoView, viewRootNodes, boundTextNodes, boundElements);
     for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
         var binder = binders[binderIdx];
         var element = boundElements[binderIdx];
         var domEl = element.element;
         // lightDoms
         var lightDom = null;
         // Note: for the root element we can't use the binder.elementIsEmpty
         // information as we don't use the element from the ProtoView
         // but an element from the document.
         if (lang_1.isPresent(binder.componentId) && (!binder.elementIsEmpty || lang_1.isPresent(inplaceElement))) {
             lightDom = this._shadowDomStrategy.constructLightDom(view, domEl);
         }
         element.lightDom = lightDom;
         // init contentTags
         var contentTag = element.contentTag;
         if (lang_1.isPresent(contentTag)) {
             var directParentLightDom = this._directParentLightDom(view, binderIdx);
             contentTag.init(directParentLightDom);
         }
         // events
         if (lang_1.isPresent(binder.eventLocals) && lang_1.isPresent(binder.localEvents)) {
             for (var i = 0; i < binder.localEvents.length; i++) {
                 this._createEventListener(view, domEl, binderIdx, binder.localEvents[i].name, binder.eventLocals);
             }
         }
     }
     return view;
 };
Example #4
0
  _createView(protoView:ProtoView): View {
    var rootElementClone = protoView.isRootView ? protoView.element : DOM.importIntoDoc(protoView.element);
    var elementsWithBindingsDynamic;
    if (protoView.isTemplateElement) {
      elementsWithBindingsDynamic = DOM.querySelectorAll(DOM.content(rootElementClone), NG_BINDING_CLASS_SELECTOR);
    } else {
      elementsWithBindingsDynamic = DOM.getElementsByClassName(rootElementClone, NG_BINDING_CLASS);
    }

    var elementsWithBindings = ListWrapper.createFixedSize(elementsWithBindingsDynamic.length);
    for (var binderIdx = 0; binderIdx < elementsWithBindingsDynamic.length; ++binderIdx) {
      elementsWithBindings[binderIdx] = elementsWithBindingsDynamic[binderIdx];
    }

    var viewRootNodes;
    if (protoView.isTemplateElement) {
      var childNode = DOM.firstChild(DOM.content(rootElementClone));
      viewRootNodes = []; // TODO(perf): Should be fixed size, since we could pre-compute in in ProtoView
      // Note: An explicit loop is the fastest way to convert a DOM array into a JS array!
      while(childNode != null) {
        ListWrapper.push(viewRootNodes, childNode);
        childNode = DOM.nextSibling(childNode);
      }
    } else {
      viewRootNodes = [rootElementClone];
    }

    var binders = protoView.elementBinders;
    var boundTextNodes = [];
    var boundElements = ListWrapper.createFixedSize(binders.length);
    var viewContainers = ListWrapper.createFixedSize(binders.length);
    var contentTags = ListWrapper.createFixedSize(binders.length);

    for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
      var binder = binders[binderIdx];
      var element;
      if (binderIdx === 0 && protoView.rootBindingOffset === 1) {
        element = rootElementClone;
      } else {
        element = elementsWithBindings[binderIdx - protoView.rootBindingOffset];
      }
      boundElements[binderIdx] = element;

      // boundTextNodes
      var childNodes = DOM.childNodes(DOM.templateAwareRoot(element));
      var textNodeIndices = binder.textNodeIndices;
      for (var i = 0; i<textNodeIndices.length; i++) {
        ListWrapper.push(boundTextNodes, childNodes[textNodeIndices[i]]);
      }

      // viewContainers
      var viewContainer = null;
      if (isBlank(binder.componentId) && isPresent(binder.nestedProtoView)) {
        viewContainer = new ViewContainer(this, element);
      }
      viewContainers[binderIdx] = viewContainer;

      // contentTags
      var contentTag = null;
      if (isPresent(binder.contentTagSelector)) {
        contentTag = new Content(element, binder.contentTagSelector);
      }
      contentTags[binderIdx] = contentTag;
    }

    var view = new View(
      protoView, viewRootNodes,
      boundTextNodes, boundElements, viewContainers, contentTags
    );

    for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
      var binder = binders[binderIdx];
      var element = boundElements[binderIdx];

      // static child components
      if (isPresent(binder.componentId) && isPresent(binder.nestedProtoView)) {
        var childView = this._createView(binder.nestedProtoView);
        view.setComponentView(this._shadowDomStrategy, binderIdx, childView);
      }

      // events
      if (isPresent(binder.eventLocals)) {
        ListWrapper.forEach(binder.eventNames, (eventName) => {
          this._createEventListener(view, element, binderIdx, eventName, binder.eventLocals);
        });
      }
    }

    if (protoView.isRootView) {
      view.hydrate(null);
    }

    return view;
  }