<commit_before>var V = _.xValue = {
    /*jshint evil:true */
    resolve: function(context, reference) {
        var full = 'context["'+reference+'"]';
        try {
            return eval(full+'||context.'+reference);
        } catch (e) {
            return eval(full);
        }
    },
    name: function(node) {
        if (node.nodeType === 3 && !node.noSubNames) {
            node.splitOnName();// ensure this is run before node.name
        }
        return node.tagName === 'FORM' ? node.getAttribute('name') : node.name;
    },
    parse: function(value) {
        if (typeof value === "string") {
            try {
                value = JSON.parse(value);
            } catch (e) {}
        } else if (Array.isArray(value)) {
            value = value.map(V.parse);
        }
        return value;
    },
    string: function(value) {
        if (value !== undefined && typeof value !== "string") {
            try {
                value = JSON.stringify(value);
            } catch (e) {
                value = value+'';
            }
        }
        return value;
    },
    stringifyFor: function(el) {
        var stringify = el.getAttribute('x-value-stringify');
        return stringify && V.resolve(window, stringify) || V.string;
    },
    nameNodes: function(parent, nameFn, possibleParentFn, attrFn) {
        for (var i=0, done = []; i<parent.childNodes.length; i++) {
            var node = parent.childNodes[i],
                name = V.name(node);
            if (name && done.indexOf(name) < 0) {
                done.push(name);
                nameFn(name, node);
            } else if (possibleParentFn && !node.useBaseValue()) {
                possibleParentFn(node);
            } else if (node.useAttrValues) {
                V.nameAttrs(node, attrFn);
            }
        }
        if (parent.useAttrValues) {
            V.nameAttrs(parent, attrFn);
        }
    },
    nameAttrs: function(node, attrFn) {
        var allowed = node.getAttribute('x-value-attr').split(',');
        for (var a=0; a < node.attributes.length; a++) {
            var attr = node.attributes[a];
            if (allowed.indexOf(attr.name) >= 0) {
                attrFn(attr);
            }
        }
    },
    combine: function(oldValue, newValue, rejectNull) {
        if (oldValue === undefined || oldValue === newValue ||
            (rejectNull && oldValue === null)) {
            return newValue;
        }
        if (Array.isArray(oldValue)) {
            if (oldValue.indexOf(newValue) < 0) {
                oldValue.push(newValue);
            }
            return oldValue;
        }
        return [oldValue, newValue];
    },
    getNameValue: function(parent, value) {
        V.nameNodes(parent, function(name, node) {
            value[name] = V.combine(value[name], node.nameValue);
        }, function(possibleParent) {
            V.getNameValue(possibleParent, value);
        }, function(attr) {
            value[attr.name] = attr.baseValue;
        });
        return value;
    },
    setNameValue: function(parent, values) {
        V.nameNodes(parent, function(name, node) {
            var value = V.resolve(values, name);
            if (value !== undefined) {
                node.nameValue = value;
            }
        }, function(possibleParent) {
            V.setNameValue(possibleParent, values);
        }, function(attr) {
            var value = V.resolve(values, attr.name);
            if (value !== undefined) {
                attr.baseValue = value;
            }
        });
    },
    booleanAttr: function(attr) {
        return {
            get: function() {
                return this.hasAttribute(attr);
            },
            set: function(value) {
                this[value ? 'setAttribute' : 'removeAttribute'](attr, true);
            }
        };
    },
    nameRE: /\$\{([^}]+)\}/,
    changeEvent: window.CustomEvent ? function(node) {
        node.dispatchEvent(new CustomEvent('change', { bubbles:true }));
    } : function(node) {
        var e = D.createEvent('CustomEvent');
        e.initCustomEvent('change', true);
        node.dispatchEvent(e);
    }
};

_.define([Node], {
    value: {
        get: function() {
            return this.hasAttribute && this.hasAttribute('value') ?
                this.getAttribute('value') :
                this.textContent;
        },
        set: function(value) {
            if (this.hasAttribute && this.hasAttribute('value')) {
                this.setAttribute('value', value);
            } else {
                this.textContent = value;
            }
        }
    },
    baseValue:  {
        get: function(){ return V.parse(this.value); },
        set: function(value) {
            var oldValue = this.value,
                newValue = this.value = V.string(value);
            if (oldValue !== newValue) {
                V.changeEvent(this);
            }
        }
    },
    useBaseValue: function() {
        var kids = this.childNodes;
        if (this.noSubNames || !kids.length) {
            return true;// always use base when no descendents
        }
        if (kids.length > 1 || kids[0].name || this.children.length) {
            return false;// never use base with multiple kids, named kid, or element children
        }
        // if Text, check if it just hasn't be split yet.
        return !kids[0].splitOnName || !kids[0].splitOnName();
    },
    nameParent: {
        get: function() {
            var node = this,
                parent;
            while ((parent = node.parentNode)) {
                if (V.name(parent) ||
                    (parent.hasAttribute && parent.hasAttribute('x-value-parent'))) {
                    return parent;
                }
                node = parent;
            }
            return node === this ? null : node;
        }
    },
    nameGroup: {
        get: function() {
            var el = this,
                name = V.name(el);
            return name ? el.parentNode ?
                el.nameParent.queryNameAll(name) :
                new X.List(el) :
                null;
        }
    },
    nameValue: {
        get: function() {
            var values;
            if (V.name(this)) {
                this.nameGroup.each(function(node) {
                    values = V.combine(values, node.xValue);
                });
            }
            return values || this.xValue;
        },
        set: function(values) {
            if (V.name(this) && Array.isArray(values)) {
                var group = this.nameGroup;
                if (_.repeat && !values.length && group.length && !group[0].hasAttribute(_.repeat.id)) {
                    _.repeat.init(group[0], true);
                }
                group.each(function(node, i) {
                    if (i < values.length) {
                        node.nameValue = values[i];
                    } else {
                        node.remove();
                    }
                });
                while (group.length < values.length) {
                    var last = group[group.length - 1];
                    group.add(last.repeat(values[group.length]));
                }
            } else if (this.tagName === 'X-REPEAT') {
                this.repeat(values);
            } else {
                this.xValue = values;
            }
        }
    },
    xValue: {
        get: function() {
            return this.useBaseValue() ? this.baseValue : V.getNameValue(this, {});
        },
        set: function(value) {
            if (this.useBaseValue() || typeof value !== "object") {
                this.baseValue = value;
            } else {
                V.setNameValue(this, value);
            }
        }
    }
});
_.define([Attr], {
    useBaseValue: function(){ return true; },
}, true);

_.define([Element], {
    name: {
        get: function(){ return this.getAttribute('name'); },
        set: function(name){ this.setAttribute('name', name); }
    },
    baseProperty: 'value',
    baseValue: {
        get: function() {
            var parser = this.getAttribute('x-value-parse');
            parser = parser && V.resolve(window, parser) || V.parse;
            return parser.call(this, this[this.baseProperty]);
        },
        set: function(value) {
            var oldValue = this[this.baseProperty],
                newValue = this[this.baseProperty] = V.stringifyFor(this).call(this, value);
            if (oldValue !== newValue) {
                V.changeEvent(this);
            }
        }
    },
    useAttrValues: V.booleanAttr('x-value-attr'),
    noSubNames: V.booleanAttr('x-value-none')
}, true);

_.define(X.containers, {
    queryName: function(name) {
        return this.queryNameAll(name, 1)[0];
    },
    queryNameAll: function(name, count, _list) {
        _list = _list || new X.List(count);
        var parents = _.isList(this) ? this : [this];
        for (var s=0; s < parents.length && !_list.isFull(); s++) {
            var parent = parents[s],
                xrepeat = null;
            for (var i=0; i < parent.childNodes.length && !_list.isFull(); i++) {
                var node = parent.childNodes[i],
                    nodeName = V.name(node);
                if (nodeName === name) {
                    if (node.tagName === 'X-REPEAT') {
                        if (xrepeat !== false) {
                            xrepeat = node;
                        }
                    } else {
                        xrepeat = false;
                        _list.add(node);
                    }
                } else if (node.nodeType === 1) {
                    if (nodeName) {
                        if (name.indexOf(nodeName+'.') === 0) {
                            node.queryNameAll(name.substring(nodeName.length+1), count, _list);
                        }
                    } else {
                        node.queryNameAll(name, count, _list);
                    }
                }
            }
            if (xrepeat) {
                _list.add(xrepeat);
            }
            if (parent.useAttrValues && !_list.isFull()) {
                var el = this,
                    allowed = parent.getAttribute('x-value-attr').split(',');
                if (allowed.indexOf(name) >= 0) {
                    for (var a=0; a < el.attributes.length; a++) {
                        var attr = el.attributes[a];
                        if (attr.name === name) {
                            attr.parentNode = el;
                            _list.add(attr);
                            break;
                        }
                    }
                }
            }
        }
        return _list;
    }
});

_.define([Text], {
    useBaseValue: function() {
        return true;
    },
    splitOnName: function() {
        var text = this,
            match = text.textContent.match(V.nameRE);
        if (match) {
            var start = match.index,
                name = match[0];
            if (start > 0) {
                text.splitText(start);
                text.noSubNames = true;
                text = text.nextSibling;
            }
            if (text.textContent.length > name.length) {
                text.splitText(name.length);
            }
            text.name = match[1];
            text.textContent = '';
        }
        // all have no sub names after splitting
        text.noSubNames = true;
        return !!match;
    }
}, true);

_.define([HTMLInputElement], {
    checkable: {
        get: function() {
            return this.type === 'radio' || this.type === 'checkbox';
        }
    },
    xValue:  {
        get: function() {
            return !this.checkable || this.checked ? this.baseValue : null;
        },
        set: function(value) {
            var input = this;
            if (input.checkable && (input.value !== "" || input.hasAttribute('value'))) {
                value = (Array.isArray(value) ? value : [value]).map(V.stringifyFor(input));
                var was = input.checked;
                input.checked = value.indexOf(input.value) >= 0;
                if (was !== input.checked) {
                    V.changeEvent(input);
                }
            } else {
                this.baseValue = value;
            }
        }
    },
    nameValue: {
        get: function() {
            if (this.checkable) {
                var group = this.nameGroup,
                    value;
                group.each(function(node) {
                    value = V.combine(value, node.xValue, true);
                });
                return Array.isArray(value) && (this.type === 'radio' || group.length === 1) ?
                    value[0] :
                    value;
            }
            return this.baseValue;
        },
        set: function(value) {
            if (this.checkable) {
                value = (Array.isArray(value) ? value : [value]).map(V.stringifyFor(this));
                var changed = false;
                this.nameGroup.each(function(input) {
                    var was = input.checked;
                    input.checked = value.indexOf(input.value) >= 0;
                    if (was !== input.checked) {
                        changed = true;
                    }
                });
                if (changed) {
                    V.changeEvent(this);
                }
            } else {
                this.baseValue = value;
            }
        }
    }
}, true);

