function declarativeBindImpl()

in archived/SharedContent/js/Microsoft.WinJS/js/base.js [19708:19820]


    function declarativeBindImpl(rootElement, dataContext, skipRoot, bindingCache, defaultInitializer, c) {
        _WriteProfilerMark("WinJS.Binding:processAll,StartTM");

        var pend = {
            count: 0,
            checkComplete: function checkComplete() {
                this.count--;
                if (this.count === 0) {
                    _WriteProfilerMark("WinJS.Binding:processAll,StopTM");
                    c();
                }
            }
        };
        var baseElement = (rootElement || _Global.document.body);
        var selector = "[data-win-bind],[data-win-control]";
        var elements = baseElement.querySelectorAll(selector);
        var neg;
        if (!skipRoot && (baseElement.getAttribute("data-win-bind") || baseElement.winControl)) {
            neg = baseElement;
        }

        pend.count++;
        var source = dataContext || _Global;

        _DomWeakRefTable._DOMWeakRefTable_fastLoadPath = true;
        try {
            var baseElementData = _ElementUtilities.data(baseElement);
            baseElementData.winBindings = baseElementData.winBindings || [];

            for (var i = (neg ? -1 : 0), l = elements.length; i < l; i++) {
                var element = i < 0 ? neg : elements[i];

                // If we run into a declarative control container (e.g. Binding.Template) we don't process its
                //  children, but we do give it an opportunity to process them later using this data context.
                //
                if (element.winControl && element.winControl.constructor && element.winControl.constructor.isDeclarativeControlContainer) {
                    i += element.querySelectorAll(selector).length;

                    var idcc = element.winControl.constructor.isDeclarativeControlContainer;
                    if (typeof idcc === "function") {
                        idcc = requireSupportedForProcessing(idcc);
                        idcc(element.winControl, function (element) {
                            return declarativeBind(element, dataContext, false, bindingCache, defaultInitializer);
                        });
                    }
                }

                // In order to catch controls above we may have elements which don't have bindings, skip them
                //
                if (!element.hasAttribute("data-win-bind")) {
                    continue;
                }

                var original = element.getAttribute("data-win-bind");
                var declBind = calcBinding(original, bindingCache);

                if (!declBind.implemented) {
                    for (var bindIndex = 0, bindLen = declBind.length; bindIndex < bindLen; bindIndex++) {
                        var bind = declBind[bindIndex];
                        bind.initializer = bind.initializer || defaultInitializer;
                        if (bind.initializer) {
                            bind.implementation = initializerOneBinding;
                        } else {
                            bind.implementation = sourceOneBinding;
                        }
                    }
                    declBind.implemented = true;
                }

                pend.count++;

                var bindingId = setBindingToken(element);
                var ref = optimizeBindingReferences ? bindingId : element.id;

                if (!ref) {
                    // We use our own counter here, as the IE "uniqueId" is only
                    // global to a document, which means that binding against
                    // unparented DOM elements would get duplicate IDs.
                    //
                    // The elements may not be parented at this point, but they
                    // will be parented by the time the binding action is fired.
                    //
                    element.id = ref = bindingId;
                }

                _DomWeakRefTable._createWeakRef(element, ref);
                var elementData = _ElementUtilities.data(element);
                elementData.winBindings = null;
                var cacheEntry;
                if (bindingCache && bindingCache.elements) {
                    cacheEntry = bindingCache.elements[ref];
                    if (!cacheEntry) {
                        bindingCache.elements[ref] = cacheEntry = { bindings: [] };
                    }
                }

                for (var bindIndex2 = 0, bindLen2 = declBind.length; bindIndex2 < bindLen2; bindIndex2++) {
                    var bind2 = declBind[bindIndex2];
                    var cancel2 = bind2.implementation(bind2, ref, bindingId, source, element, pend, cacheEntry);
                    if (cancel2) {
                        elementData.winBindings = elementData.winBindings || [];
                        elementData.winBindings.push(cancel2);
                        baseElementData.winBindings.push(cancel2);
                    }
                }
                pend.count--;
            }
        }
        finally {
            _DomWeakRefTable._DOMWeakRefTable_fastLoadPath = false;
        }
        pend.checkComplete();
    }