コード例 #1
0
module.exports = function elementIsVisible(el) {
    if (el.dom) el = el.dom; //ExtJS Element (hopefully)
    if (el instanceof jQuery) el = el[0];
    var t = benchmarkBox.now();

    /* variant 1: Ext2: has dependency on ext2
    //var ret = Ext2.fly(el).isVisible();
    */

    /* variant 2: jquery: not always correct
    //var ret = $(el).is(':visible');
    */

    /* variant 3: manuallycheck visiblity+display, basically what ext2 does */
    var ret = true;
    while (el && el.tagName && el.tagName.toLowerCase() != "body") {
        var vis = !($(el).css('visibility') == 'hidden' || $(el).css('display') == 'none');
        if (!vis) {
            ret = false;
            break;
        }
        el = el.parentNode;
    }

    benchmarkBox.time('isVisible uncached', benchmarkBox.now()-t);
    return ret;
};
コード例 #2
0
module.exports = function getCachedWidth(e) {
    if (e.dom) e = e.dom; //ExtJS Element (hopefully)
    if (e.jquery) e = e.get(0);
    var ret = false;
    while (e) {
        if (e.getAttribute('data-width') == '100%') {
        } else if (typeof e.kwfWidthCache != 'undefined') {
            ret = e.kwfWidthCache;
            break;
        } else {
            var t = benchmarkBox.now();
            if (e.tagName == 'MAIN') {
                //IE 12 returns clientWidth 0 for <main>??!
                ret = e.offsetWidth;
            } else {
                ret = e.clientWidth;
            }
            benchmarkBox.time('getWidth uncached', benchmarkBox.now()-t);
            e.kwfWidthCache = ret;
            cachedWidthEls.push(e);
            break;
        }
        e = e.parentNode;
    }
    return ret;
};
コード例 #3
0
 setTimeout(function() {
     deferredStart = benchmarkBox.now();
     if (enableOnReadyConsoleProfile) console.profile("callOnContentReady body deferred");
     onReadyState = 'callDefer';
     callOnContentReady(document.body, { action: 'render' });
     onReadyState = 'calledDefer';
 }, 10);
コード例 #4
0
 var processNext = function processNext() {
     benchmarkBox.count('chunks');
     var t = benchmarkBox.now();
     while (onReadyElQueue.length && benchmarkBox.now()-t < 50) {
         processOnReadyElQueueEntry();
     }
     if (onReadyElQueue.length) {
         setTimeout(processNext, 1);
     } else {
         onReadyIsCalling = false;
         benchmarkBox.time('time', benchmarkBox.now()-deferredStart);
         if (enableOnReadyConsoleProfile) console.profileEnd();
         benchmarkBox.create({
             type: 'onReady defer'
         });
     }
 };
コード例 #5
0
    //call the callback of an element ready handler
    function callQueueFn(queueEntry, config)
    {
        var t = benchmarkBox.now();
        var el = queueEntry.el;
        if (queueEntry.onAction != 'contentReady') {
            el = $(el);
        }
        queueEntry.fn.call(queueEntry.options.scope || window, el, config);
        var fnName = queueEntry.fn.name;
        if (!fnName) {
            fnName = 'unknown';
        }

        benchmarkBox.subTime(
            'on'+queueEntry.onAction.charAt(0).toUpperCase() + queueEntry.onAction.slice(1),
            'fn: '+fnName,
            benchmarkBox.now()-t
        );
    };