_.define([HTMLSelectElement], {
    xValue: {
        get: function() {
            if (this.multiple) {
                var selected = this.children.only('selected', true);
                return selected.length ? selected.each('xValue') :
                    this.children.length > 1 ? [] : null;
            }
            return V.parse(this.baseValue);
        },
        set: function(value) {
            if (this.multiple) {
                value = (Array.isArray(value) ? value : [value]).map(V.string);
                var changed = false;
                this.children.each(function(option) {
                    var was = option.selected;
                    option.selected = value.indexOf(option.value) >= 0;
                    if (option.select !== was) {
                        changed = true;
                    }
                });
                if (changed) {
                    V.changeEvent(this);
                }
            } else {
                this.baseValue = value;
            }
        }
    }
}, true);

_.define([HTMLLIElement], {
    baseProperty: {
        get: function() {
            // ordered ones use relative index, unordered ones use text
            return this.parentNode instanceof HTMLOListElement ?
                'value' :
                'textContent';
        }
    }
}, true);

_.define([HTMLOptionElement], {
    baseProperty: {
        get: function() {
            return this.hasAttribute('value') ?
                'value' :
                'textContent';
        }
    }
}, true);
<commit_msg>parentNode is read-only in safari<commit_after>var V = _.xValue = {
    /*jshint evil:true */
    resolve: function(context, reference) {
        var full = 'context["'+reference+'"]';
        try {
            return eval(full+'||context.'+reference);
        } catch (e) {
            return eval(full);
        }
    },
    name: function(node) {
        if (node.nodeType === 3 && !node.noSubNames) {
            node.splitOnName();// ensure this is run before node.name
        }
        return node.tagName === 'FORM' ? node.getAttribute('name') : node.name;
    },
    parse: function(value) {
        if (typeof value === "string") {
            try {
                value = JSON.parse(value);
            } catch (e) {}
        } else if (Array.isArray(value)) {
            value = value.map(V.parse);
        }
        return value;
    },
    string: function(value) {
        if (value !== undefined && typeof value !== "string") {
            try {
                value = JSON.stringify(value);
            } catch (e) {
                value = value+'';
            }
        }
        return value;
    },
    stringifyFor: function(el) {
        var stringify = el.getAttribute('x-value-stringify');
        return stringify && V.resolve(window, stringify) || V.string;
    },
    nameNodes: function(parent, nameFn, possibleParentFn, attrFn) {
        for (var i=0, done = []; i<parent.childNodes.length; i++) {
            var node = parent.childNodes[i],
                name = V.name(node);
            if (name && done.indexOf(name) < 0) {
                done.push(name);
                nameFn(name, node);
            } else if (possibleParentFn && !node.useBaseValue()) {
                possibleParentFn(node);
            } else if (node.useAttrValues) {
                V.nameAttrs(node, attrFn);
            }
        }
        if (parent.useAttrValues) {
            V.nameAttrs(parent, attrFn);
        }
    },
    nameAttrs: function(node, attrFn) {
        var allowed = node.getAttribute('x-value-attr').split(',');
        for (var a=0; a < node.attributes.length; a++) {
            var attr = node.attributes[a];
            if (allowed.indexOf(attr.name) >= 0) {
                attrFn(attr);
            }
        }
    },
    combine: function(oldValue, newValue, rejectNull) {
        if (oldValue === undefined || oldValue === newValue ||
            (rejectNull && oldValue === null)) {
            return newValue;
        }
        if (Array.isArray(oldValue)) {
            if (oldValue.indexOf(newValue) < 0) {
                oldValue.push(newValue);
            }
            return oldValue;
        }
        return [oldValue, newValue];
    },
    getNameValue: function(parent, value) {
        V.nameNodes(parent, function(name, node) {
            value[name] = V.combine(value[name], node.nameValue);
        }, function(possibleParent) {
            V.getNameValue(possibleParent, value);
        }, function(attr) {
            value[attr.name] = attr.baseValue;
        });
        return value;
    },
    setNameValue: function(parent, values) {
        V.nameNodes(parent, function(name, node) {
            var value = V.resolve(values, name);
            if (value !== undefined) {
                node.nameValue = value;
            }
        }, function(possibleParent) {
            V.setNameValue(possibleParent, values);
        }, function(attr) {
            var value = V.resolve(values, attr.name);
            if (value !== undefined) {
                attr.baseValue = value;
            }
        });
    },
    booleanAttr: function(attr) {
        return {
            get: function() {
                return this.hasAttribute(attr);
            },
            set: function(value) {
                this[value ? 'setAttribute' : 'removeAttribute'](attr, true);
            }
        };
    },
    nameRE: /\$\{([^}]+)\}/,
    changeEvent: window.CustomEvent ? function(node) {
        node.dispatchEvent(new CustomEvent('change', { bubbles:true }));
    } : function(node) {
        var e = D.createEvent('CustomEvent');
        e.initCustomEvent('change', true);
        node.dispatchEvent(e);
    }
};

_.define([Node], {
    value: {
        get: function() {
            return this.hasAttribute && this.hasAttribute('value') ?
                this.getAttribute('value') :
                this.textContent;
        },
        set: function(value) {
            if (this.hasAttribute && this.hasAttribute('value')) {
                this.setAttribute('value', value);
            } else {
                this.textContent = value;
            }
        }
    },
    baseValue:  {
        get: function(){ return V.parse(this.value); },
        set: function(value) {
            var oldValue = this.value,
                newValue = this.value = V.string(value);
            if (oldValue !== newValue) {
                V.changeEvent(this);
            }
        }
    },
    useBaseValue: function() {
        var kids = this.childNodes;
        if (this.noSubNames || !kids.length) {
            return true;// always use base when no descendents
        }
        if (kids.length > 1 || kids[0].name || this.children.length) {
            return false;// never use base with multiple kids, named kid, or element children
        }
        // if Text, check if it just hasn't be split yet.
        return !kids[0].splitOnName || !kids[0].splitOnName();
    },
    nameParent: {
        get: function() {
            var node = this,
                parent;
            while ((parent = node.parentNode)) {
                if (V.name(parent) ||
                    (parent.hasAttribute && parent.hasAttribute('x-value-parent'))) {
                    return parent;
                }
                node = parent;
            }
            return node === this ? null : node;
        }
    },
    nameGroup: {
        get: function() {
            var el = this,
                name = V.name(el);
            return name ? el.parentNode ?
                el.nameParent.queryNameAll(name) :
                new X.List(el) :
                null;
        }
    },
    nameValue: {
        get: function() {
            var values;
            if (V.name(this)) {
                this.nameGroup.each(function(node) {
                    values = V.combine(values, node.xValue);
                });
            }
            return values || this.xValue;
        },
        set: function(values) {
            if (V.name(this) && Array.isArray(values)) {
                var group = this.nameGroup;
                if (_.repeat && !values.length && group.length && !group[0].hasAttribute(_.repeat.id)) {
                    _.repeat.init(group[0], true);
                }
                group.each(function(node, i) {
                    if (i < values.length) {
                        node.nameValue = values[i];
                    } else {
                        node.remove();
                    }
                });
                while (group.length < values.length) {
                    var last = group[group.length - 1];
                    group.add(last.repeat(values[group.length]));
                }
            } else if (this.tagName === 'X-REPEAT') {
                this.repeat(values);
            } else {
                this.xValue = values;
            }
        }
    },
    xValue: {
        get: function() {
            return this.useBaseValue() ? this.baseValue : V.getNameValue(this, {});
        },
        set: function(value) {
            if (this.useBaseValue() || typeof value !== "object") {
                this.baseValue = value;
            } else {
                V.setNameValue(this, value);
            }
        }
    }
});
_.define([Attr], {
    useBaseValue: function(){ return true; },
}, true);

_.define([Element], {
    name: {
        get: function(){ return this.getAttribute('name'); },
        set: function(name){ this.setAttribute('name', name); }
    },
    baseProperty: 'value',
    baseValue: {
        get: function() {
            var parser = this.getAttribute('x-value-parse');
            parser = parser && V.resolve(window, parser) || V.parse;
            return parser.call(this, this[this.baseProperty]);
        },
        set: function(value) {
            var oldValue = this[this.baseProperty],
                newValue = this[this.baseProperty] = V.stringifyFor(this).call(this, value);
            if (oldValue !== newValue) {
                V.changeEvent(this);
            }
        }
    },
    useAttrValues: V.booleanAttr('x-value-attr'),
    noSubNames: V.booleanAttr('x-value-none')
}, true);

_.define(X.containers, {
    queryName: function(name) {
        return this.queryNameAll(name, 1)[0];
    },
    queryNameAll: function(name, count, _list) {
        _list = _list || new X.List(count);
        var parents = _.isList(this) ? this : [this];
        for (var s=0; s < parents.length && !_list.isFull(); s++) {
            var parent = parents[s],
                xrepeat = null;
            for (var i=0; i < parent.childNodes.length && !_list.isFull(); i++) {
                var node = parent.childNodes[i],
                    nodeName = V.name(node);
                if (nodeName === name) {
                    if (node.tagName === 'X-REPEAT') {
                        if (xrepeat !== false) {
                            xrepeat = node;
                        }
                    } else {
                        xrepeat = false;
                        _list.add(node);
                    }
                } else if (node.nodeType === 1) {
                    if (nodeName) {
                        if (name.indexOf(nodeName+'.') === 0) {
                            node.queryNameAll(name.substring(nodeName.length+1), count, _list);
                        }
                    } else {
                        node.queryNameAll(name, count, _list);
                    }
                }
            }
            if (xrepeat) {
                _list.add(xrepeat);
            }
            if (parent.useAttrValues && !_list.isFull()) {
                var el = this,
                    allowed = parent.getAttribute('x-value-attr').split(',');
                if (allowed.indexOf(name) >= 0) {
                    for (var a=0; a < el.attributes.length; a++) {
                        var attr = el.attributes[a];
                        if (attr.name === name) {
                            if (!attr.parentNode) {
                                attr.parentNode = el;
                            }
                            _list.add(attr);
                            break;
                        }
                    }
                }
            }
        }
        return _list;
    }
});

_.define([Text], {
    useBaseValue: function() {
        return true;
    },
    splitOnName: function() {
        var text = this,
            match = text.textContent.match(V.nameRE);
        if (match) {
            var start = match.index,
                name = match[0];
            if (start > 0) {
                text.splitText(start);
                text.noSubNames = true;
                text = text.nextSibling;
            }
            if (text.textContent.length > name.length) {
                text.splitText(name.length);
            }
            text.name = match[1];
            text.textContent = '';
        }
        // all have no sub names after splitting
        text.noSubNames = true;
        return !!match;
    }
}, true);

_.define([HTMLInputElement], {
    checkable: {
        get: function() {
            return this.type === 'radio' || this.type === 'checkbox';
        }
    },
    xValue:  {
        get: function() {
            return !this.checkable || this.checked ? this.baseValue : null;
        },
        set: function(value) {
            var input = this;
            if (input.checkable && (input.value !== "" || input.hasAttribute('value'))) {
                value = (Array.isArray(value) ? value : [value]).map(V.stringifyFor(input));
                var was = input.checked;
                input.checked = value.indexOf(input.value) >= 0;
                if (was !== input.checked) {
                    V.changeEvent(input);
                }
            } else {
                this.baseValue = value;
            }
        }
    },
    nameValue: {
        get: function() {
            if (this.checkable) {
                var group = this.nameGroup,
                    value;
                group.each(function(node) {
                    value = V.combine(value, node.xValue, true);
                });
                return Array.isArray(value) && (this.type === 'radio' || group.length === 1) ?
                    value[0] :
                    value;
            }
            return this.baseValue;
        },
        set: function(value) {
            if (this.checkable) {
                value = (Array.isArray(value) ? value : [value]).map(V.stringifyFor(this));
                var changed = false;
                this.nameGroup.each(function(input) {
                    var was = input.checked;
                    input.checked = value.indexOf(input.value) >= 0;
                    if (was !== input.checked) {
                        changed = true;
                    }
                });
                if (changed) {
                    V.changeEvent(this);
                }
            } else {
                this.baseValue = value;
            }
        }
    }
}, true);