コード例 #6
0
module.exports = function getCachedWidth(e) {
    if (e.dom) renderedEl = e.dom; //ExtJS Element (hopefully)
    if (e instanceof $) e = e.get(0);
    var ret = false;
    while (e) {
        if (e.getAttribute('data-width') == '100%') {
        } else if (typeof e.kwfWidthCache != 'undefined') {
            ret = e.kwfWidthCache;
            break;
        } else {
            var t = benchmarkBox.now();
            ret = e.clientWidth;
            benchmarkBox.time('getWidth uncached', benchmarkBox.now()-t);
            e.kwfWidthCache = ret;
            cachedWidthEls.push(e);
            break;
        }
        e = e.parentNode;
    }
    return ret;
};
コード例 #7
0
$(document).ready(function() {
    if ($(document.body).is('.kwfUp-frontend')) {
        if (!document.body) {
            //this happens if a redirect by changing location in JS is done
            //in that case no contentReady needs to be called
            return;
        }
        var t = benchmarkBox.now();
        if (enableOnReadyConsoleProfile) console.profile("callOnContentReady body");
        onReadyState = 'callNonDefer';
        callOnContentReady(document.body, { action: 'render' });
        onReadyState = 'calledNonDefer';
        if (enableOnReadyConsoleProfile) console.profileEnd();
        benchmarkBox.time('time', benchmarkBox.now()-t);
        benchmarkBox.create({
            type: 'onReady'
        });
        setTimeout(function() {
            deferredStart = benchmarkBox.now();
            if (enableOnReadyConsoleProfile) console.profile("callOnContentReady body deferred");
            onReadyState = 'callDefer';
            callOnContentReady(document.body, { action: 'render' });
            onReadyState = 'calledDefer';
        }, 10);

        var timeoutId;
        $(window).resize(function() {
            if (timeoutId) {
                clearTimeout(timeoutId);
            }
            timeoutId = setTimeout(function() {
                callOnContentReady(document.body, { action: 'widthChange' } );
            }, 100);
        });
    }
});
コード例 #8
0
var callOnContentReady = function(renderedEl, options)
{
    benchmarkBox.count('callOnContentReady');
    if (!options) options = {};
    if (typeof options.newRender != 'undefined') {
        //backwards compatibility, for callOnContentReady call
        options.action = options.newRender ? 'render' : 'show';
        delete options.newRender;
    }
    if (!options.action) {
        if (typeof console != 'undefined' && console.warn) console.warn('Please set option action on callOnContentReady');
        options.action = 'render';
    }
    if (!renderedEl) {
        if (typeof console != 'undefined' && console.warn) console.warn('Please pass element argument on callOnContentReady');
        renderedEl = document.body;
    }
    if (renderedEl.dom) renderedEl = renderedEl.dom; //ExtJS Element (hopefully)
    if (renderedEl.jquery) {
        renderedEl.each(function(){ callOnContentReady(this, options); });
        return;
    }

    //add entries to onReadyElQueue, depending on renderedEl
    var onActions;
    if (options.action == 'render') {
        onActions = ['render', 'show', 'widthChange', 'contentReady'];
    } else if (options.action == 'show') {
        onActions = ['show', 'widthChange', 'contentReady'];
    } else if (options.action == 'hide') {
        onActions = ['hide'];
    } else if (options.action == 'widthChange') {
        onActions = ['widthChange', 'contentReady'];
    }

    var html = false;
    for (var i = 0; i < readyElHandlers.length; i++) {
        var hndl = readyElHandlers[i];
        if (options.handlerNum && $.inArray(hndl.num, options.handlerNum) == -1) {
            continue;
        }

        //onReadyState gets set before callOnContentReady(body)
        //can not be part of options as it would be missing in recursive calls
        if (onReadyState == 'callNonDefer') {
            if (hndl.options.defer) {
                continue;
            }
        } else if (onReadyState == 'callDefer') {
            if (!hndl.options.defer) {
                continue;
            }
        }

        if (hndl.options.checkVisibility) {
            if (renderedEl != document.body && !elementIsVisible(renderedEl)) {
                if (options.action == 'render' && hndl.selector && elCacheBySelector[hndl.selector]) {
                    //mark cache as dirty as we don't query (and update the selector) as the renderedEl is invisible
                    //TODO don't always mark as dirty especially when we have multiple handlers with same selector
                    elCacheBySelector[hndl.selector].dirty = true;
                }
                continue;
            }
            //if checkVisibility is activated, don't skip based on onActions as
            //even a widthChange action could make an element visible (media queries)
        } else {
            if ($.inArray(hndl.onAction, onActions) == -1) {
                continue;
            }
        }

        if (options.action == 'render' && !html) {
            var t = benchmarkBox.now();
            html = renderedEl.innerHTML;
            benchmarkBox.time('innerHTML', benchmarkBox.now()-t);
        }

        var useSelectorCache;
        if (options.action != 'render' || !hndl.selector) {
            useSelectorCache = true;
        } else {
            if (onReadyState == 'callDefer' && renderedEl == document.body && elCacheBySelector[hndl.selector]) {
                useSelectorCache = true;
            } else {
                var t = benchmarkBox.now();
                var m = hndl.selector.match(/^[a-z]*\.([a-z]+)/i);
                //do a stupid text search on the selector, using that we can skip query for many selectors that don't exist in the current el
                if (m && html.indexOf(m[1]) == -1) {
                    useSelectorCache = true;
                    if (!elCacheBySelector[hndl.selector]) {
                        elCacheBySelector[hndl.selector] = [];
                    }
                } else {
                    useSelectorCache = false;
                }
                benchmarkBox.time('checkInnerHtml', benchmarkBox.now()-t);
            }
        }

        if (useSelectorCache && elCacheBySelector[hndl.selector] && !elCacheBySelector[hndl.selector].dirty) {
            benchmarkBox.count('queryCache');
            var els = [];
            for (var j=0; j<elCacheBySelector[hndl.selector].length; j++) {
                if (renderedEl == document.body ||
                    renderedEl == elCacheBySelector[hndl.selector][j] ||
                    $.contains(renderedEl, elCacheBySelector[hndl.selector][j])
                ) {
                    els.push(elCacheBySelector[hndl.selector][j]);
                }
            }
        } else if (!hndl.selector) {
            var els = $.makeArray($(renderedEl));
        } else {
            var t = benchmarkBox.now();
            var els = $.makeArray($(renderedEl).find(hndl.selector));
            if (matchesSelector(renderedEl, hndl.selector)) {
                els.push(renderedEl);
            }
            benchmarkBox.time('query', benchmarkBox.now() - t);
            if (!elCacheBySelector[hndl.selector]) {
                elCacheBySelector[hndl.selector] = els;
            } else {
                for(var j=0; j<els.length; ++j) {
                    if ($.inArray(els[j], elCacheBySelector[hndl.selector]) == -1) {
                        elCacheBySelector[hndl.selector].push(els[j]);
                    }
                }
            }
        }

        for (var j = 0; j< els.length; ++j) {

            var alreadyInQueue = false;
            $.each(onReadyElQueue, function(indx, queueEntry) {
                if (queueEntry.num == hndl.num && els[j] == queueEntry.el) {
                    alreadyInQueue = true;
                }
            });

            if (!alreadyInQueue) {
                var parentsCount = 0;
                var n = els[j];
                while (n = n.parentNode) {
                    parentsCount++;
                }
                benchmarkBox.count('readyEl');
                onReadyElQueue.push({
                    el: els[j],
                    fn: hndl.fn,
                    options: hndl.options,
                    num: hndl.num,
                    callerOptions: options,
                    onAction: hndl.onAction,
                    selector: hndl.selector,
                    priority: hndl.options.priority || 0,
                    parentsCount: parentsCount
                });
            }
        }
    }

    //sort onReadyElQueue
    var t = benchmarkBox.now();
    onReadyElQueue.sort(function sortOnReadyElQueue(a, b) {
        if (a.priority != b.priority) {
            return a.priority - b.priority;
        } else {
            if (a.parentsCount != b.parentsCount) {
                return a.parentsCount - b.parentsCount;
            } else {
                return a.num - b.num;
            }
        }
    });
    benchmarkBox.time('sort', benchmarkBox.now() - t);

    if (onReadyIsCalling) {
        return;
    }

    onReadyIsCalling = true;

    //call the callback of an element ready handler
    function callQueueFn(queueEntry, config)
    {
        var t = benchmarkBox.now();
        var el = queueEntry.el;
        if (queueEntry.onAction != 'contentReady') {
            el = $(el);
        }
        queueEntry.fn.call(queueEntry.options.scope || window, el, config);
        var fnName = queueEntry.fn.name;
        if (!fnName) {
            fnName = 'unknown';
        }

        benchmarkBox.subTime(
            'on'+queueEntry.onAction.charAt(0).toUpperCase() + queueEntry.onAction.slice(1),
            'fn: '+fnName,
            benchmarkBox.now()-t
        );
    };

    //process one entry of the readyElQueue
    //own function so it can be called in sync or in deferred chunks
    function processOnReadyElQueueEntry()
    {
        var queueEntry = onReadyElQueue.shift();
        var el = queueEntry.el;
        if (queueEntry.onAction == 'render') {
            if (queueEntry.options.checkVisibility && !elementIsVisible(el)) {
                return;
            }
            if (!el.initDone) el.initDone = {};
            if (el.initDone[queueEntry.num]) {
                return;
            }
            el.initDone[queueEntry.num] = true;
            var config = {};
            var configEl = $(el).find('> input[type="hidden"]');
            if (configEl.length) {
                try {
                    var v = configEl.get(0).value;
                    if (v.substr(0, 1) == '{' || v.substr(0, 1) == '[') {
                        config = $.parseJSON(v);
                    }
                } catch (err) {}
            }
            callQueueFn(queueEntry, config);
        } else if (queueEntry.onAction == 'show') {
            if (elementIsVisible(el)) {
                callQueueFn(queueEntry);
            }
        } else if (queueEntry.onAction == 'hide') {
            if (!elementIsVisible(el)) {
                callQueueFn(queueEntry);
            }
        } else if (queueEntry.onAction == 'widthChange') {
            if (!queueEntry.options.checkVisibility || elementIsVisible(el)) {
                callQueueFn(queueEntry);
            }
        } else if (queueEntry.onAction == 'contentReady') {
            var options = {
                newRender: (queueEntry.callerOptions.action == 'render'),
                action: queueEntry.callerOptions.action
            };
            callQueueFn(queueEntry, options);
        }
    }

    if (onReadyState == 'callDefer') {
        var processNext = function processNext() {
            benchmarkBox.count('chunks');
            var t = benchmarkBox.now();
            while (onReadyElQueue.length && benchmarkBox.now()-t < 50) {
                processOnReadyElQueueEntry();
            }
            if (onReadyElQueue.length) {
                setTimeout(processNext, 1);
            } else {
                onReadyIsCalling = false;
                benchmarkBox.time('time', benchmarkBox.now()-deferredStart);
                if (enableOnReadyConsoleProfile) console.profileEnd();
                benchmarkBox.create({
                    type: 'onReady defer'
                });
            }
        };
        processNext();
    } else {
        while (onReadyElQueue.length) {
            processOnReadyElQueueEntry();
        }
        onReadyIsCalling = false;
    }

};