_.define([HTMLSelectElement], {
    xValue: {
        get: function() {
            if (this.multiple) {
                var selected = this.children.only('selected', true);
                return selected.length ? selected.each('xValue') :
                    this.children.length > 1 ? [] : null;
            }
            return V.parse(this.baseValue);
        },
        set: function(value) {
            if (this.multiple) {
                value = (Array.isArray(value) ? value : [value]).map(V.string);
                var changed = false;
                this.children.each(function(option) {
                    var was = option.selected;
                    option.selected = value.indexOf(option.value) >= 0;
                    if (option.select !== was) {
                        changed = true;
                    }
                });
                if (changed) {
                    V.changeEvent(this);
                }
            } else {
                this.baseValue = value;
            }
        }
    }
}, true);

_.define([HTMLLIElement], {
    baseProperty: {
        get: function() {
            // ordered ones use relative index, unordered ones use text
            return this.parentNode instanceof HTMLOListElement ?
                'value' :
                'textContent';
        }
    }
}, true);

_.define([HTMLOptionElement], {
    baseProperty: {
        get: function() {
            return this.hasAttribute('value') ?
                'value' :
                'textContent';
        }
    }
}, true);
<|endoftext|>


<commit_before>"use strict";

var reloadTimerId = null;
var oTable;
var colHdrs;     // e.g: ['sTitle': 'Testcase', 'sTitle': 'Env', ... ]
var rowHdrs;       // e.g: ['mixed-2suv', 'lucky6', ...]
var BASELINE = "1.8.1-938-rel-enterprise";
var WARNING = 0.1;
var ERROR = 0.3;

function Settings(testcase, metric) {
    this.testcase = testcase;
    this.metric = metric;
    this.baseline = BASELINE;
    this.error = ERROR;
    this.warning = WARNING;
}

function getSettings(settings) {
    /*
     * Get user defined settings
     */
    $.get('/litmus/get/settings',
        {'testcase': settings.testcase, 'metric': settings.metric},
        function(data) {
            settings.error = data.error;
            settings.warning = data.warning;
            settings.baseline = data.baseline;
        }, 'json');
}

function setReloadInterval(itv_str) {
    if (isNaN(itv_str)) {
        console.error("cannot parse reload interval : " + itv_str);
        return;
    }

    var itv = parseInt(itv_str);

    // cancel reload events
    if (reloadTimerId !== null) {
        clearInterval(reloadTimerId);
    }

    if (itv !== 0) {
        reloadTimerId = setInterval(function() {
            location.reload();
        }, itv);
    }
}

function getAllTags() {
    $.get('/litmus/get/tags',
        function(data) {
            $.each(data, function(i, v) {
                // input(type='radio', name='tag', onclick="showResults('');", id="2.0.1")label(for="2.0.1") 2.0.1
                var button = "<input type='radio' name='tag' onclick=\"showResults('" + v + "');\" id='"
                             + v.replace(/\./g, '-')  + "'>" + v + "";
                $('#tag').append(button);
            });
            $(function() {
                $("#tag").buttonset();
            });
        }, 'json');

}

function showResults(tag) {
    var url, oTable;
    if (tag) {
        url = '/litmus/get?tag=';
    } else {
        url = '/litmus/get?';
    }
    $.get(url + tag, { },
        function(data) {
            processData(data);
            renderTable(data);
        }, 'json');
}

function changeColors(row, vals, error, warning) {
    /**
     * Change cell colors based on the baseline values
     */
    return function(data) {
        if (data.length === 1) {
            return;
        }
        var baseval = data[1][4];
        $.each(vals.slice(4), function(j, v) {
            v = parseInt(v);
            $(row).find('td').eq(j+4).removeAttr("style");
            if (!isNaN(baseval) && !isNaN(v)) {
                var delta = (v - baseval) / baseval;
                if (Math.abs(error) < Math.abs(warning)) {
                    console.error("invalid error/warning ranges");
                    return;
                }
                if ((delta > error && error > 0) ||
                    (delta < error && error < 0)) {
                    $(row).find('td').eq(j+4).css("background-color","red");
                } else if ((delta > warning && delta < error) ||
                    (delta < warning && delta > error)) {
                    $(row).find('td').eq(j+4).css("background-color","yellow");
                }
            }
        });
    };
}
function applyErrorRanges() {
    /*
     * Apply error range check for each cell
     *
     * If data falls out of the range, turns cell to red
     * Accept negative ranges
     */
    oTable.$('tr').each(function() {
        var row = this;
        var vals = oTable.fnGetData(this);
        var settings = new Settings(vals[0], vals[2]);
        getSettings(settings);
        var uri = '/litmus/get';
        var criteria = {'testcase': settings.testcase,
                        'metric': settings.metric,
                        'build': settings.baseline,
                        'env': vals[1]};
        $.get(uri, criteria,
              changeColors(row, vals, settings.error, settings.warning),
              'json');
    });
}

function processData(data) {
    /*
     * Process json data coming from the server
     * Current implementation retrieves info only
     */
    colHdrs = [];
    rowHdrs = [];
    $.each(data[0], function(i, v) {
        colHdrs[i] = {'sTitle': v};
    });

    $.each(data.slice(1), function(i, v) {
        rowHdrs[i] = v[0];
    });

    return data;
}

function regTdActions(data, target, col, comment) {
    /**
     * Register actions to each table cell
     */
    var testcase= data[0];
    var env = data[1];
    var metric = data[2];
    var build = colHdrs[col]['sTitle'];

    if (col === 0) {
        var url = 'https://raw.github.com/couchbase/testrunner/master/conf/perf/' + testcase + '.conf';
        $(target).html(function(i, oldText) {
            return '' + oldText + '';
        });
    }
    if (col < 4) {
        return;     // support test results for now
    }

    var rcMenu = [
        {'

Color:

':
            function(menuItem, cmenu, e) {
                var t = $(e.target);
                if ($(t).is('.swatch')) {
                    var color = $(t).css('background-color');
                    $(target).css('background-color', color);
                    $(t).parent().find('.swatch').removeClass('swatch-selected');
                    $(t).addClass('swatch-selected');
                    $.ajax({
                        type: 'POST',
                        url: '../post/color/',
                        data: {'testcase': testcase,
                            'env': env,
                            'build': build,
                            'metric': metric,
                            'color': color},
                        error: function(response) {
                            console.error(response.responseText);
                        }
                    });
                }
            }
        },
        {'Comment': function(menuItem, cmenu, e) {
                $('#comment-form').dialog({
                    autoOpen: false,
                    modal: true,
                    width: 350,
                    buttons: {
                        Ok: function() {
                            var comment = $('#comment-form textarea').val();
                            $.ajax({
                                type: 'POST',
                                url: '../post/comment/',
                                data: {'testcase': testcase,
                                    'env': env,
                                    'build': build,
                                    'metric': metric,
                                    'comment': comment},
                                error: function(response) {
                                    console.error(response.responseText);
                                }
                            });
                            $(this).dialog("close");
                        },
                        Cancel: function() {
                            $(this).dialog("close");
                        }
                    },
                    open: function() {
                        if (comment !== undefined && comment) {
                            $('#comment-form textarea').html(comment);
                        }
                    }
                });
                $("#comment-form").dialog("open");
            }
        }
    ];

    $(target).contextMenu(rcMenu , {theme:'gloss'});
}

function renderTable(data) {
    /*
     * Render table with the given data
     */

    if (oTable) {
        oTable.fnDestroy();
        $("thead").remove();
    }

    oTable = $('#litmus table').dataTable({
        "sDom": 'Tlfrtip',
        'bProcessing': true,
        'bPaginate': true,
        'sPaginationType': 'full_numbers',
        'aaData': data.slice(1),
        'aoColumns': colHdrs,
        'aaSorting': [[0, 'desc']],
        'bStateSave': true,
        'fnDrawCallback': function() {
            $('#loading').remove();
        },
        "aoColumnDefs": [ {
            "aTargets": [ '_all' ],
            "mRender": function ( data, type, full ) {
                var arr = data.split("-&-");
                return arr[0];
            },
            "fnCreatedCell": function (nTd, sData, oData, iRow, iCol) {
                var arr = oData[iCol].split("-&-");
                if (typeof(arr[1]) !== undefined && arr[1]) {
                    $(nTd).css('background-color', arr[1]);
                }
                if (typeof(arr[2]) !== undefined && arr[2]) {
                    $(nTd).append("
" + arr[2] + "
");
                }
                regTdActions(oData, nTd, iCol, arr[2]);
            }
        }],
        'bDestroy': true,
        "bAutoWidth": false
    });

    new FixedHeader(oTable);
}
<commit_msg>legacy code cleanup<commit_after>"use strict";

var reloadTimerId = null;
var oTable;
var colHdrs;     // e.g: ['sTitle': 'Testcase', 'sTitle': 'Env', ... ]
var rowHdrs;       // e.g: ['mixed-2suv', 'lucky6', ...]
var WARNING = 0.1;
var ERROR = 0.3;

function setReloadInterval(itv_str) {
    if (isNaN(itv_str)) {
        console.error("cannot parse reload interval : " + itv_str);
        return;
    }

    var itv = parseInt(itv_str);

    // cancel reload events
    if (reloadTimerId !== null) {
        clearInterval(reloadTimerId);
    }

    if (itv !== 0) {
        reloadTimerId = setInterval(function() {
            location.reload();
        }, itv);
    }
}

function getAllTags() {
    $.get('/litmus/get/tags',
        function(data) {
            $.each(data, function(i, v) {
                // input(type='radio', name='tag', onclick="showResults('');", id="2.0.1")label(for="2.0.1") 2.0.1
                var button = "<input type='radio' name='tag' onclick=\"showResults('" + v + "');\" id='"
                             + v.replace(/\./g, '-')  + "'>" + v + "";
                $('#tag').append(button);
            });
            $(function() {
                $("#tag").buttonset();
            });
        }, 'json');

}

function showResults(tag) {
    var url, oTable;
    if (tag) {
        url = '/litmus/get?tag=';
    } else {
        url = '/litmus/get?';
    }
    $.get(url + tag, { },
        function(data) {
            processData(data);
            renderTable(data);
        }, 'json');
}

function processData(data) {
    /*
     * Process json data coming from the server
     * Current implementation retrieves info only
     */
    colHdrs = [];
    rowHdrs = [];
    $.each(data[0], function(i, v) {
        colHdrs[i] = {'sTitle': v};
    });

    $.each(data.slice(1), function(i, v) {
        rowHdrs[i] = v[0];
    });

    return data;
}

function regTdActions(data, target, col, comment) {
    /**
     * Register actions to each table cell
     */
    var testcase= data[0];
    var env = data[1];
    var metric = data[2];
    var build = colHdrs[col]['sTitle'];

    if (col === 0) {
        var url = 'https://raw.github.com/couchbase/testrunner/master/conf/perf/' + testcase + '.conf';
        $(target).html(function(i, oldText) {
            return '' + oldText + '';
        });
    }
    if (col < 4) {
        return;     // support test results for now
    }

    var rcMenu = [
        {'

Color:

':
            function(menuItem, cmenu, e) {
                var t = $(e.target);
                if ($(t).is('.swatch')) {
                    var color = $(t).css('background-color');
                    $(target).css('background-color', color);
                    $(t).parent().find('.swatch').removeClass('swatch-selected');
                    $(t).addClass('swatch-selected');
                    $.ajax({
                        type: 'POST',
                        url: '../post/color/',
                        data: {'testcase': testcase,
                            'env': env,
                            'build': build,
                            'metric': metric,
                            'color': color},
                        error: function(response) {
                            console.error(response.responseText);
                        }
                    });
                }
            }
        },
        {'Comment': function(menuItem, cmenu, e) {
                $('#comment-form').dialog({
                    autoOpen: false,
                    modal: true,
                    width: 350,
                    buttons: {
                        Ok: function() {
                            var comment = $('#comment-form textarea').val();
                            $.ajax({
                                type: 'POST',
                                url: '../post/comment/',
                                data: {'testcase': testcase,
                                    'env': env,
                                    'build': build,
                                    'metric': metric,
                                    'comment': comment},
                                error: function(response) {
                                    console.error(response.responseText);
                                }
                            });
                            $(this).dialog("close");
                        },
                        Cancel: function() {
                            $(this).dialog("close");
                        }
                    },
                    open: function() {
                        if (comment !== undefined && comment) {
                            $('#comment-form textarea').html(comment);
                        }
                    }
                });
                $("#comment-form").dialog("open");
            }
        }
    ];

    $(target).contextMenu(rcMenu , {theme:'gloss'});
}

function renderTable(data) {
    /*
     * Render table with the given data
     */

    if (oTable) {
        oTable.fnDestroy();
        $("thead").remove();
    }

    oTable = $('#litmus table').dataTable({
        "sDom": 'Tlfrtip',
        'bProcessing': true,
        'bPaginate': true,
        'sPaginationType': 'full_numbers',
        'aaData': data.slice(1),
        'aoColumns': colHdrs,
        'aaSorting': [[0, 'desc']],
        'bStateSave': true,
        'fnDrawCallback': function() {
            $('#loading').remove();
        },
        "aoColumnDefs": [ {
            "aTargets": [ '_all' ],
            "mRender": function ( data, type, full ) {
                var arr = data.split("-&-");
                return arr[0];
            },
            "fnCreatedCell": function (nTd, sData, oData, iRow, iCol) {
                var arr = oData[iCol].split("-&-");
                if (typeof(arr[1]) !== undefined && arr[1]) {
                    $(nTd).css('background-color', arr[1]);
                }
                if (typeof(arr[2]) !== undefined && arr[2]) {
                    $(nTd).append("
" + arr[2] + "
");
                }
                regTdActions(oData, nTd, iCol, arr[2]);
            }
        }],
        'bDestroy': true,
        "bAutoWidth": false
    });

    new FixedHeader(oTable);
}
<|endoftext|>


<commit_before>'use strict';

app
  .controller('LoadCtrl', ['$scope', '$cookies', '$location', '$alert', 'networksService', 'commonDataService', function ($scope, $cookies, $location, $alert, networksService, commonDataService) {
	networksService.getNetworksList().success(function(data) {
		$scope.networks = data;
	})
	.error(function(err) {
		$alert({title: 'Unable to load list of networks', content: err, placement: 'top', type: 'danger', show: true});
	});

	$scope.selectNetwork = function(id)
	{
		networksService.getParticularNetwork(id).success(function(data)
		{
			commonDataService = data;
		})
		.error(function(err)
		{
			$alert({title: 'Unable to load network', content: err, placement: 'top', type: 'danger', show: true});
		});

		$cookies.put('activeNetworkID', id);
		$location.path('/core/workbench');
	}
  }]);<commit_msg>Removed redundant network load<commit_after>'use strict';

app
  .controller('LoadCtrl', ['$scope', '$cookies', '$location', '$alert', 'networksService', 'commonDataService', function ($scope, $cookies, $location, $alert, networksService, commonDataService) {
	networksService.getNetworksList().success(function(data) {
		$scope.networks = data;
	})
	.error(function(err) {
		$alert({title: 'Unable to load list of networks', content: err, placement: 'top', type: 'danger', show: true});
	});

	$scope.selectNetwork = function(id)
	{
		networksService.getParticularNetwork(id).success(function(data)
		{

		})
		.error(function(err)
		{
			$alert({title: 'Unable to load network', content: err, placement: 'top', type: 'danger', show: true});
		});

		$cookies.put('activeNetworkID', id);
		$location.path('/core/workbench');
	}
  }]);<|endoftext|>


<commit_before>// ==UserScript==
// @name        Mijikai.jp prettify
// @namespace   curipha
// @description Tweak mijikai.jp
// @include     http://mijikai.jp/
// @version     0.0.1
// @grant       none
// ==/UserScript==

(function() {
  var tds = document.querySelectorAll('td[width="8%"]');
  var pattern = /^.*[fjkloqy-].*\.jp$/;

  for (var td of tds) {
    td.innerHTML = td.textContent.toLowerCase();

    if (pattern.test(td.textContent)) {
      td.style.color = "#ddd";
      //td.innerHTML = '';
    }
  }
})();
<commit_msg>Update RegExp pattern<commit_after>// ==UserScript==
// @name        Mijikai.jp prettify
// @namespace   curipha
// @description Tweak mijikai.jp
// @include     http://mijikai.jp/
// @version     0.0.2
// @grant       none
// ==/UserScript==

(function() {
  var tds = document.querySelectorAll('td[width="8%"]');
  var pattern = /^(.*[joqy-].*|[0-9]?[a-z]+[0-9]+|[a-z]?[0-9]+[a-z]+)\.jp$/;

  for (var td of tds) {
    td.innerHTML = td.textContent.toLowerCase();

    if (pattern.test(td.textContent)) {
      td.style.color = "#ddd";
      //td.innerHTML = '';
    }
  }
})();
<|endoftext|>


<commit_before>import { expect } from 'chai';
import sinon from 'sinon';
import Promise from 'bluebird';
import Etcd from 'node-etcd';

import Microlock, {
  events,

  EtcdClientRequiredError,
  KeyRequiredError,
  NodeIdRequiredError,
  InvalidTtlError,
  AlreadyLockedError,
  LockNotOwnedError
} from '../../src/microlock';

describe('microlock', () => {
  let etcd = null
    , key = null
    , node1 = null
    , node2 = null
    , lock1 = null
    , lock2 = null
    , ttl = null;

  beforeEach(() => {
    etcd = new Etcd();

    key = 'key';

    node1 = 'node_1';
    node2 = 'node_2';

    ttl = 5;

    lock1 = new Microlock(etcd, key, node1, ttl);
    lock2 = new Microlock(etcd, key, node2, ttl);
  });

  afterEach(() => Promise.all([
    lock1.unlock(),
    lock2.unlock()
  ]).catch((e) => e));

  describe('lock', () => {
    context('is locked', () => {
      beforeEach(() => lock2.lock());
      it('rejects with AlreadyLockedError', (done) => {
        lock1
        .lock()
        .then(() => done(new Error('should have rejected')), (e) => {
          expect(e instanceof AlreadyLockedError).to.be.true;
          done();
        })
        .catch(done);
      });
    });
    context('is not locked', () => {
      it('resolves', (done) => {
        lock1
        .lock()
        .then(() => done(), () => done(new Error('should have resolved')));
      });
    });
  });
  describe('unlock', () => {
    context('is locked by current node', () => {
      beforeEach(() => lock1.lock());
      it('resolves', (done) => {
        lock1
        .unlock()
        .then(() => done(), () => done(new Error('should have resolved')));
      });
    });
    context('is not locked by current node', () => {
      beforeEach(() => lock2.lock());
      it('rejects with LockNotOwnedError', (done) => {
        lock1
        .unlock()
        .then(() => done(new Error('should have rejected')), (e) => {
          expect(e instanceof LockNotOwnedError).to.be.true;
          done();
        })
        .catch(done);
      });
    });
    context('is not locked', () => {
      it('rejects with LockNotOwnedError', (done) => {
        lock1
        .unlock()
        .then(() => done(new Error('should have rejected')), (e) => {
          expect(e instanceof LockNotOwnedError).to.be.true;
          done();
        })
        .catch(done);
      });
    });
  });
  describe('renew', () => {
    context('is locked by current node', () => {
      beforeEach(() => lock1.lock());
      it('resolves', (done) => {
        lock1
        .renew()
        .then(() => done(), () => done(new Error('should have resolved')));
      });
    });
    context('is not locked by current node', () => {
      beforeEach(() => lock2.lock());
      it('rejects with LockNotOwnedError', (done) => {
        lock1
        .renew()
        .then(() => done(new Error('should have rejected')), (e) => {
          expect(e instanceof LockNotOwnedError).to.be.true;
          done();
        })
        .catch(done);
      });
    });
    context('is not locked', () => {
      it('rejects with LockNotOwnedError', (done) => {
        lock1
        .renew()
        .then(() => done(new Error('should have rejected')), (e) => {
          expect(e instanceof LockNotOwnedError).to.be.true;
          done();
        })
        .catch(done);
      });
    });
  });
});
<commit_msg>Revert to using built code for integration tests<commit_after>import { expect } from 'chai';
import sinon from 'sinon';
import Promise from 'bluebird';
import Etcd from 'node-etcd';

import Microlock, {
  events,

  EtcdClientRequiredError,
  KeyRequiredError,
  NodeIdRequiredError,
  InvalidTtlError,
  AlreadyLockedError,
  LockNotOwnedError
} from '../../lib/microlock';

describe('microlock', () => {
  let etcd = null
    , key = null
    , node1 = null
    , node2 = null
    , lock1 = null
    , lock2 = null
    , ttl = null;

  beforeEach(() => {
    etcd = new Etcd();

    key = 'key';

    node1 = 'node_1';
    node2 = 'node_2';

    ttl = 5;

    lock1 = new Microlock(etcd, key, node1, ttl);
    lock2 = new Microlock(etcd, key, node2, ttl);
  });

  afterEach(() => Promise.all([
    lock1.unlock(),
    lock2.unlock()
  ]).catch((e) => e));

  describe('lock', () => {
    context('is locked', () => {
      beforeEach(() => lock2.lock());
      it('rejects with AlreadyLockedError', (done) => {
        lock1
        .lock()
        .then(() => done(new Error('should have rejected')), (e) => {
          expect(e instanceof AlreadyLockedError).to.be.true;
          done();
        })
        .catch(done);
      });
    });
    context('is not locked', () => {
      it('resolves', (done) => {
        lock1
        .lock()
        .then(() => done(), () => done(new Error('should have resolved')));
      });
    });
  });
  describe('unlock', () => {
    context('is locked by current node', () => {
      beforeEach(() => lock1.lock());
      it('resolves', (done) => {
        lock1
        .unlock()
        .then(() => done(), () => done(new Error('should have resolved')));
      });
    });
    context('is not locked by current node', () => {
      beforeEach(() => lock2.lock());
      it('rejects with LockNotOwnedError', (done) => {
        lock1
        .unlock()
        .then(() => done(new Error('should have rejected')), (e) => {
          expect(e instanceof LockNotOwnedError).to.be.true;
          done();
        })
        .catch(done);
      });
    });
    context('is not locked', () => {
      it('rejects with LockNotOwnedError', (done) => {
        lock1
        .unlock()
        .then(() => done(new Error('should have rejected')), (e) => {
          expect(e instanceof LockNotOwnedError).to.be.true;
          done();
        })
        .catch(done);
      });
    });
  });
  describe('renew', () => {
    context('is locked by current node', () => {
      beforeEach(() => lock1.lock());
      it('resolves', (done) => {
        lock1
        .renew()
        .then(() => done(), () => done(new Error('should have resolved')));
      });
    });
    context('is not locked by current node', () => {
      beforeEach(() => lock2.lock());
      it('rejects with LockNotOwnedError', (done) => {
        lock1
        .renew()
        .then(() => done(new Error('should have rejected')), (e) => {
          expect(e instanceof LockNotOwnedError).to.be.true;
          done();
        })
        .catch(done);
      });
    });
    context('is not locked', () => {
      it('rejects with LockNotOwnedError', (done) => {
        lock1
        .renew()
        .then(() => done(new Error('should have rejected')), (e) => {
          expect(e instanceof LockNotOwnedError).to.be.true;
          done();
        })
        .catch(done);
      });
    });
  });
});
<|endoftext|>


<commit_before>var fs = require('fs');
var sep = require('path').sep;
var exec = require('child_process').execSync;
var machine_parameter = JSON.parse(fs.readFileSync([process.cwd(), 'parameters.json'].join(sep)));
var user_name = machine_parameter.parameters.virtualMachines_nixml_adminUsername.value;
var machine_name = machine_parameter.parameters.virtualMachines_nixml_name.value;
var address = JSON.parse(exec(`azure network public-ip show CAAPI ${machine_name}-ip --json`).toString());
var ip = address.ipAddress;
var dns_name = address.dnsSettings.fqdn;
console.log('');
console.log('');
console.log(`Host ${machine_name}`);
console.log(`     Hostname ${ip}`);
console.log(`     Hostname ${dns_name}`);
console.log(`     User ${user_name}`);<commit_msg>machine_ip -> machine_name-ip<commit_after>var fs = require('fs');
var sep = require('path').sep;
var exec = require('child_process').execSync;
var machine_parameter = JSON.parse(fs.readFileSync([process.cwd(), 'parameters.json'].join(sep)));

var user_name = machine_parameter.parameters.virtualMachines_nixml_adminUsername.value;
var machine_name = machine_parameter.parameters.virtualMachines_nixml_name.value;
var machine_ip = machine_parameter.parameters.publicIPAddresses_nixml_ip_name;
var address = JSON.parse(exec(`azure network public-ip show CAAPI ${machine_ip} --json`).toString());
var ip = address.ipAddress;
var dns_name = address.dnsSettings.fqdn;
console.log('');
console.log('');
console.log(`Host ${machine_name}`);
console.log(`     Hostname ${ip}`);
console.log(`     Hostname ${dns_name}`);
console.log(`     User ${user_name}`);<|endoftext|>


<commit_before>describe('NDP.Integrator(opt_dimensions)', function() {

  beforeEach(function() {
    jasmine.addMatchers(CustomMatchers);
    NDP.DIMENSIONS = 2;
    this.integratorA = new NDP.Integrator();
    this.integratorB = new NDP.Integrator(1);
  });

  it('should be a Function Object', function() {
    expect(NDP.Integrator).toEqual(jasmine.any(Function));
  });
  it('should default [dimensions] to NDP.DIMENSIONS', function() {
    expect(this.integratorA.dimensions).toBe(NDP.DIMENSIONS);
  });
  it('should set [dimensions] to the first argument if passed', function() {
    this.integratorA = new NDP.Integrator(1);
    expect(this.integratorA.dimensions).toBe(1);

    this.integratorB = new NDP.Integrator(2);
    expect(this.integratorB.dimensions).toBe(2);
  });
  it('should only accept Numbers and set [dimensions] to an Integer', function() {
    this.integratorA = new NDP.Integrator('1');
    expect(this.integratorA.dimensions).toBe(NDP.DIMENSIONS);

    this.integratorA = new NDP.Integrator('cats');
    expect(this.integratorA.dimensions).toBe(NDP.DIMENSIONS);

    this.integratorA = new NDP.Integrator(2.8);
    expect(this.integratorA.dimensions).toBe(2);

    this.integratorA = new NDP.Integrator(3.2);
    expect(this.integratorA.dimensions).toBe(3);
  });
  it('should set [__dimensions] to [dimensions]', function() {
    expect(this.integratorA.__dimensions).toBe(this.integratorA.dimensions);
  });

  describe('dimensions', function() {
    it('should be an Integer', function() {
      expect(this.integratorA.dimensions).toBeAnInteger();
    });
    it('should be readonly', function() {
      var dimensions = this.integratorA.dimensions;
      this.integratorA.dimensions = 100;
      expect(this.integratorA.dimensions).toBe(dimensions);
    });
    it('should have a private __dimensions counterpart', function() {
      expect(this.integratorA.__dimensions).toBe(this.integratorA.dimensions);
      expect(this.integratorA.__dimensions).toBeAnInteger();
    });
  });

  describe('__vector', function() {
    it('should be an Object', function() {
      expect(this.integratorA.__vector).toEqual(jasmine.any(Object));
    });
    it('should reference NDP.Vector[dimensions]', function() {
      expect(this.integratorA.__vector).toEqual(NDP['Vector' + this.integratorA.dimensions]);
    });
    it('should throw an error for cases where a Vector Object is not available', function() {
      expect(function() {
        new NDP.Integrator(0);
      }).toThrow('Integrator: No Vector Object available for [0] dimensions');
    });
  });
});
<commit_msg>:gb: Implemented worker vector test suite<commit_after>describe('NDP.Integrator(opt_dimensions)', function() {

  beforeEach(function() {
    jasmine.addMatchers(CustomMatchers);
    NDP.DIMENSIONS = 2;
    this.integratorA = new NDP.Integrator();
    this.integratorB = new NDP.Integrator(1);
  });

  it('should be a Function Object', function() {
    expect(NDP.Integrator).toEqual(jasmine.any(Function));
  });
  it('should default [dimensions] to NDP.DIMENSIONS', function() {
    expect(this.integratorA.dimensions).toBe(NDP.DIMENSIONS);
  });
  it('should set [dimensions] to the first argument if passed', function() {
    this.integratorA = new NDP.Integrator(1);
    expect(this.integratorA.dimensions).toBe(1);

    this.integratorB = new NDP.Integrator(2);
    expect(this.integratorB.dimensions).toBe(2);
  });
  it('should only accept Numbers and set [dimensions] to an Integer', function() {
    this.integratorA = new NDP.Integrator('1');
    expect(this.integratorA.dimensions).toBe(NDP.DIMENSIONS);

    this.integratorA = new NDP.Integrator('cats');
    expect(this.integratorA.dimensions).toBe(NDP.DIMENSIONS);

    this.integratorA = new NDP.Integrator(2.8);
    expect(this.integratorA.dimensions).toBe(2);

    this.integratorA = new NDP.Integrator(3.2);
    expect(this.integratorA.dimensions).toBe(3);
  });
  it('should set [__dimensions] to [dimensions]', function() {
    expect(this.integratorA.__dimensions).toBe(this.integratorA.dimensions);
  });

  describe('dimensions', function() {
    it('should be an Integer', function() {
      expect(this.integratorA.dimensions).toBeAnInteger();
    });
    it('should be readonly', function() {
      var dimensions = this.integratorA.dimensions;
      this.integratorA.dimensions = 100;
      expect(this.integratorA.dimensions).toBe(dimensions);
    });
    it('should have a private __dimensions counterpart', function() {
      expect(this.integratorA.__dimensions).toBe(this.integratorA.dimensions);
      expect(this.integratorA.__dimensions).toBeAnInteger();
    });
  });

  describe('__vector', function() {
    it('should be an Object', function() {
      expect(this.integratorA.__vector).toEqual(jasmine.any(Object));
    });
    it('should reference NDP.Vector[dimensions]', function() {
      expect(this.integratorA.__vector).toEqual(NDP['Vector' + this.integratorA.dimensions]);
    });
    it('should throw an error for cases where a Vector Object is not available', function() {
      expect(function() {
        new NDP.Integrator(0);
      }).toThrow('Integrator: No Vector Object available for [0] dimensions');
    });
  });

  describe('__acc, __vel, __pos', function() {
    beforeEach(function() {
      this.vectorKeys = ['__acc', '__vel', '__pos'];
    });
    it('should be __private', function() {
      for (var i = 0; i < this.vectorKeys.length; i++) {
        var privateKey = this.vectorKeys[i];
        var publicKey = privateKey.replace(/_/g, '');
        expect(this.integratorA[privateKey]).toBeDefined();
        expect(this.integratorA[publicKey]).toBeUndefined();
      }
    });
    it('should be an NDP.Array instance', function() {
      for (var i = 0; i < this.vectorKeys.length; i++) {
        expect(this.integratorA[this.vectorKeys[i]]).toEqual(jasmine.any(NDP.Array));
      }
    });
    it('should be of length [dimensions]', function() {
      for (var i = 0; i < this.vectorKeys.length; i++) {
        expect(this.integratorA[this.vectorKeys[i]].length).toBe(this.integratorA.dimensions);
      }
    });
  });
});
<|endoftext|>


<commit_before>import HTML5Video from 'playbacks/html5_video'
import Events from 'base/events.js'

import $ from 'clappr-zepto'

describe('HTML5Video playback', function() {
  beforeEach(function() {
    this.options = { src: 'http://example.com/dash.ogg' }
  })

  it('checks if it can play a resource', function() {
    expect(HTML5Video.canPlay('')).to.be.false
    expect(HTML5Video.canPlay('resource_without_dots')).to.be.false
    expect(HTML5Video.canPlay('http://domain.com/video.ogv')).to.be.true
    expect(HTML5Video.canPlay('http://domain.com/video.ogv?query_string=here')).to.be.true
    expect(HTML5Video.canPlay('/relative/video.ogv')).to.be.true
  })

  it('checks if it can play a resource with mime-type', function() {
    expect(HTML5Video.canPlay('resource_without_dots', 'video/ogg; codecs="theora, vorbis"')).to.be.true
  })

  it('does set a valid src to video element', function() {
    const playback = new HTML5Video(this.options)
    expect(playback._src).to.be.equals('http://example.com/dash.ogg')
  })

  it('starts not ready', function() {
    const playback = new HTML5Video(this.options)

    expect(playback.isReady).to.be.undefined
  })

  it('can be ready', function() {
    const playback = new HTML5Video(this.options)
    playback._ready()

    expect(playback.isReady).to.be.true
  })

  it('triggers PLAYBACK_PLAY_INTENT on play request', function() {
    const callback = sinon.spy()
    const playback = new HTML5Video(this.options)

    playback.on(Events.PLAYBACK_PLAY_INTENT, callback)
    playback.play()

    callback.should.have.been.calledOnce
  })

  it('trigger PLAYBACK_SEEK on media seeking event', function(done) {
    this.timeout(5000)
    const callback = sinon.spy()
    const playback = new HTML5Video({ src: '/test/fixtures/SampleVideo_360x240_1mb.mp4' })

    playback.on(Events.PLAYBACK_SEEK, callback)
    playback.on(Events.PLAYBACK_SEEK, () => {
      callback.should.have.been.calledOnce
      done()
    }, this)

    playback.el.dispatchEvent(new Event('seeking'))
  })

  it('triggers PLAYBACK_SEEKED on media seeked event', function(done) {
    this.timeout(5000)
    const callback = sinon.spy()
    const playback = new HTML5Video({ src: '/test/fixtures/SampleVideo_360x240_1mb.mp4' })

    playback.on(Events.PLAYBACK_SEEKED, callback)
    playback.on(Events.PLAYBACK_SEEKED, () => {
      callback.should.have.been.calledOnce
      done()
    }, this)

    playback.el.dispatchEvent(new Event('seeked'))
  })

  it('isPlaying() is true after constructor when autoPlay is true', function(done) {
    const playback = new HTML5Video({ src: 'http://example.com/dash.ogg', autoPlay: true })
    process.nextTick(function() {
      expect(playback.isPlaying()).to.be.true
      done()
    })
  })

  it('setup crossorigin attribute', function() {
    const options = $.extend({ playback: { crossOrigin: 'use-credentials' } }, this.options)
    const playback = new HTML5Video(options)

    expect(playback.el.crossOrigin).to.be.equal('use-credentials')
    expect(playback.el.getAttribute('crossorigin')).equal('use-credentials')
  })

  it('enables inline playback for webviews when playInline flag is set', function() {
    const options = $.extend({ playback: { playInline: true } }, this.options)
    const playback = new HTML5Video(options)

    expect(playback.el['x-webkit-playsinline']).to.be.true
    expect(playback.el.getAttribute('playsinline')).equal('playsinline')
  })

  it('allows displaying default video tag controls', function() {
    const options = $.extend({ playback: { controls: 'controls' } }, this.options)
    const playback = new HTML5Video(options)
    expect(playback.el.controls).to.be.true
  })

  it('mute or unmute video element when volume is changed', function() {
    const playback = new HTML5Video(this.options)

    expect(playback.el.getAttribute('muted')).to.be.null
    expect(playback.el.muted).to.be.false

    playback.volume(0)
    expect(playback.el.getAttribute('muted')).equal('true')
    expect(playback.el.muted).to.be.true

    playback.volume(0.5)
    expect(playback.el.getAttribute('muted')).to.be.null
    expect(playback.el.muted).to.be.false
  })

  it('setup external tracks', function() {
    let newTrackUrl = () => { URL.createObjectURL(new Blob([], { type: 'text/vtt' })) }
    const options = $.extend({ playback: {
      externalTracks: [
        { lang: 'en', label: 'English', src: newTrackUrl(), kind: 'subtitles' },
        { lang: 'fr', label: 'French', src: newTrackUrl() }
      ]
    } }, this.options)
    const playback = new HTML5Video(options)
    playback.render()
    const $tracks = playback.$el.find('track[data-html5-video-track]')

    expect($tracks[0].getAttribute('data-html5-video-track')).to.be.equal('0')
    expect($tracks[0].getAttribute('kind')).to.be.equal('subtitles')
    expect($tracks[0].getAttribute('label')).to.be.equal('English')
    expect($tracks[0].getAttribute('srclang')).to.be.equal('en')

    expect($tracks[1].getAttribute('data-html5-video-track')).to.be.equal('1')
    expect($tracks[1].getAttribute('kind')).to.be.equal('subtitles')
    expect($tracks[1].getAttribute('label')).to.be.equal('French')
    expect($tracks[1].getAttribute('srclang')).to.be.equal('fr')
  })

  it('can switch text tracks', function() {
    let newTrackUrl = () => { URL.createObjectURL(new Blob([], { type: 'text/vtt' })) }
    const options = $.extend({ playback: {
      externalTracks: [
        { lang: 'en', label: 'English', src: newTrackUrl(), kind: 'subtitles' },
        { lang: 'fr', label: 'French', src: newTrackUrl() }
      ]
    } }, this.options)
    const playback = new HTML5Video(options)
    playback.render()

    expect(playback.hasClosedCaptionsTracks).to.be.true
    expect(playback.closedCaptionsTracks.length).equal(2)
    expect(playback.closedCaptionsTrackId).equal(-1)
    expect(playback.closedCaptionsTracks[0].track.mode).to.not.equal('showing')
    expect(playback.closedCaptionsTracks[1].track.mode).to.not.equal('showing')

    playback.closedCaptionsTrackId = 0
    expect(playback.closedCaptionsTrackId).equal(0)
    expect(playback.closedCaptionsTracks[0].track.mode).equal('showing')
    expect(playback.closedCaptionsTracks[1].track.mode).to.not.equal('showing')

    playback.closedCaptionsTrackId = 1
    expect(playback.closedCaptionsTrackId).equal(1)
    expect(playback.closedCaptionsTracks[0].track.mode).to.not.equal('showing')
    expect(playback.closedCaptionsTracks[1].track.mode).equal('showing')

    playback.closedCaptionsTrackId = -1
    expect(playback.closedCaptionsTrackId).equal(-1)
    expect(playback.closedCaptionsTracks[0].track.mode).to.not.equal('showing')
    expect(playback.closedCaptionsTracks[1].track.mode).to.not.equal('showing')
  })

  describe('progress', function() {
    let start, end, currentTime
    const duration = 300
    const fakeEl = {
      get currentTime() { return currentTime },
      get duration() { return duration },
      get buffered() { return { start: (i) => start[i], end: (i) => end[i], get length() { return start.length } } }
    }

    beforeEach(function() {
      currentTime = 0
      start = [0]
      end = [30]

      this.callback = sinon.spy()
      this.playback = new HTML5Video(this.options)
      this.playback.setElement(fakeEl)
      this.playback.on(Events.PLAYBACK_PROGRESS, this.callback)
    })

    it('should trigger PLAYBACK_PROGRESS with current buffer position', function() {
      this.playback._onProgress() // cannot trigger event on fake element (improve later?)
      let currentProgess = this.callback.getCall(0).args[0]

      expect(currentProgess.start).to.be.equal(start[0])
      expect(currentProgess.current).to.be.equal(end[0])
      expect(currentProgess.total).to.be.equal(duration)
    })

    it('should find current buffer position', function() {
      start = [0, 50, 180]
      end = [30, 90, 280]
      currentTime = 75 // this should be located at index 1

      this.playback._onProgress() // cannot trigger event on fake element (improve later?)
      let progress = this.callback.getCall(0).args[0]

      expect(progress.start).to.be.equal(start[1])
      expect(progress.current).to.be.equal(end[1])
    })

    it('does not trigger buffer event when the playback is initialized', function() {
      /*
        Only trigger buffer events when buffer state change.
        The default value for _bufferState is false.
      */

      let builtInEvents = ['loadedmetadata', 'progress', 'timeupdate'].map(
        function(label) {
          return new Event(label)
        }
      )

      let callback = sinon.spy()
      let playback = new HTML5Video(this.options)

      playback.on(Events.PLAYBACK_BUFFERING, callback)
      playback.on(Events.PLAYBACK_BUFFERFULL, callback)

      builtInEvents.map(function(event) { playback.el.dispatchEvent(event) })
      callback.should.not.have.been.called
    })

    it('should return an array of buffer segments as {start, end} objects', function() {
      start = [0, 50, 180]
      end = [30, 90, 280]

      this.playback._onProgress() // cannot trigger event on fake element (improve later?)
      let buffered = this.callback.getCall(0).args[1]

      expect(buffered.length).to.be.equal(start.length)
      expect(buffered[0]).to.deep.equal({ start: start[0], end: end[0] })
      expect(buffered[1]).to.deep.equal({ start: start[1], end: end[1] })
      expect(buffered[2]).to.deep.equal({ start: start[2], end: end[2] })
    })
  })

  it('should be able to identify it can play resources independently of the file extension case', function() {
    expect(HTML5Video.canPlay('/relative/video.ogg')).to.be.true
    expect(HTML5Video.canPlay('/relative/VIDEO.OGG')).to.be.true
  })

  describe('options', function() {
    it('should use the playback object within player options', function() {
      const options = {
        src: 'http://example.com/video.m3u8',
        nonPlaybackOption: false,
        playback: {
          somePlaybackOption: true
        }
      }
      const html5Video = new HTML5Video(options)
      expect(html5Video.options.playback.somePlaybackOption).to.be.true
      expect(html5Video.options.playback).not.to.include.keys('nonPlaybackOption')
    })

    it('should use hlsjsConfig from player options as fallback', function() {
      const options = {
        src: 'http://example.com/video.m3u8',
        nonPlaybackOption: false,
        somePlaybackOption: true
      }
      const html5Video = new HTML5Video(options)
      expect(html5Video.options.playback.somePlaybackOption).to.be.true
      expect(html5Video.options.playback.nonPlaybackOption).to.be.false
    })
  })

  describe('video element', function() {
    it('should set src url from options', function() {
      const options = {
        src: 'http://example.com/some_source?query_string=here',
        mimeType: 'application/x-mpegURL'
      }
      const html5Video = new HTML5Video(options)
      html5Video.render()
      expect(html5Video.el.getAttribute('src')).to.be.equal(options.src)
    })

    it('should have src attribute removed after stop, and then added after play', function() {
      const options = {
        src: 'http://example.com/video.mp4'
      }
      const html5Video = new HTML5Video(options)
      html5Video.render()
      html5Video.play()
      html5Video.stop()
      expect(html5Video.el.hasAttribute('src')).to.be.false
      html5Video.play()
      expect(html5Video.el.getAttribute('src')).to.be.equal(options.src)
    })
  })

  describe('audio resources', function() {
    it('should be able to play audio resources', function() {
      expect(HTML5Video.canPlay('http://domain.com/Audio.oga')).to.be.true
      expect(HTML5Video.canPlay('http://domain.com/Audio.oga?query_string=here')).to.be.true
      expect(HTML5Video.canPlay('/relative/Audio.oga')).to.be.true
      expect(HTML5Video.canPlay('/relative/Audio.wav')).to.be.true
    })

    it('should play audio resources on an audio tag', function() {
      const options = { src: 'http://example.com/dash.oga' }
      const playback = new HTML5Video(options)
      expect(playback.tagName).to.be.equal('audio')
    })

    it('should use an audio tag when the audioOnly option is set to true', function() {
      const options = {
        src: 'http://example.com/dash.m3u8',
        playback: { audioOnly: true }
      }
      const playback = new HTML5Video(options)
      expect(playback.tagName).to.be.equal('audio')
    })

    it('should not play video resources on an audio tag if audioOnly flag is not set and a video mime-type is set', function() {
      const options = { src: 'http://example.com/video.mp4', mimeType: 'video/mp4' }
      const playback = new HTML5Video(options)
      expect(playback.isAudioOnly).to.be.false
      expect(playback.tagName).to.be.equal('video')
    })

    it('should play on audio tag if audioOnly flag is not set and the mime-type specified is audio only', function() {
      let options = { src: 'http://example.com/audio?some_parameter=value', mimeType: 'audio/ogg' },
        playback = new HTML5Video(options)
      expect(playback.isAudioOnly).to.be.true
      expect(playback.tagName).to.be.equal('audio')

      options = { src: 'http://example.com/audio?some_parameter=value', mimeType: 'audio/wav' }
      playback = new HTML5Video(options)
      expect(playback.isAudioOnly).to.be.true
      expect(playback.tagName).to.be.equal('audio')
    })

    it('should not play video resources on an audio tag if audioOnly flag is not set', function() {
      const options = { src: 'http://example.com/dash.m3u8' }
      const playback = new HTML5Video(options)
      expect(playback.isAudioOnly).to.be.false
      expect(playback.tagName).to.be.equal('video')
    })
  })
})
<commit_msg>test(html5_video): fix broken playback test on chrome<commit_after>import HTML5Video from 'playbacks/html5_video'
import Events from 'base/events.js'

import $ from 'clappr-zepto'

describe('HTML5Video playback', function() {
  beforeEach(function() {
    this.options = { src: 'http://example.com/dash.ogg' }
  })

  it('checks if it can play a resource', function() {
    expect(HTML5Video.canPlay('')).to.be.false
    expect(HTML5Video.canPlay('resource_without_dots')).to.be.false
    expect(HTML5Video.canPlay('http://domain.com/video.ogv')).to.be.true
    expect(HTML5Video.canPlay('http://domain.com/video.ogv?query_string=here')).to.be.true
    expect(HTML5Video.canPlay('/relative/video.ogv')).to.be.true
  })

  it('checks if it can play a resource with mime-type', function() {
    expect(HTML5Video.canPlay('resource_without_dots', 'video/ogg; codecs="theora, vorbis"')).to.be.true
  })

  it('does set a valid src to video element', function() {
    const playback = new HTML5Video(this.options)
    expect(playback._src).to.be.equals('http://example.com/dash.ogg')
  })

  it('starts not ready', function() {
    const playback = new HTML5Video(this.options)

    expect(playback.isReady).to.be.undefined
  })

  it('can be ready', function() {
    const playback = new HTML5Video(this.options)
    playback._ready()

    expect(playback.isReady).to.be.true
  })

  it('triggers PLAYBACK_PLAY_INTENT on play request', function() {
    const callback = sinon.spy()
    const playback = new HTML5Video(this.options)

    playback.on(Events.PLAYBACK_PLAY_INTENT, callback)
    playback.play()

    callback.should.have.been.calledOnce
  })

  it('trigger PLAYBACK_SEEK on media seeking event', function(done) {
    this.timeout(5000)
    const callback = sinon.spy()
    const playback = new HTML5Video({ src: '/test/fixtures/SampleVideo_360x240_1mb.mp4' })

    playback.on(Events.PLAYBACK_SEEK, callback)
    playback.on(Events.PLAYBACK_SEEK, () => {
      callback.should.have.been.calledOnce
      done()
    }, this)

    playback.el.dispatchEvent(new Event('seeking'))
  })

  it('triggers PLAYBACK_SEEKED on media seeked event', function(done) {
    this.timeout(5000)
    const callback = sinon.spy()
    const playback = new HTML5Video({ src: '/test/fixtures/SampleVideo_360x240_1mb.mp4' })

    playback.on(Events.PLAYBACK_SEEKED, callback)
    playback.on(Events.PLAYBACK_SEEKED, () => {
      callback.should.have.been.calledOnce
      done()
    }, this)

    playback.el.dispatchEvent(new Event('seeked'))
  })

  it('isPlaying() is true after constructor when autoPlay is true', function(done) {
    const playback = new HTML5Video({ src: 'http://example.com/dash.ogg', autoPlay: true, mute: true })
    process.nextTick(function() {
      expect(playback.isPlaying()).to.be.true
      done()
    })
  })

  it('setup crossorigin attribute', function() {
    const options = $.extend({ playback: { crossOrigin: 'use-credentials' } }, this.options)
    const playback = new HTML5Video(options)

    expect(playback.el.crossOrigin).to.be.equal('use-credentials')
    expect(playback.el.getAttribute('crossorigin')).equal('use-credentials')
  })

  it('enables inline playback for webviews when playInline flag is set', function() {
    const options = $.extend({ playback: { playInline: true } }, this.options)
    const playback = new HTML5Video(options)

    expect(playback.el['x-webkit-playsinline']).to.be.true
    expect(playback.el.getAttribute('playsinline')).equal('playsinline')
  })

  it('allows displaying default video tag controls', function() {
    const options = $.extend({ playback: { controls: 'controls' } }, this.options)
    const playback = new HTML5Video(options)
    expect(playback.el.controls).to.be.true
  })

  it('mute or unmute video element when volume is changed', function() {
    const playback = new HTML5Video(this.options)

    expect(playback.el.getAttribute('muted')).to.be.null
    expect(playback.el.muted).to.be.false

    playback.volume(0)
    expect(playback.el.getAttribute('muted')).equal('true')
    expect(playback.el.muted).to.be.true

    playback.volume(0.5)
    expect(playback.el.getAttribute('muted')).to.be.null
    expect(playback.el.muted).to.be.false
  })

  it('setup external tracks', function() {
    let newTrackUrl = () => { URL.createObjectURL(new Blob([], { type: 'text/vtt' })) }
    const options = $.extend({ playback: {
      externalTracks: [
        { lang: 'en', label: 'English', src: newTrackUrl(), kind: 'subtitles' },
        { lang: 'fr', label: 'French', src: newTrackUrl() }
      ]
    } }, this.options)
    const playback = new HTML5Video(options)
    playback.render()
    const $tracks = playback.$el.find('track[data-html5-video-track]')

    expect($tracks[0].getAttribute('data-html5-video-track')).to.be.equal('0')
    expect($tracks[0].getAttribute('kind')).to.be.equal('subtitles')
    expect($tracks[0].getAttribute('label')).to.be.equal('English')
    expect($tracks[0].getAttribute('srclang')).to.be.equal('en')

    expect($tracks[1].getAttribute('data-html5-video-track')).to.be.equal('1')
    expect($tracks[1].getAttribute('kind')).to.be.equal('subtitles')
    expect($tracks[1].getAttribute('label')).to.be.equal('French')
    expect($tracks[1].getAttribute('srclang')).to.be.equal('fr')
  })

  it('can switch text tracks', function() {
    let newTrackUrl = () => { URL.createObjectURL(new Blob([], { type: 'text/vtt' })) }
    const options = $.extend({ playback: {
      externalTracks: [
        { lang: 'en', label: 'English', src: newTrackUrl(), kind: 'subtitles' },
        { lang: 'fr', label: 'French', src: newTrackUrl() }
      ]
    } }, this.options)
    const playback = new HTML5Video(options)
    playback.render()

    expect(playback.hasClosedCaptionsTracks).to.be.true
    expect(playback.closedCaptionsTracks.length).equal(2)
    expect(playback.closedCaptionsTrackId).equal(-1)
    expect(playback.closedCaptionsTracks[0].track.mode).to.not.equal('showing')
    expect(playback.closedCaptionsTracks[1].track.mode).to.not.equal('showing')

    playback.closedCaptionsTrackId = 0
    expect(playback.closedCaptionsTrackId).equal(0)
    expect(playback.closedCaptionsTracks[0].track.mode).equal('showing')
    expect(playback.closedCaptionsTracks[1].track.mode).to.not.equal('showing')

    playback.closedCaptionsTrackId = 1
    expect(playback.closedCaptionsTrackId).equal(1)
    expect(playback.closedCaptionsTracks[0].track.mode).to.not.equal('showing')
    expect(playback.closedCaptionsTracks[1].track.mode).equal('showing')

    playback.closedCaptionsTrackId = -1
    expect(playback.closedCaptionsTrackId).equal(-1)
    expect(playback.closedCaptionsTracks[0].track.mode).to.not.equal('showing')
    expect(playback.closedCaptionsTracks[1].track.mode).to.not.equal('showing')
  })

  describe('progress', function() {
    let start, end, currentTime
    const duration = 300
    const fakeEl = {
      get currentTime() { return currentTime },
      get duration() { return duration },
      get buffered() { return { start: (i) => start[i], end: (i) => end[i], get length() { return start.length } } }
    }

    beforeEach(function() {
      currentTime = 0
      start = [0]
      end = [30]

      this.callback = sinon.spy()
      this.playback = new HTML5Video(this.options)
      this.playback.setElement(fakeEl)
      this.playback.on(Events.PLAYBACK_PROGRESS, this.callback)
    })

    it('should trigger PLAYBACK_PROGRESS with current buffer position', function() {
      this.playback._onProgress() // cannot trigger event on fake element (improve later?)
      let currentProgess = this.callback.getCall(0).args[0]

      expect(currentProgess.start).to.be.equal(start[0])
      expect(currentProgess.current).to.be.equal(end[0])
      expect(currentProgess.total).to.be.equal(duration)
    })

    it('should find current buffer position', function() {
      start = [0, 50, 180]
      end = [30, 90, 280]
      currentTime = 75 // this should be located at index 1

      this.playback._onProgress() // cannot trigger event on fake element (improve later?)
      let progress = this.callback.getCall(0).args[0]

      expect(progress.start).to.be.equal(start[1])
      expect(progress.current).to.be.equal(end[1])
    })

    it('does not trigger buffer event when the playback is initialized', function() {
      /*
        Only trigger buffer events when buffer state change.
        The default value for _bufferState is false.
      */

      let builtInEvents = ['loadedmetadata', 'progress', 'timeupdate'].map(
        function(label) {
          return new Event(label)
        }
      )

      let callback = sinon.spy()
      let playback = new HTML5Video(this.options)

      playback.on(Events.PLAYBACK_BUFFERING, callback)
      playback.on(Events.PLAYBACK_BUFFERFULL, callback)

      builtInEvents.map(function(event) { playback.el.dispatchEvent(event) })
      callback.should.not.have.been.called
    })

    it('should return an array of buffer segments as {start, end} objects', function() {
      start = [0, 50, 180]
      end = [30, 90, 280]

      this.playback._onProgress() // cannot trigger event on fake element (improve later?)
      let buffered = this.callback.getCall(0).args[1]

      expect(buffered.length).to.be.equal(start.length)
      expect(buffered[0]).to.deep.equal({ start: start[0], end: end[0] })
      expect(buffered[1]).to.deep.equal({ start: start[1], end: end[1] })
      expect(buffered[2]).to.deep.equal({ start: start[2], end: end[2] })
    })
  })

  it('should be able to identify it can play resources independently of the file extension case', function() {
    expect(HTML5Video.canPlay('/relative/video.ogg')).to.be.true
    expect(HTML5Video.canPlay('/relative/VIDEO.OGG')).to.be.true
  })

  describe('options', function() {
    it('should use the playback object within player options', function() {
      const options = {
        src: 'http://example.com/video.m3u8',
        nonPlaybackOption: false,
        playback: {
          somePlaybackOption: true
        }
      }
      const html5Video = new HTML5Video(options)
      expect(html5Video.options.playback.somePlaybackOption).to.be.true
      expect(html5Video.options.playback).not.to.include.keys('nonPlaybackOption')
    })

    it('should use hlsjsConfig from player options as fallback', function() {
      const options = {
        src: 'http://example.com/video.m3u8',
        nonPlaybackOption: false,
        somePlaybackOption: true
      }
      const html5Video = new HTML5Video(options)
      expect(html5Video.options.playback.somePlaybackOption).to.be.true
      expect(html5Video.options.playback.nonPlaybackOption).to.be.false
    })
  })

  describe('video element', function() {
    it('should set src url from options', function() {
      const options = {
        src: 'http://example.com/some_source?query_string=here',
        mimeType: 'application/x-mpegURL'
      }
      const html5Video = new HTML5Video(options)
      html5Video.render()
      expect(html5Video.el.getAttribute('src')).to.be.equal(options.src)
    })

    it('should have src attribute removed after stop, and then added after play', function() {
      const options = {
        src: 'http://example.com/video.mp4'
      }
      const html5Video = new HTML5Video(options)
      html5Video.render()
      html5Video.play()
      html5Video.stop()
      expect(html5Video.el.hasAttribute('src')).to.be.false
      html5Video.play()
      expect(html5Video.el.getAttribute('src')).to.be.equal(options.src)
    })
  })

  describe('audio resources', function() {
    it('should be able to play audio resources', function() {
      expect(HTML5Video.canPlay('http://domain.com/Audio.oga')).to.be.true
      expect(HTML5Video.canPlay('http://domain.com/Audio.oga?query_string=here')).to.be.true
      expect(HTML5Video.canPlay('/relative/Audio.oga')).to.be.true
      expect(HTML5Video.canPlay('/relative/Audio.wav')).to.be.true
    })

    it('should play audio resources on an audio tag', function() {
      const options = { src: 'http://example.com/dash.oga' }
      const playback = new HTML5Video(options)
      expect(playback.tagName).to.be.equal('audio')
    })

    it('should use an audio tag when the audioOnly option is set to true', function() {
      const options = {
        src: 'http://example.com/dash.m3u8',
        playback: { audioOnly: true }
      }
      const playback = new HTML5Video(options)
      expect(playback.tagName).to.be.equal('audio')
    })

    it('should not play video resources on an audio tag if audioOnly flag is not set and a video mime-type is set', function() {
      const options = { src: 'http://example.com/video.mp4', mimeType: 'video/mp4' }
      const playback = new HTML5Video(options)
      expect(playback.isAudioOnly).to.be.false
      expect(playback.tagName).to.be.equal('video')
    })

    it('should play on audio tag if audioOnly flag is not set and the mime-type specified is audio only', function() {
      let options = { src: 'http://example.com/audio?some_parameter=value', mimeType: 'audio/ogg' },
        playback = new HTML5Video(options)
      expect(playback.isAudioOnly).to.be.true
      expect(playback.tagName).to.be.equal('audio')

      options = { src: 'http://example.com/audio?some_parameter=value', mimeType: 'audio/wav' }
      playback = new HTML5Video(options)
      expect(playback.isAudioOnly).to.be.true
      expect(playback.tagName).to.be.equal('audio')
    })

    it('should not play video resources on an audio tag if audioOnly flag is not set', function() {
      const options = { src: 'http://example.com/dash.m3u8' }
      const playback = new HTML5Video(options)
      expect(playback.isAudioOnly).to.be.false
      expect(playback.tagName).to.be.equal('video')
    })
  })
})
<|endoftext|>


<commit_before>define(["dojo/_base/html"],function(dhtml){
	dojo.declare("dojox.mobile.ProgressIndicator", null, {
		interval: 100, // milliseconds
		colors: [
			"#C0C0C0", "#C0C0C0", "#C0C0C0", "#C0C0C0",
			"#C0C0C0", "#C0C0C0", "#B8B9B8", "#AEAFAE",
			"#A4A5A4", "#9A9A9A", "#8E8E8E", "#838383"
		],

		_bars: [],

		constructor: function(){
			this.domNode = dojo.create("DIV");
			this.domNode.className = "mblProgContainer";
			this.spinnerNode = dojo.create("DIV", null, this.domNode);
			for(var i = 0; i < this.colors.length; i++){
				var div = dojo.create("DIV", {className:"mblProg mblProg"+i}, this.spinnerNode);
				this._bars.push(div);
			}
		},

		start: function(){
			if(this.imageNode){
				var img = this.imageNode;
				var l = Math.round((this.domNode.offsetWidth - img.offsetWidth) / 2);
				var t = Math.round((this.domNode.offsetHeight - img.offsetHeight) / 2);
				img.style.margin = t+"px "+l+"px";
				return;
			}
			var cntr = 0;
			var _this = this;
			var n = this.colors.length;
			this.timer = setInterval(function(){
				cntr--;
				cntr = cntr < 0 ? n - 1 : cntr;
				var c = _this.colors;
				for(var i = 0; i < n; i++){
					var idx = (cntr + i) % n;
					_this._bars[i].style.backgroundColor = c[idx];
				}
			}, this.interval);
		},

		stop: function(){
			if(this.timer){
				clearInterval(this.timer);
			}
			this.timer = null;
			if(this.domNode.parentNode){
				this.domNode.parentNode.removeChild(this.domNode);
			}
		},

		setImage: function(/*String*/file){
			// summary:
			//		Set an indicator icon image file (typically animated GIF).
			//		If null is specified, restores the default spinner.
			if(file){
				this.imageNode = dojo.create("IMG", {src:file}, this.domNode);
				this.spinnerNode.style.display = "none";
			}else{
				if(this.imageNode){
					this.domNode.removeChild(this.imageNode);
					this.imageNode = null;
				}
				this.spinnerNode.style.display = "";
			}
		}
	});
	dojox.mobile.ProgressIndicator._instance = null;
	dojox.mobile.ProgressIndicator.getInstance = function(){
		if(!dojox.mobile.ProgressIndicator._instance){
			dojox.mobile.ProgressIndicator._instance = new dojox.mobile.ProgressIndicator();
		}
		return dojox.mobile.ProgressIndicator._instance;
	};

	return dojox.mobile.ProgressIndicator;
});
<commit_msg>Fixes #12723 !strict Workaround to avoid a side-effect of the screen flicker workaround.<commit_after>define(["dojo/_base/html"],function(dhtml){
	dojo.declare("dojox.mobile.ProgressIndicator", null, {
		interval: 100, // milliseconds
		colors: [
			"#C0C0C0", "#C0C0C0", "#C0C0C0", "#C0C0C0",
			"#C0C0C0", "#C0C0C0", "#B8B9B8", "#AEAFAE",
			"#A4A5A4", "#9A9A9A", "#8E8E8E", "#838383"
		],

		_bars: [],

		constructor: function(){
			this.domNode = dojo.create("DIV");
			this.domNode.className = "mblProgContainer";
			if(dojo.config["mblAndroidWorkaround"] !== false && dojo.isAndroid >= 2.2 && dojo.isAndroid < 3){
				// workaround to avoid the side effects of the fixes for android screen flicker problem
				dojo.style(this.domNode, "webkitTransform", "translate3d(0,0,0)");
			}
			this.spinnerNode = dojo.create("DIV", null, this.domNode);
			for(var i = 0; i < this.colors.length; i++){
				var div = dojo.create("DIV", {className:"mblProg mblProg"+i}, this.spinnerNode);
				this._bars.push(div);
			}
		},

		start: function(){
			if(this.imageNode){
				var img = this.imageNode;
				var l = Math.round((this.domNode.offsetWidth - img.offsetWidth) / 2);
				var t = Math.round((this.domNode.offsetHeight - img.offsetHeight) / 2);
				img.style.margin = t+"px "+l+"px";
				return;
			}
			var cntr = 0;
			var _this = this;
			var n = this.colors.length;
			this.timer = setInterval(function(){
				cntr--;
				cntr = cntr < 0 ? n - 1 : cntr;
				var c = _this.colors;
				for(var i = 0; i < n; i++){
					var idx = (cntr + i) % n;
					_this._bars[i].style.backgroundColor = c[idx];
				}
			}, this.interval);
		},

		stop: function(){
			if(this.timer){
				clearInterval(this.timer);
			}
			this.timer = null;
			if(this.domNode.parentNode){
				this.domNode.parentNode.removeChild(this.domNode);
			}
		},

		setImage: function(/*String*/file){
			// summary:
			//		Set an indicator icon image file (typically animated GIF).
			//		If null is specified, restores the default spinner.
			if(file){
				this.imageNode = dojo.create("IMG", {src:file}, this.domNode);
				this.spinnerNode.style.display = "none";
			}else{
				if(this.imageNode){
					this.domNode.removeChild(this.imageNode);
					this.imageNode = null;
				}
				this.spinnerNode.style.display = "";
			}
		}
	});
	dojox.mobile.ProgressIndicator._instance = null;
	dojox.mobile.ProgressIndicator.getInstance = function(){
		if(!dojox.mobile.ProgressIndicator._instance){
			dojox.mobile.ProgressIndicator._instance = new dojox.mobile.ProgressIndicator();
		}
		return dojox.mobile.ProgressIndicator._instance;
	};

	return dojox.mobile.ProgressIndicator;
});
<|endoftext|>


<commit_before>/* @flow */
import { Dimensions, StyleSheet } from 'react-native';

import { colors } from 'app/settings';

export default StyleSheet.create({
  Poster: {
    backgroundColor: colors.cardBackgroundColor,
  },
  Pdf: {
    flex: 1,
    // Remove offset due to the navigation bar and footer menu.
    height: Dimensions.get('window').height - 120,
  },
  FooterButton: {
    backgroundColor: colors.secondaryColor,
  },
  Title: {
    textAlign: 'center',
  },
  Authors: {
    textAlign: 'center',
    paddingTop: 10,
  },
  Abstract: {
    paddingTop: 20,
  },
  SavedAt: {
    paddingTop: 15,
    color: colors.textSecondaryColor,
    fontSize: 11,
  },
});
<commit_msg>Fix poster issue that prevents zooming/pinching<commit_after>/* @flow */
import { Dimensions, StyleSheet } from 'react-native';

import { colors } from 'app/settings';

export default StyleSheet.create({
  Poster: {
    backgroundColor: colors.cardBackgroundColor,
  },
  Pdf: {
    flex: 1,
    // Remove offset due to the navigation bar and footer menu.
    height: Dimensions.get('window').height - 135,
  },
  FooterButton: {
    backgroundColor: colors.secondaryColor,
  },
  Title: {
    textAlign: 'center',
  },
  Authors: {
    textAlign: 'center',
    paddingTop: 10,
  },
  Abstract: {
    paddingTop: 20,
  },
  SavedAt: {
    paddingTop: 15,
    color: colors.textSecondaryColor,
    fontSize: 11,
  },
});
<|endoftext|>