<commit_before>/*
 * Copyright (c) 2005-2007 Henri Sivonen
 * Copyright (c) 2007-2008 Mozilla Foundation
 * Copyright (c) 2007 Simon Pieters
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
var hasDuplicateMessages = false
var currentOl = null
var ungroupedOl = null
var groupedOl = null
var urlInput = null
var fileInput = null
var textarea = null

function boot(){
    initFieldHolders()
    schemaChanged()
    parserChanged()
    initGrouping()
}

function initFieldHolders(){
    if (document.forms[0].className == 'simple') {
        return
    }
    urlInput = document.getElementById('doc')

    textarea = createHtmlElement('textarea')
    if (textarea) {
        textarea.cols = 72
        textarea.rows = 15
        textarea.id = 'doc'
        textarea.name = 'content'
        copySourceIntoTextArea()
        if (textarea.value == '') {
            textarea.value = '<!DOCTYPE html>\n\n\n<title></title>\n\n\n

\n\n'
        }
    }

    fileInput = createHtmlElement('input')
    if (fileInput) {
        fileInput.type = 'file'
        fileInput.id = 'doc'
        fileInput.name = 'file'
    }

    var td = urlInput.parentNode
    if (td) {
        var th = td.previousSibling
        var label = th.firstChild
        var modeSelect = createHtmlElement("select")
        modeSelect.appendChild(createOption('Address', ''))
        modeSelect.appendChild(createOption('File Upload', 'file'))
        modeSelect.appendChild(createOption('Text Field', 'textarea'))
        modeSelect.onchange = function(){
            if (this.value == 'file') {
                installFileUpload()
            }
            else
                if (this.value == 'textarea') {
                    installTextarea()
                }
                else {
                    installUrlInput()
                }
        }
        th.replaceChild(modeSelect, label)
    }
}

function createOption(text, value){
    var rv = createHtmlElement('option')
    rv.value = value
    var tn = document.createTextNode(text)
    rv.appendChild(tn)
    return rv
}

function schemaChanged(){
    if (document.getElementById) {
        var input = document.getElementById("schema")
        var select = document.getElementById("preset")
        if (input) {
            var value = input.value
            if (select) {
                if (select.firstChild) {
                    for (var n = select.firstChild; n != null; n = n.nextSibling) {
                        if (n.value == value) {
                            n.selected = true
                            toggleParsers(value)
                            return
                        }
                    }
                    select.firstChild.selected = true
                    toggleParsers("")
                }
            }
        }
    }
}

function presetChanged(){
    if (document.getElementById) {
        var input = document.getElementById("schema")
        var select = document.getElementById("preset")
        if (input && select) {
            input.value = select.value
        }
    }
    toggleParsers(select.value)
}

function toggleParsers(newValue){
    if (document.getElementById) {
        var preset = document.getElementById("preset")
        if (preset) {
            if (isHtmlCompatiblePreset(newValue)) {
                var select = document.getElementById("parser")
                if (select) {
                    if (select.firstChild) {
                        for (var n = select.firstChild; n != null; n = n.nextSibling) {
                            n.disabled = false
                        }
                        if (document.getElementById('doc').name == 'content') {
                            // text area case
                            if (select.firstChild.selected) {
                                select.firstChild.nextSibling.nextSibling.nextSibling.selected = true
                                disableById('nsfilter')
                            }
                            select.firstChild.disabled = true
                        }
                    }
                }
            }
            else {
                var select = document.getElementById("parser")
                if (select) {
                    if (select.firstChild) {
                        if (select.firstChild.selected) {
                            select.firstChild.nextSibling.selected = true
                        }
                        for (var n = select.firstChild; n != null; n = n.nextSibling) {
                            n.disabled = (n.value == "" || isHtmlParserValue(n.value))
                        }
                    }
                }
            }
        }
    }
}

function isHtmlParserValue(parser){
    return (parser.indexOf("html") == 0)
}

function isHtmlCompatiblePreset(preset){
    return (preset == "" ||
    preset.indexOf("http://s.validator.nu/xhtml10/xhtml-basic.rnc") == 0 ||
    preset.indexOf("http://s.validator.nu/xhtml10/xhtml-frameset.rnc") == 0 ||
    preset.indexOf("http://s.validator.nu/xhtml10/xhtml-strict.rnc") == 0 ||
    preset.indexOf("http://s.validator.nu/xhtml10/xhtml-transitional.rnc") == 0 ||
    preset.indexOf("http://s.validator.nu/html5/html5full.rnc") == 0)
}

function parserChanged(){
    if (document.getElementById) {
        var parser = document.getElementById("parser")
        if (parser) {
            if (isHtmlParserValue(parser.value)) {
                var select = document.getElementById("preset")
                if (select) {
                    if (select.firstChild) {
                        for (var n = select.firstChild; n != null; n = n.nextSibling) {
                            n.disabled = !isHtmlCompatiblePreset(n.value)
                        }
                    }
                }
                var nsfilter = document.getElementById("nsfilter")
                if (nsfilter) {
                    nsfilter.disabled = true
                }
            }
            else {
                var select = document.getElementById("preset")
                if (select) {
                    if (select.firstChild) {
                        for (var n = select.firstChild; n != null; n = n.nextSibling) {
                            n.disabled = false
                        }
                    }
                }
                var nsfilter = document.getElementById("nsfilter")
                if (nsfilter) {
                    nsfilter.disabled = false
                }
            }
        }
    }
}

function formSubmission(){
    if (document.getElementById) {
        if (document.getElementsByTagName) {
            var form = document.getElementsByTagName("form")[0]
            if (form.checkValidity) {
                if (!form.checkValidity()) {
                    return true
                }
            }
        }
        disableById("submit")
        disableById("preset")
        disableByIdIfEmptyString("parser")
        disableByIdIfEmptyString("schema")
        disableByIdIfEmptyString("charset")
        disableByIdIfEmptyString("nsfilter")
        maybeMoveDocumentRowDown()
        return true
    }
}

function maybeMoveDocumentRowDown(){
    var field = document.getElementById('doc')
    if (field && field.name != 'doc') {
        var td = field.parentNode
        if (td) {
            var tr = td.parentNode
            var tbody = tr.parentNode
            tbody.appendChild(tr)
        }
    }
}

function disableById(id){
    var field = document.getElementById(id)
    if (field) {
        field.disabled = true
    }
}

function disableByIdIfEmptyString(id){
    var field = document.getElementById(id)
    if (field) {
        if ("" == field.value) {
            field.disabled = true
        }
    }
}

function enableById(id){
    var field = document.getElementById(id)
    if (field) {
        field.disabled = false
    }
}

function createHtmlElement(tagName){
    return document.createElementNS ? document.createElementNS("http://www.w3.org/1999/xhtml", tagName) : document.createElement(tagName)
}

function installGroupingToggle(){
    var para = createHtmlElement('p')
    var button = createHtmlElement('input')
    button.type = 'button'
    button.value = 'Group Messages'
    para.appendChild(button)
    if (hasDuplicateMessages) {
        button.onclick = function(){
            if (currentOl == ungroupedOl) {
                currentOl.parentNode.replaceChild(groupedOl, currentOl)
                currentOl = groupedOl
                this.value = 'Ungroup Messages'
            }
            else {
                currentOl.parentNode.replaceChild(ungroupedOl, currentOl)
                currentOl = ungroupedOl
                this.value = 'Group Messages'
            }
        }
    }
    else {
        button.disabled = true
    }
    currentOl.parentNode.insertBefore(para, currentOl)
}

function initGrouping(){
    var n = document.documentElement.lastChild.firstChild
    while (n) {
        // The line below protects IE users from a crash
        if (n instanceof HTMLOListElement && n.className != 'source') { // deliberately IE-incompatible
            //		if (n.start) { // cross-browser compatible
            currentOl = n
            break
        }
        n = n.nextSibling
    }
    if (!currentOl) {
        return
    }
    ungroupedOl = currentOl
    groupedOl = buildGrouped(ungroupedOl)
    installGroupingToggle()
}

function buildGrouped(ol){
    var locListByMsg = {}
    var rv = createHtmlElement('ol')
    var li = ol.firstChild
    var i = 1
    while (li) {
        var msgPara = li.firstChild
        var locExtract = createHtmlElement('li')
        locExtract.value = i
        var loc = msgPara.nextSibling
        var elaboration = null
        if (loc && loc.className && loc.className == 'location') {
            locExtract.appendChild(loc.cloneNode(true))
            var extract = loc.nextSibling
            if (extract && extract.className && extract.className == 'extract') {
                locExtract.appendChild(extract.cloneNode(true))
                elaboration = extract.nextSibling
            }
            else {
                elaboration = extract
            }
        }
        else {
            elaboration = loc
            var noLoc = createHtmlElement('p')
            noLoc.appendChild(document.createTextNode("(No location)"))
            locExtract.appendChild(noLoc)
        }
        var locList = null
        var msgText = msgPara.innerHTML
        locList = locListByMsg[msgText]
        if (locList) {
            hasDuplicateMessages = true
        }
        else {
            locList = createHtmlElement('ol')
            locListByMsg[msgText] = locList
            var msgItem = createHtmlElement('li')
            msgItem.className = li.className
            msgItem.appendChild(msgPara.cloneNode(true))
            if (elaboration) {
                msgItem.appendChild(elaboration.cloneNode(true))
            }
            msgItem.appendChild(locList)
            rv.appendChild(msgItem)
        }
        locList.appendChild(locExtract)

        li = li.nextSibling
        i++
    }

    return rv
}

function installTextarea(){
    if (document.getElementById) {
        var input = document.getElementById('doc')
        if (input && textarea) {
            var form = document.forms[0]
            if (form) {
                form.method = 'post'
                form.enctype = 'multipart/form-data'
                input.parentNode.replaceChild(textarea, input)
                disableById('charset')
                schemaChanged()
            }
        }
    }
}

function installFileUpload(){
    if (document.getElementById) {
        var input = document.getElementById('doc')
        if (input && fileInput) {
            var form = document.forms[0]
            if (form) {
                form.method = 'post'
                form.enctype = 'multipart/form-data'
                input.parentNode.replaceChild(fileInput, input)
                enableById('charset')
                schemaChanged()
            }
        }
    }
}

function installUrlInput(){
    if (document.getElementById) {
        var input = document.getElementById('doc')
        if (input && urlInput) {
            var form = document.forms[0]
            if (form) {
                form.method = 'get'
                form.enctype = ''
                input.parentNode.replaceChild(urlInput, input)
                enableById('charset')
                schemaChanged()
            }
        }
    }
}

function copySourceIntoTextArea(){
    var strings = []
    var source = null
    var n = document.documentElement.lastChild.firstChild
    while (n) {
        if (n.className == 'source') {
            source = n
            break
        }
        n = n.nextSibling
    }
    if (source && textarea) {
        var li = source.firstChild
        while (li) {
            var code = li.firstChild
            strings.push(code.textContent)

            li = li.nextSibling
        }
        textarea.value = strings.join('\n')
    }
}

window.onunload = function(){
    if (document.getElementById) {
        enableById("submit")
        enableById("preset")
        enableById("parser")
        enableById("schema")
        enableById("charset")
        enableById("nsfilter")
        schemaChanged()
        parserChanged()
    }
}
<commit_msg>try to make it work in IE<commit_after>/*
 * Copyright (c) 2005-2007 Henri Sivonen
 * Copyright (c) 2007-2008 Mozilla Foundation
 * Copyright (c) 2007 Simon Pieters
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
var hasDuplicateMessages = false
var currentOl = null
var ungroupedOl = null
var groupedOl = null
var urlInput = null
var fileInput = null
var textarea = null

function boot(){
    initFieldHolders()
    schemaChanged()
    parserChanged()
    initGrouping()
}

function initFieldHolders(){
    if (document.forms[0].className == 'simple') {
        return
    }
    urlInput = document.getElementById('doc')

    textarea = createHtmlElement('textarea')
    if (textarea) {
        textarea.cols = 72
        textarea.rows = 15
        textarea.id = 'doc'
        textarea.name = 'content'
        copySourceIntoTextArea()
        if (textarea.value == '') {
            textarea.value = '<!DOCTYPE html>\n\n\n<title></title>\n\n\n

\n\n'
        }
    }

    fileInput = createHtmlElement('input')
    if (fileInput) {
        fileInput.type = 'file'
        fileInput.id = 'doc'
        fileInput.name = 'file'
    }

    var td = urlInput.parentNode
    if (td) {
        var th = td.previousSibling
        var label = th.firstChild
        var modeSelect = createHtmlElement("select")
        modeSelect.appendChild(createOption('Address', ''))
        modeSelect.appendChild(createOption('File Upload', 'file'))
        modeSelect.appendChild(createOption('Text Field', 'textarea'))
        modeSelect.onchange = function(){
            if (this.value == 'file') {
                installFileUpload()
            }
            else
                if (this.value == 'textarea') {
                    installTextarea()
                }
                else {
                    installUrlInput()
                }
        }
        th.replaceChild(modeSelect, label)
    }
}

function createOption(text, value){
    var rv = createHtmlElement('option')
    rv.value = value
    var tn = document.createTextNode(text)
    rv.appendChild(tn)
    return rv
}

function schemaChanged(){
    if (document.getElementById) {
        var input = document.getElementById("schema")
        var select = document.getElementById("preset")
        if (input) {
            var value = input.value
            if (select) {
                if (select.firstChild) {
                    for (var n = select.firstChild; n != null; n = n.nextSibling) {
                        if (n.value == value) {
                            n.selected = true
                            toggleParsers(value)
                            return
                        }
                    }
                    select.firstChild.selected = true
                    toggleParsers("")
                }
            }
        }
    }
}

function presetChanged(){
    if (document.getElementById) {
        var input = document.getElementById("schema")
        var select = document.getElementById("preset")
        if (input && select) {
            input.value = select.value
        }
    }
    toggleParsers(select.value)
}

function toggleParsers(newValue){
    if (document.getElementById) {
        var preset = document.getElementById("preset")
        if (preset) {
            if (isHtmlCompatiblePreset(newValue)) {
                var select = document.getElementById("parser")
                if (select) {
                    if (select.firstChild) {
                        for (var n = select.firstChild; n != null; n = n.nextSibling) {
                            n.disabled = false
                        }
                        if (document.getElementById('doc').name == 'content') {
                            // text area case
                            if (select.firstChild.selected) {
                                select.firstChild.nextSibling.nextSibling.nextSibling.selected = true
                                disableById('nsfilter')
                            }
                            select.firstChild.disabled = true
                        }
                    }
                }
            }
            else {
                var select = document.getElementById("parser")
                if (select) {
                    if (select.firstChild) {
                        if (select.firstChild.selected) {
                            select.firstChild.nextSibling.selected = true
                        }
                        for (var n = select.firstChild; n != null; n = n.nextSibling) {
                            n.disabled = (n.value == "" || isHtmlParserValue(n.value))
                        }
                    }
                }
            }
        }
    }
}

function isHtmlParserValue(parser){
    return (parser.indexOf("html") == 0)
}

function isHtmlCompatiblePreset(preset){
    return (preset == "" ||
    preset.indexOf("http://s.validator.nu/xhtml10/xhtml-basic.rnc") == 0 ||
    preset.indexOf("http://s.validator.nu/xhtml10/xhtml-frameset.rnc") == 0 ||
    preset.indexOf("http://s.validator.nu/xhtml10/xhtml-strict.rnc") == 0 ||
    preset.indexOf("http://s.validator.nu/xhtml10/xhtml-transitional.rnc") == 0 ||
    preset.indexOf("http://s.validator.nu/html5/html5full.rnc") == 0)
}

function parserChanged(){
    if (document.getElementById) {
        var parser = document.getElementById("parser")
        if (parser) {
            if (isHtmlParserValue(parser.value)) {
                var select = document.getElementById("preset")
                if (select) {
                    if (select.firstChild) {
                        for (var n = select.firstChild; n != null; n = n.nextSibling) {
                            n.disabled = !isHtmlCompatiblePreset(n.value)
                        }
                    }
                }
                var nsfilter = document.getElementById("nsfilter")
                if (nsfilter) {
                    nsfilter.disabled = true
                }
            }
            else {
                var select = document.getElementById("preset")
                if (select) {
                    if (select.firstChild) {
                        for (var n = select.firstChild; n != null; n = n.nextSibling) {
                            n.disabled = false
                        }
                    }
                }
                var nsfilter = document.getElementById("nsfilter")
                if (nsfilter) {
                    nsfilter.disabled = false
                }
            }
        }
    }
}

function formSubmission(){
    if (document.getElementById) {
        if (document.getElementsByTagName) {
            var form = document.getElementsByTagName("form")[0]
            if (form.checkValidity) {
                if (!form.checkValidity()) {
                    return true
                }
            }
        }
        disableById("submit")
        disableById("preset")
        disableByIdIfEmptyString("parser")
        disableByIdIfEmptyString("schema")
        disableByIdIfEmptyString("charset")
        disableByIdIfEmptyString("nsfilter")
        maybeMoveDocumentRowDown()
        return true
    }
}

function maybeMoveDocumentRowDown(){
    var field = document.getElementById('doc')
    if (field && field.name != 'doc') {
        var td = field.parentNode
        if (td) {
            var tr = td.parentNode
            var tbody = tr.parentNode
            tbody.appendChild(tr)
        }
    }
}

function disableById(id){
    var field = document.getElementById(id)
    if (field) {
        field.disabled = true
    }
}

function disableByIdIfEmptyString(id){
    var field = document.getElementById(id)
    if (field) {
        if ("" == field.value) {
            field.disabled = true
        }
    }
}

function enableById(id){
    var field = document.getElementById(id)
    if (field) {
        field.disabled = false
    }
}

function createHtmlElement(tagName){
    return document.createElementNS ? document.createElementNS("http://www.w3.org/1999/xhtml", tagName) : document.createElement(tagName)
}

function installGroupingToggle(){
    var para = createHtmlElement('p')
    var button = createHtmlElement('input')
    button.type = 'button'
    button.value = 'Group Messages'
    para.appendChild(button)
    if (hasDuplicateMessages) {
        button.onclick = function(){
            if (currentOl == ungroupedOl) {
                currentOl.parentNode.replaceChild(groupedOl, currentOl)
                currentOl = groupedOl
                this.value = 'Ungroup Messages'
            }
            else {
                currentOl.parentNode.replaceChild(ungroupedOl, currentOl)
                currentOl = ungroupedOl
                this.value = 'Group Messages'
            }
        }
    }
    else {
        button.disabled = true
    }
    currentOl.parentNode.insertBefore(para, currentOl)
}

function initGrouping(){
    var n = document.documentElement.lastChild.firstChild
    while (n) {
        // The line below protects IE users from a crash
        if (n instanceof HTMLOListElement && n.className != 'source') { // deliberately IE-incompatible
            //		if (n.start) { // cross-browser compatible
            currentOl = n
            break
        }
        n = n.nextSibling
    }
    if (!currentOl) {
        return
    }
    ungroupedOl = currentOl
    groupedOl = buildGrouped(ungroupedOl)
    installGroupingToggle()
}

function buildGrouped(ol){
    var locListByMsg = {}
    var rv = createHtmlElement('ol')
    var li = ol.firstChild
    var i = 1
    while (li) {
        var msgPara = li.firstChild
        var locExtract = createHtmlElement('li')
        locExtract.value = i
        var loc = msgPara.nextSibling
        var elaboration = null
        if (loc && loc.className && loc.className == 'location') {
            locExtract.appendChild(loc.cloneNode(true))
            var extract = loc.nextSibling
            if (extract && extract.className && extract.className == 'extract') {
                locExtract.appendChild(extract.cloneNode(true))
                elaboration = extract.nextSibling
            }
            else {
                elaboration = extract
            }
        }
        else {
            elaboration = loc
            var noLoc = createHtmlElement('p')
            noLoc.appendChild(document.createTextNode("(No location)"))
            locExtract.appendChild(noLoc)
        }
        var locList = null
        var msgText = msgPara.innerHTML
        locList = locListByMsg[msgText]
        if (locList) {
            hasDuplicateMessages = true
        }
        else {
            locList = createHtmlElement('ol')
            locListByMsg[msgText] = locList
            var msgItem = createHtmlElement('li')
            msgItem.className = li.className
            msgItem.appendChild(msgPara.cloneNode(true))
            if (elaboration) {
                msgItem.appendChild(elaboration.cloneNode(true))
            }
            msgItem.appendChild(locList)
            rv.appendChild(msgItem)
        }
        locList.appendChild(locExtract)

        li = li.nextSibling
        i++
    }

    return rv
}

function installTextarea(){
    if (document.getElementById) {
        var input = document.getElementById('doc')
        if (input && textarea) {
            var form = document.forms[0]
            if (form) {
                form.method = 'post'
                form.enctype = 'multipart/form-data'
                input.parentNode.replaceChild(textarea, input)
                disableById('charset')
                schemaChanged()
            }
        }
    }
}

function installFileUpload(){
    if (document.getElementById) {
        var input = document.getElementById('doc')
        if (input && fileInput) {
            var form = document.forms[0]
            if (form) {
                form.method = 'post'
                form.enctype = 'multipart/form-data'
                input.parentNode.replaceChild(fileInput, input)
                enableById('charset')
                schemaChanged()
            }
        }
    }
}

function installUrlInput(){
    if (document.getElementById) {
        var input = document.getElementById('doc')
        if (input && urlInput) {
            var form = document.forms[0]
            if (form) {
                form.method = 'get'
                form.enctype = ''
                input.parentNode.replaceChild(urlInput, input)
                enableById('charset')
                schemaChanged()
            }
        }
    }
}

function copySourceIntoTextArea(){
    var strings = []
    var source = null
    var n = document.documentElement.lastChild.firstChild
    while (n) {
        if (n.className == 'source') {
            source = n
            break
        }
        n = n.nextSibling
    }
    if (source && textarea) {
        var li = source.firstChild
        while (li) {
            var code = li.firstChild
			var text = code.textContent
			if (text) {
	            strings.push(text)
			} else {
				strings.push(code.innerText)
			}

            li = li.nextSibling
        }
        textarea.value = strings.join('\n')
    }
}

window.onunload = function(){
    if (document.getElementById) {
        enableById("submit")
        enableById("preset")
        enableById("parser")
        enableById("schema")
        enableById("charset")
        enableById("nsfilter")
        schemaChanged()
        parserChanged()
    }
}
<|endoftext|>


<commit_before>/* This software is licensed under a BSD license; see the LICENSE file for details. */

define_ibex_controller({
name: "VBox",

jqueryWidget: {
    _init: function () {
        this.cssPrefix = this.options.options._cssPrefix;
        this.utils = this.options.options._utils;
        this.finishedCallback = this.options.options._finishedCallback;
        this.controllerDefaults = this.options.options._controllerDefaults;
        this.utilsClass = this.options.options._utilsClass;
        this.callbackWhenChildFinishes = this.options.options._vboxCallbackWhenChildFinishes;

        this.children = this.options.children;
        this.triggers = this.options.triggers;
        this.padding = dget(this.options, "padding", "2em");

        assert_is_arraylike(this.children, "The 'children' option of VBox must be an array");
        assert(this.children.length % 2 == 0, "The 'children' array for VBox must contain an even number of elements");

        assert_is_arraylike(this.triggers, "The 'triggers' option of VBox must be an array");
        assert(this.triggers.length > 0, "The 'triggers' array for VBox must be an array of length > 0");

        var t = this;
        $.each(this.triggers, function (_, tr) {
            assert(typeof(tr) == "number", "The 'triggers' array for VBox must be an array of integers");
            assert(tr >= 0 && tr < t.children.length / 2,
                   "Numbers in the 'triggers' array must be indices into the 'children' array starting from 0");
        });

        this.indicesAndResultsOfThingsThatHaveFinished = [];
//        this.childInstances = [];
        this.childUtils = [];

        this.childElements = new Array(this.children.length / 2);
        for (var i = 0; i < this.children.length; i += 2) {
            var controllerClass = this.children[i];
            var addImmediately = true;
            var removePrevious = false;
            if (controllerClass.charAt(0) == "*" || controllerClass.charAt(0) == "!") {
                addImmediately = false;
                if (controllerClass.charAt(0) == "!")
                    removePrevious = true;
                controllerClass = controllerClass.substr(1);
            }
            var childOptions = this.children[i + 1];
            childOptions = merge_dicts(this.controllerDefaults[controllerClass], childOptions);

            var u = new this.utilsClass(this.utils.getValuesFromPreviousElement());
            this.childUtils.push(u);
            (function(i) {
                u.setResults = function(results) {
                    t.indicesAndResultsOfThingsThatHaveFinished.push([i, results]);
                };
            })(i);

            function makeDiv() {
                var d = $(document.createElement("p")).css('clear', 'both');

                // Call a manipulator if one was supplied.
                if (! (t.options.manipulators === undefined)) {
                    for (var j = 0; j < t.options.manipulators.length; ++j) {
                        if (t.options.manipulators[j][0] == (i / 2))
                            d = t.options.manipulators[j][1](d);
                    }
                }

                // Add padding if requested.
                var dd = null;
                if (t.padding && i > 0) {
                    dd = $(document.createElement("div"))
                        .css('margin-top', t.padding)
                        .css('margin-bottom', 0)
                        .append(d);
                }

                // Wrap in a table if we're centering things.
                var ddd = null;
                if (conf_centerItems) {
                    ddd = $("
");
                    var tr = $(document.createElement("tr"));
                    var td = $(document.createElement("td"));
                    ddd.append(tr.append(td.append(dd ? dd : d)));
                }

                // Add the actual child.
                var ac = ddd ? ddd : (dd ? dd : d);

                var l = t.childUtils.length - 1;
                // Get around JavaScript's silly closure capture behavior (deriving
                // from weird variable scoping rules).
                // See http://calculist.blogspot.com/2005/12/gotcha-gotcha.html
                (function(l) {
                    childOptions._finishedCallback = function (r) { t.myFinishedCallback(l, r); };
                    childOptions._cssPrefix = ibex_controller_name_to_css_prefix(controllerClass);
                    childOptions._utils = u;
                    addSafeBindMethodPair(controllerClass);
                    d[controllerClass](childOptions);
                })(l);

                return ac;
            }

            if (addImmediately) {
                var ac = makeDiv()
                this.childElements[i/2] = { child: ac, addImmediately: true, removePrevious: false };
                this.element.append(ac);
            }
            else {
                this.childElements[i/2] = { makeDiv: makeDiv, addImmediately: false, removePrevious: removePrevious };
            }
        }
    },

    myFinishedCallback: function(index, results) {
        this.childUtils[index].gc();
        this.indicesAndResultsOfThingsThatHaveFinished.push([index, results]);

        var satisfied = true;
        for (var i = 0; i < this.triggers.length; ++i) {
            var foundIt = false;
            for (var j = 0; j < this.indicesAndResultsOfThingsThatHaveFinished.length; ++j) {
                if (this.indicesAndResultsOfThingsThatHaveFinished[j][0] == this.triggers[i]) {
                    foundIt = true;
                    break;
                }
            }
            if (! foundIt) {
                satisfied = false;
                break;
            }
        }

        if (satisfied) {
            // Merge values for next element.
            var merged = merge_list_of_dicts($.map(this.childUtils,
                                             function (x) { return x.valuesForNextElement; }));
            this.utils.valuesForNextElement = merged;

            this.finishedCallback(this.concatResults(this.indicesAndResultsOfThingsThatHaveFinished));
        }

        if (this.callbackWhenChildFinishes)
            this.callbackWhenChildFinishes(index, this.childElements[index].child, results);

        // Add next child if it wasn't added at the beginning.
        if (index + 1 < this.childElements.length) {
            var ce = this.childElements[index+1];
            if (! ce.addImmediately) {
                var ac = ce.makeDiv();
                ce.child = ac;
                ce.child.insertAfter(this.childElements[index].child);
                if (ce.removePrevious)
                    this.childElements[index].child.remove();
            }
        }
    },

    concatResults: function(iar) {
        iar = iar.sort(function(x, y) { return x[0] - y[0]; });
        var res = [];
        for (var i = 0; i < iar.length; ++i) {
            for (var j = 0; j < iar[i][1].length; ++j) {
                var line = [];
                for (var k = 0; k < iar[i][1][j].length; ++k)
                    line.push(iar[i][1][j][k]);
                res.push(line);
            }
        }
        return res;
    }
},

properties: { obligatory: ["children", "triggers"] }

});
<commit_msg>Fix bug with result concatenation in VBox<commit_after>/* This software is licensed under a BSD license; see the LICENSE file for details. */

define_ibex_controller({
name: "VBox",

jqueryWidget: {
    _init: function () {
        this.cssPrefix = this.options.options._cssPrefix;
        this.utils = this.options.options._utils;
        this.finishedCallback = this.options.options._finishedCallback;
        this.controllerDefaults = this.options.options._controllerDefaults;
        this.utilsClass = this.options.options._utilsClass;
        this.callbackWhenChildFinishes = this.options.options._vboxCallbackWhenChildFinishes;

        this.children = this.options.children;
        this.triggers = this.options.triggers;
        this.padding = dget(this.options, "padding", "2em");

        assert_is_arraylike(this.children, "The 'children' option of VBox must be an array");
        assert(this.children.length % 2 == 0, "The 'children' array for VBox must contain an even number of elements");

        assert_is_arraylike(this.triggers, "The 'triggers' option of VBox must be an array");
        assert(this.triggers.length > 0, "The 'triggers' array for VBox must be an array of length > 0");

        var t = this;
        $.each(this.triggers, function (_, tr) {
            assert(typeof(tr) == "number", "The 'triggers' array for VBox must be an array of integers");
            assert(tr >= 0 && tr < t.children.length / 2,
                   "Numbers in the 'triggers' array must be indices into the 'children' array starting from 0");
        });

        this.indicesAndResultsOfThingsThatHaveFinished = [];
//        this.childInstances = [];
        this.childUtils = [];

        this.childElements = new Array(this.children.length / 2);
        for (var i = 0; i < this.children.length; i += 2) {
            var controllerClass = this.children[i];
            var addImmediately = true;
            var removePrevious = false;
            if (controllerClass.charAt(0) == "*" || controllerClass.charAt(0) == "!") {
                addImmediately = false;
                if (controllerClass.charAt(0) == "!")
                    removePrevious = true;
                controllerClass = controllerClass.substr(1);
            }
            var childOptions = this.children[i + 1];
            childOptions = merge_dicts(this.controllerDefaults[controllerClass], childOptions);

            var u = new this.utilsClass(this.utils.getValuesFromPreviousElement());
            this.childUtils.push(u);
            (function(i) {
                u.setResults = function(results) {
                    t.indicesAndResultsOfThingsThatHaveFinished.push([i, results]);
                };
            })(i);

            function makeDiv() {
                var d = $(document.createElement("p")).css('clear', 'both');

                // Call a manipulator if one was supplied.
                if (! (t.options.manipulators === undefined)) {
                    for (var j = 0; j < t.options.manipulators.length; ++j) {
                        if (t.options.manipulators[j][0] == (i / 2))
                            d = t.options.manipulators[j][1](d);
                    }
                }

                // Add padding if requested.
                var dd = null;
                if (t.padding && i > 0) {
                    dd = $(document.createElement("div"))
                        .css('margin-top', t.padding)
                        .css('margin-bottom', 0)
                        .append(d);
                }

                // Wrap in a table if we're centering things.
                var ddd = null;
                if (conf_centerItems) {
                    ddd = $("
");
                    var tr = $(document.createElement("tr"));
                    var td = $(document.createElement("td"));
                    ddd.append(tr.append(td.append(dd ? dd : d)));
                }

                // Add the actual child.
                var ac = ddd ? ddd : (dd ? dd : d);

                var l = t.childUtils.length - 1;
                // Get around JavaScript's silly closure capture behavior (deriving
                // from weird variable scoping rules).
                // See http://calculist.blogspot.com/2005/12/gotcha-gotcha.html
                (function(l) {
                    childOptions._finishedCallback = function (r) { t.myFinishedCallback(l, r); };
                    childOptions._cssPrefix = ibex_controller_name_to_css_prefix(controllerClass);
                    childOptions._utils = u;
                    addSafeBindMethodPair(controllerClass);
                    d[controllerClass](childOptions);
                })(l);

                return ac;
            }

            if (addImmediately) {
                var ac = makeDiv()
                this.childElements[i/2] = { child: ac, addImmediately: true, removePrevious: false };
                this.element.append(ac);
            }
            else {
                this.childElements[i/2] = { makeDiv: makeDiv, addImmediately: false, removePrevious: removePrevious };
            }
        }
    },

    myFinishedCallback: function(index, results) {
        this.childUtils[index].gc();
        this.indicesAndResultsOfThingsThatHaveFinished.push([index, results]);

        var satisfied = true;
        for (var i = 0; i < this.triggers.length; ++i) {
            var foundIt = false;
            for (var j = 0; j < this.indicesAndResultsOfThingsThatHaveFinished.length; ++j) {
                if (this.indicesAndResultsOfThingsThatHaveFinished[j][0] == this.triggers[i]) {
                    foundIt = true;
                    break;
                }
            }
            if (! foundIt) {
                satisfied = false;
                break;
            }
        }

        if (satisfied) {
            // Merge values for next element.
            var merged = merge_list_of_dicts($.map(this.childUtils,
                                             function (x) { return x.valuesForNextElement; }));
            this.utils.valuesForNextElement = merged;

            this.finishedCallback(this.concatResults(this.indicesAndResultsOfThingsThatHaveFinished));
        }

        if (this.callbackWhenChildFinishes)
            this.callbackWhenChildFinishes(index, this.childElements[index].child, results);

        // Add next child if it wasn't added at the beginning.
        if (index + 1 < this.childElements.length) {
            var ce = this.childElements[index+1];
            if (! ce.addImmediately) {
                var ac = ce.makeDiv();
                ce.child = ac;
                ce.child.insertAfter(this.childElements[index].child);
                if (ce.removePrevious)
                    this.childElements[index].child.remove();
            }
        }
    },

    concatResults: function(iar) {
        iar = iar.sort(function(x, y) { return x[0] - y[0]; });
        var res = [];
        for (var i = 0; i < iar.length; ++i) {
            for (var j = 0; iar[i][1] && j < iar[i][1].length; ++j) {
                var line = [];
                for (var k = 0; k < iar[i][1][j].length; ++k)
                      line.push(iar[i][1][j][k]);
                res.push(line);
            }
        }
        return res;
    }
},

properties: { obligatory: ["children", "triggers"] }

});
<|endoftext|>


<commit_before>//= require active_admin/base
//= require select2
//= require expanding/expanding

$(document).ready(function() {
    var url;

    if (window.location.pathname === '/admin/lentil_tagsets/new') {
      url = '../lentil_tags/tags_api'
    } else {
      url = '../../lentil_tags/tags_api'
    }

    $(".lentil-admin-select").select2({
      width: 200,
    	ajax: {
        url: url,
        dataType: 'json',
        delay: 250,
        data: function (params) {
          return {
            q: params.term
          };
        },
        processResults: function (data, page) {
          // parse the results into the format expected by Select2.
          // since we are using custom formatting functions we do not need to
          // alter the remote JSON data
          return {
            results: $.map(data, function (item) {
              return {
                text: item.name,
                id: item.id
              };
            })
          };
        },
        cache: true
      }
    });
});<commit_msg>formatting<commit_after>//= require active_admin/base
//= require select2
//= require expanding/expanding

$(document).ready(function() {
    var url;

    if (window.location.pathname === '/admin/lentil_tagsets/new') {
      url = '../lentil_tags/tags_api';
    } else {
      url = '../../lentil_tags/tags_api';
    }

    $(".lentil-admin-select").select2({
      width: 200,
    	ajax: {
        url: url,
        dataType: 'json',
        delay: 250,
        data: function (params) {
          return {
            q: params.term
          };
        },
        processResults: function (data, page) {
          // parse the results into the format expected by Select2.
          // since we are using custom formatting functions we do not need to
          // alter the remote JSON data
          return {
            results: $.map(data, function (item) {
              return {
                text: item.name,
                id: item.id
              };
            })
          };
        },
        cache: true
      }
    });
});<|endoftext|>


<commit_before>// Get 5 cats, put them in the cache
// Move one up from cache
// Check if cache has 2 or fewer matchups

function renderInitialMatchup() {
  getCatQueueData().done(function() {
    renderCatQueue();
    renderNextMatchup();
  });
}

// AJAX request to fill the CATARRAY
function getCatQueueData() {
  var request = $.get({
    url: "/cats/random_cats.json"
  })
  var promise = request.then(function(data) {
    if (CATARRAY.length == 0) {
      CATARRAY = data
    } else {
      for (var i = 0; i < data.length; i++) {
        CATARRAY.push(data[i])
      }
    };
  })
  return promise
}

// Creates individual matchup divs, while removing cats from the array
function createMatchupTemplate() {
  var cat1 = CATARRAY.shift()
  var cat2 = CATARRAY.shift()
  var cats = {
    cat1: cat1,
    cat2: cat2
  }
  var html = JST['views/voting_boxes'](cats)
  var $html = $(html);
  return $html
}

// Renders matchups into a hidden div
function renderCatQueue() {
  while (CATARRAY.length > 0) {
    var $html = createMatchupTemplate()
    $('#kitty-cache').append($html)
  }
}

function renderNextMatchup() {
  $('#matchup-container').children().remove();
  var nextMatchup = $('#kitty-cache').children()[0]
  var $nextMatchup = $(nextMatchup).hide();
  // console.log($nextMatchup)
  $('#matchup-container').append($nextMatchup)
  $nextMatchup.fadeIn();
}<commit_msg>Wrap up caching logic<commit_after>// Get 5 cats, put them in the cache
// Move one up from cache
// Check if cache has 2 or fewer matchups

function renderInitialMatchup() {
  getCatQueueData().done(function() {
    renderCatQueue();
    renderNextMatchup();
  });
}

// AJAX request to fill the CATARRAY
function getCatQueueData() {
  var request = $.get({
    url: "/cats/random_cats.json"
  })
  var promise = request.then(function(data) {
    if (CATARRAY.length == 0) {
      CATARRAY = data
    } else {
      for (var i = 0; i < data.length; i++) {
        CATARRAY.push(data[i])
      }
    };
  })
  return promise
}

// Creates individual matchup divs, while removing cats from the array
function createMatchupTemplate() {
  var cat1 = CATARRAY.shift()
  var cat2 = CATARRAY.shift()
  var cats = {
    cat1: cat1,
    cat2: cat2
  }
  var html = JST['views/voting_boxes'](cats)
  var $html = $(html);
  return $html
}

// Renders matchups into a hidden div
function renderCatQueue() {
  while (CATARRAY.length > 0) {
    var $html = createMatchupTemplate()
    $('#kitty-cache').append($html)
  }
}

function renderNextMatchup() {
  var $kittyCache = $('#kitty-cache').children()
  // Refill the stock if we're on cats
  if ($kittyCache.length <= 2) {
    getCatQueueData().done(renderCatQueue)
    console.log('refilled!')
  }

  // Move kitty from cache to matchup
  $('#matchup-container').children().remove();
  var nextMatchup = $kittyCache[0]
  var $nextMatchup = $(nextMatchup).hide();
  $('#matchup-container').append($nextMatchup)
  $nextMatchup.fadeIn();
}<|endoftext|>


<commit_before>//* Event modal capture feature: capture events to a specific
// control via enyo.dispatcher.capture(inControl, inShouldForward)
// release events via enyo.dispatcher.release()
//* @protected
enyo.dispatcher.features.push(function(e) {
	var c = e.dispatchTarget;
	var wants = this.captureTarget && !this.noCaptureEvents[e.type];
	var needs = wants && !(c && c.isDescendantOf && c.isDescendantOf(this.captureTarget));
	if (needs) {
		var c1 = e.captureTarget = this.captureTarget;
		this.dispatchBubble(e, c1);
		// only prevent normal dispatch if... there is still a captureTarget after
		// dispatching to the original capture target and we're not forwarding and
		// this is not this is an auto forward event
		if (this.captureTarget && !this.autoForwardEvents[e.type] && !this.forwardEvents) {
			e.preventDispatch = true;
		}
	}
});
//
//	NOTE: This object is a plug-in; these methods should
//	be called on _enyo.dispatcher_, and not on the plug-in itself.
//
enyo.mixin(enyo.dispatcher, {
	noCaptureEvents: {load: 1, unload:1, error: 1},
	autoForwardEvents: {leave: 1, resize: 1},
	captures: [],
	//* Capture events for `inTarget` and optionally forward them
	capture: function(inTarget, inShouldForward) {
		var info = {target: inTarget, forward: inShouldForward};
		this.captures.push(info);
		this.setCaptureInfo(info);
	},
	//* Release the last captured event
	release: function() {
		this.captures.pop();
		this.setCaptureInfo(this.captures[this.captures.length-1]);
	},
	//* Set the information for a captured event
	setCaptureInfo: function(inInfo) {
		this.captureTarget = inInfo && inInfo.target;
		this.forwardEvents = inInfo && inInfo.forward;
	}
});
<commit_msg>* modal: prevent the release of capture during event processing from altering how a captured event propagates.<commit_after>//* Event modal capture feature: capture events to a specific
// control via enyo.dispatcher.capture(inControl, inShouldForward)
// release events via enyo.dispatcher.release()
//* @protected
enyo.dispatcher.features.push(function(e) {
	var c = e.dispatchTarget;
	var wants = this.captureTarget && !this.noCaptureEvents[e.type];
	var needs = wants && !(c && c.isDescendantOf && c.isDescendantOf(this.captureTarget));
	if (needs) {
		var c1 = e.captureTarget = this.captureTarget;
		// NOTE: We do not want releasing capture while an event is being processed to alter
		// the way the event propagates. Therefore decide if the event should forward
		// before the capture target receives the event (since it may release capture).
		var shouldForward = (this.autoForwardEvents[e.type] || this.forwardEvents);
		if (e.type == "tap") {
			console.log(shouldForward, this.forwardEvents);
		}
		this.dispatchBubble(e, c1);
		if (!shouldForward) {
			e.preventDispatch = true;
		}
	}
});
//
//	NOTE: This object is a plug-in; these methods should
//	be called on _enyo.dispatcher_, and not on the plug-in itself.
//
enyo.mixin(enyo.dispatcher, {
	noCaptureEvents: {load: 1, unload:1, error: 1},
	autoForwardEvents: {leave: 1, resize: 1},
	captures: [],
	//* Capture events for `inTarget` and optionally forward them
	capture: function(inTarget, inShouldForward) {
		var info = {target: inTarget, forward: inShouldForward};
		this.captures.push(info);
		this.setCaptureInfo(info);
	},
	//* Release the last captured event
	release: function() {
		this.captures.pop();
		this.setCaptureInfo(this.captures[this.captures.length-1]);
	},
	//* Set the information for a captured event
	setCaptureInfo: function(inInfo) {
		this.captureTarget = inInfo && inInfo.target;
		this.forwardEvents = inInfo && inInfo.forward;
	}
});
<|endoftext|>


<commit_before>/*!
	GET requests handler
*/

import squel from 'squel';

import {selectBy} from './queryBuilder.js';
import structureResults from './handleGet.structureResults.js';
import normalizeResponse from './handleGet.normalizeResponse.js';
import unserializeKey from './queryBuilder.unserializeKey.js';

export default function (request, body, context) {
	squel.useFlavour('mysql');

	const query = selectBy(request, context);

	return context.callQuery(query).then(([results]) => {
		let response = {};
		const status = results.length > 0 ? 200 : 404;

		let unserializedResults = [];
		results.forEach((res, i) => {
			unserializedResults.push({});
			Object.keys(res).forEach((key) => {
				unserializeKey(res, unserializedResults[unserializedResults.length - 1], key);
			})
		});

		// merges duplicates and structures the response (removes JOINs artefacts)
		response[request.main.type] = structureResults(unserializedResults, request, context);
		// if a single object was requested, return it as an object and not as a collection
		response = normalizeResponse(request.main, response);

		return {response, status};
	});
}
<commit_msg>root key of a GET response now is set to the fetched relationship, if any<commit_after>/*!
	GET requests handler
*/

import squel from 'squel';

import {selectBy} from './queryBuilder.js';
import structureResults from './handleGet.structureResults.js';
import normalizeResponse from './handleGet.normalizeResponse.js';
import unserializeKey from './queryBuilder.unserializeKey.js';

export default function (request, body, context) {
	squel.useFlavour('mysql');

	const query = selectBy(request, context);

	return context.callQuery(query).then(([results]) => {
		let response = {};
		const status = results.length > 0 ? 200 : 404;
		const root_key = request.main.relationship ? request.main.relationship.name : request.main.type;

		let unserializedResults = [];
		results.forEach((res, i) => {
			unserializedResults.push({});
			Object.keys(res).forEach((key) => {
				unserializeKey(res, unserializedResults[unserializedResults.length - 1], key);
			})
		});

		// merges duplicates and structures the response (removes JOINs artefacts)
		response[root_key] = structureResults(unserializedResults, request, context);
		// if a single object was requested, return it as an object and not as a collection
		response = normalizeResponse(request.main, response);

		return {response, status};
	});
}
<|endoftext|>


<commit_before>// Player Control

var player;
var users;
var usersUrl = 'users.json';

var onYouTubeIframeAPIReady = function() {
  player = new YT.Player('player', {
    height: '390',
    width: '640',
    playerVars: {'rel': 0},
    events: {
      'onReady': onPlayerReady,
      'onStateChange': onPlayerStateChange
    }
  });
};

var onPlayerReady = function(event) {
  console.log('YouTube Player ready.');
  getUsers();
};

var onPlayerStateChange = function(event) {
  if (event.data == YT.PlayerState.ENDED) {
    console.log('Play ended. Go next video.');
    loadVideo();
  }
};

var getUsers = function() {
  console.log('Loading users list... => ' + usersUrl);
  $.ajax({
    url: usersUrl,
    dataType: 'json',
    success: function(data) {
      console.log('Done.');
      users = data;
      loadVideo();
    },
    error: function(xhr) {
      console.log('Error: ' + xhr.status + ' ' + xhr.statusText);
      setTimeout(function() {
        console.log('Retry...');
        getUsers();
      }, 5000);
    }
  });
};

var loadVideo = function() {
  var user = shuffle(users)[0];
  var uploads = uploadsUrl(user['youtube']);
  console.log('Selected user: ' + user['name']);
  console.log('Loading uploads list... => ' + uploads);
  $.ajax({
    url: uploads,
    dataType: 'xml',
    success: function(data) {
      console.log('Done.');
      var video = parseVideo(shuffle(extractEntries(data))[0]);
      console.log('Selected video: ' + video.title);
      console.log('Loading video... => ' + video.url);
      player.loadVideoByUrl(video.url);
    },
    error: function(xhr) {
      console.log('Error: ' + xhr.status + ' ' + xhr.statusText);
      setTimeout(function() {
        console.log('Retry...');
        loadVideo();
      }, 5000);
    }
  });
};
<commit_msg>Issue #6: Add Google Analytics Event Tracking ('video', 'play')<commit_after>// Player Control

var player;
var users;
var usersUrl = 'users.json';

var onYouTubeIframeAPIReady = function() {
  player = new YT.Player('player', {
    height: '390',
    width: '640',
    playerVars: {'rel': 0},
    events: {
      'onReady': onPlayerReady,
      'onStateChange': onPlayerStateChange
    }
  });
};

var onPlayerReady = function(event) {
  console.log('YouTube Player ready.');
  getUsers();
};

var onPlayerStateChange = function(event) {
  if (event.data == YT.PlayerState.ENDED) {
    console.log('Play ended. Go next video.');
    loadVideo();
  }
};

var getUsers = function() {
  console.log('Loading users list... => ' + usersUrl);
  $.ajax({
    url: usersUrl,
    dataType: 'json',
    success: function(data) {
      console.log('Done.');
      users = data;
      loadVideo();
    },
    error: function(xhr) {
      console.log('Error: ' + xhr.status + ' ' + xhr.statusText);
      setTimeout(function() {
        console.log('Retry...');
        getUsers();
      }, 5000);
    }
  });
};

var loadVideo = function() {
  var user = shuffle(users)[0];
  var uploads = uploadsUrl(user['youtube']);
  console.log('Selected user: ' + user['name']);
  console.log('Loading uploads list... => ' + uploads);
  $.ajax({
    url: uploads,
    dataType: 'xml',
    success: function(data) {
      console.log('Done.');
      var video = parseVideo(shuffle(extractEntries(data))[0]);
      console.log('Selected video: ' + video.title);
      console.log('Loading video... => ' + video.url);
      player.loadVideoByUrl(video.url);
      ga('send', 'event', 'video', 'play');
    },
    error: function(xhr) {
      console.log('Error: ' + xhr.status + ' ' + xhr.statusText);
      setTimeout(function() {
        console.log('Retry...');
        loadVideo();
      }, 5000);
    }
  });
};
<|endoftext|>


<commit_before>var Downloader = require('../common/node/downloader')
var InputManager = require('./input')
var $ = require('cheerio');

// input handling
var inputMan = new InputManager();
var argv = inputMan.getArguments();

var logger = require('../common/node/logger')(inputMan.retrieveLoggerConfig(argv))
var downloader =  new Downloader(logger, [1000, 5000]);

function getFullUrl(el) {
  return "http://www.parliament.bg" + $(el).attr('href');
}

function scrapeBills(url, html) {
  var $content = $('table.bills', html),
      gov_id = url.match(/\d+$/g)[0],
      name = $("tr:contains('Име на законопроекта') td strong", $content).eq(0).text(),
      signature = $("tr:contains('Сигнатура') td", $content).eq(1).text(),
      session = $("tr:contains('Сесия') td", $content).eq(1).text(),
      date = $("tr:contains('Дата на постъпване') td", $content).eq(1).text(),
      rtf = $("tr:contains('Текст на законопроекта') td a:contains('RTF')", $content).attr('href'),
      importers = [],
      committees = [],
      reports = [],
      history = [];

  $("tr:contains('Вносители') a", $content).each(function(idx, el) {
    importers.push({
      link: $(el).attr("href"),
      name: $(el).text()
    });
  });

  $("tr:contains('Разпределение по комисии') li", $content).each(function(idx, el) {
    committees.push({
      link: $("a", el).attr("href"),
      name: $("a", el).text(),
      leading: $(el).text().match(/\((.*)\)$/)[1]
    });
  });

  $("tr:contains('Доклади от комисии') a", $content).each(function(idx, el) {
    reports.push($(el).attr("href"));
  });

  $("tr:contains('Хронология') li", $content).each(function(idx, el) {
    var text = $(el).text();
    var status = text.match(/\d{2}\/\d{2}\/\d{4} - (.*)/)[1];
    var date = text.match(/\d{2}\/\d{2}\/\d{4}/)[0].replace(/(\d{2})\/(\d{2})\/(\d{4})/, function(match, d, m, y) { return [y, m, d].join("-") });

    history.push({
      date: date,
      status: status
    });
  });

  console.log(JSON.stringify({
    gov_id: gov_id,
    name: name,
    date: date,
    signature: signature,
    session: session,
    importers: importers,
    committees: committees,
    reports: reports,
    history: history,
    rtf: rtf
  }));
}

function scrapeBillURLS(html) {
  $("#monthview ul.frontList li a", html).each(function(idx, el) {
    var url = getFullUrl(el)
    downloader.get(url, function(html) {
      scrapeBills(url, html);
    });
  });
}

function scrapeMonths(html) {
  $(".calendar_columns a", html).each(function(idx, el) {
    var url = getFullUrl(el)
    downloader.get(url, scrapeBillURLS);
  });
}

function init() {
  downloader.get(argv.url, scrapeMonths);
  //downloader.get("http://www.parliament.bg/bg/bills/ID/14141", function(html) { scrapeBills("http://www.parliament.bg/bg/bills/ID/14141", html) } )
}

init();

<commit_msg>Added retrieving of reports for bills fetcher.<commit_after>var Downloader = require('../common/node/downloader')
var InputManager = require('./input')
var $ = require('cheerio');
var Q = require('q');

// input handling
var inputMan = new InputManager();
var argv = inputMan.getArguments();

var logger = require('../common/node/logger')(inputMan.retrieveLoggerConfig(argv))
var downloader =  new Downloader(logger, [1000, 5000]);

function getFullUrl(pathOrElement) {
  return "http://www.parliament.bg" + (typeof pathOrElement === "string" ? pathOrElement : $(el).attr('href'));
}

function scrapeReport(url, html) {
  var text = $("#leftcontent1 .markcontent", html).text(),
      date = $('#leftcontent1 .dateclass', html).text().trim(),
      committee = $('#leftcontent1 .marktitle', html).contents()[0].data;
      console.log(date);

  return {
    url: url,
    text: text,
    date: date,
    committee: committee
  }
}

function scrapeBills(url, html) {
  var $content = $('table.bills', html),
      gov_id = url.match(/\d+$/g)[0],
      name = $("tr:contains('Име на законопроекта') td strong", $content).eq(0).text(),
      signature = $("tr:contains('Сигнатура') td", $content).eq(1).text(),
      session = $("tr:contains('Сесия') td", $content).eq(1).text(),
      date = $("tr:contains('Дата на постъпване') td", $content).eq(1).text(),
      rtf = $("tr:contains('Текст на законопроекта') td a:contains('RTF')", $content).attr('href'),
      importers = [],
      committees = [],
      reports = [],
      history = [];

  $("tr:contains('Вносители') a", $content).each(function(idx, el) {
    importers.push({
      link: $(el).attr("href"),
      name: $(el).text()
    });
  });

  $("tr:contains('Разпределение по комисии') li", $content).each(function(idx, el) {
    committees.push({
      link: $("a", el).attr("href"),
      name: $("a", el).text(),
      leading: $(el).text().match(/\((.*)\)$/)[1]
    });
  });

  $("tr:contains('Доклади от комисии') a", $content).each(function(idx, el) {
    reports.push($(el).attr("href"));
  });

  $("tr:contains('Хронология') li", $content).each(function(idx, el) {
    var text = $(el).text();
    var status = text.match(/\d{2}\/\d{2}\/\d{4} - (.*)/)[1];
    var date = text.match(/\d{2}\/\d{2}\/\d{4}/)[0].replace(/(\d{2})\/(\d{2})\/(\d{4})/, function(match, d, m, y) { return [y, m, d].join("-") });

    history.push({
      date: date,
      status: status
    });
  });

  promisedReports = reports.map(function(report_path) {
    var report_url = getFullUrl(report_path);
    return downloader.get(report_url).then(function(html) { return scrapeReport(report_url, html) },
                                           function(error) { logger.error(error) });
  });

  // when reports are fetched - assemble the final results and print to STDOUT.
  Q.all(promisedReports).done(function(results) {

    console.log(JSON.stringify({
      gov_id: gov_id,
      name: name,
      date: date,
      signature: signature,
      session: session,
      importers: importers,
      committees: committees,
      reports: results,
      history: history,
      rtf: rtf
    }));

  }, function(error) { logger.error(error) });

}

function scrapeBillURLS(html) {
  $("#monthview ul.frontList li a", html).each(function(idx, el) {
    var url = getFullUrl(el)
    downloader.get(url, function(html) {
      scrapeBills(url, html);
    });
  });
}

function scrapeMonths(html) {
  $(".calendar_columns a", html).each(function(idx, el) {
    var url = getFullUrl(el)
    downloader.get(url, scrapeBillURLS);
  });
}

function init() {
  downloader.get(argv.url, scrapeMonths);
  //downloader.get("http://www.parliament.bg/bg/bills/ID/14141", function(html) { scrapeBills("http://www.parliament.bg/bg/bills/ID/14141", html) } )
}

init();

<|endoftext|>


<commit_before>define([
  'extensions/collections/matrix'
],
function (MatrixCollection) {
  var AvailabilityCollection = MatrixCollection.extend({

    queryParams: function () {
      return {
        period: "day",
        collect: ["downtime:sum", "uptime:sum", "unmonitored:sum", "avgresponse:mean"]
      };
    },

    parse: function (response) {
      var data = response.data;
      _.each(data, function (d) {
        d.uptime = d["uptime:sum"];
        d.downtime = d["downtime:sum"];
        d.unmonitored = d["unmonitored:sum"];
        d.avgresponse = d["avgresponse:mean"];
        if (d.downtime === null && d.uptime === null) {
          d.total = null;
          d.uptimeFraction = null;
        } else {
          d.total = d.downtime + d.uptime;
          d.uptimeFraction = d.uptime / d.total;
        }
        d._end_at = this.getMoment(d._end_at);
        d._start_at = this.getMoment(d._start_at);
        d._timestamp = d._start_at;
      }, this);
      return {
        id: 'availability',
        title: 'Availability',
        values: data
      };
    },

    _getTotalUptime: function () {
      return this.at(0).get('values').reduce(function (memo, model) {
        return memo + model.get('uptime');
      }, 0);
    },

    _getTotalTime: function ( includeUnmonitored ) {
      return this.at(0).get('values').reduce(function (memo, model) {
        var res = memo + model.get('total');
        if (includeUnmonitored) {
          res += model.get('unmonitored');
        }
        return res;
      }, 0);
    },

    getFractionOfUptime: function () {
      return this._getTotalUptime() / this._getTotalTime();
    },

    getAverageResponseTime: function () {
      var values = this.at(0).get('values');
      var total = values.reduce(function (memo, model) {
        return memo + model.get('avgresponse');
      }, 0);
      if (total === 0) {
        return null;
      } else {
        return total / values.length;
      }
    }

  });

  return AvailabilityCollection;
});
<commit_msg>Fixing linting errors in the availability collection<commit_after>define([
  'extensions/collections/matrix'
],
function (MatrixCollection) {
  var AvailabilityCollection = MatrixCollection.extend({

    queryParams: function () {
      return {
        period: 'day',
        collect: ['downtime:sum', 'uptime:sum', 'unmonitored:sum', 'avgresponse:mean']
      };
    },

    parse: function (response) {
      var data = response.data;
      _.each(data, function (d) {
        d.uptime = d['uptime:sum'];
        d.downtime = d['downtime:sum'];
        d.unmonitored = d['unmonitored:sum'];
        d.avgresponse = d['avgresponse:mean'];
        if (d.downtime === null && d.uptime === null) {
          d.total = null;
          d.uptimeFraction = null;
        } else {
          d.total = d.downtime + d.uptime;
          d.uptimeFraction = d.uptime / d.total;
        }
        d._end_at = this.getMoment(d._end_at);
        d._start_at = this.getMoment(d._start_at);
        d._timestamp = d._start_at;
      }, this);
      return {
        id: 'availability',
        title: 'Availability',
        values: data
      };
    },

    _getTotalUptime: function () {
      return this.at(0).get('values').reduce(function (memo, model) {
        return memo + model.get('uptime');
      }, 0);
    },

    _getTotalTime: function (includeUnmonitored) {
      return this.at(0).get('values').reduce(function (memo, model) {
        var res = memo + model.get('total');
        if (includeUnmonitored) {
          res += model.get('unmonitored');
        }
        return res;
      }, 0);
    },

    getFractionOfUptime: function () {
      return this._getTotalUptime() / this._getTotalTime();
    },

    getAverageResponseTime: function () {
      var values = this.at(0).get('values');
      var total = values.reduce(function (memo, model) {
        return memo + model.get('avgresponse');
      }, 0);
      if (total === 0) {
        return null;
      } else {
        return total / values.length;
      }
    }

  });

  return AvailabilityCollection;
});
<|endoftext|>


<commit_before>// @flow

import * as React from "react";
import DocumentTitle from 'react-document-title';
import { createRefetchContainer, graphql } from 'react-relay/compat';
import Badge from 'app/components/shared/Badge';
// import Dropdown from "app/components/shared/Dropdown";
import Button from 'app/components/shared/Button';
import Dropdown from "../../shared/Dropdown";
import Icon from "app/components/shared/Icon";
import PageHeader from "app/components/shared/PageHeader";
import Panel from 'app/components/shared/Panel';
import RecoveryCodes from './RecoveryCodes';
import type { RelayProp } from 'react-relay';
import type { TwoFactor_viewer } from './__generated__/TwoFactor_viewer.graphql';

type Props = {
  relay: RelayProp,
  viewer: TwoFactor_viewer
};

class TwoFactor extends React.PureComponent<Props> {
  get recoveryCodesRemaining(): number | null {
    if (this.props.viewer.totp) {
      return this.props.viewer.totp.recoveryCodes.codes
        .filter(({ consumed }) => !consumed)
        .length;
    }
    return null;
  }

  componentDidMount() {
    // this.props.relay.refetch();
  }

  render() {
    return (
      <DocumentTitle title="Two-Factor Authentication">

          <PageHeader>
            <PageHeader.Icon>
              <Icon
                icon="placeholder"
                style={{ width: 34, height: 34, marginTop: 3, marginLeft: 3 }}
              />
            </PageHeader.Icon>
            <PageHeader.Title>
              Manage Two-Factor Authentication
            </PageHeader.Title>
            <PageHeader.Description>
              Manage your two-factor authentication settings.
            </PageHeader.Description>
            <PageHeader.Menu>
              <Button theme="default" outline={true} href="/user/settings">
                Back to Personal Settings
              </Button>
            </PageHeader.Menu>
          </PageHeader>
          {this.renderCurrentStatus()}

      </DocumentTitle>
    );
  }

  renderCurrentStatus() {
    return (
      <React.Fragment>
        <Panel className="mb4">
          <Panel.Header>
            Two-factor authentication is currently {this.props.viewer.totp ? 'active' : 'inactive'}
          </Panel.Header>
          <Panel.Section>

              Adding a second authentication mechanism to your account is rad! Words words words about what 2FA is etc Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quos corporis modi quo! Nostrum incidunt fugit laudantium quos rem odit, in obcaecati, ab ipsam voluptatum corrupti dicta itaque earum ipsum praesentium.

          </Panel.Section>
          <Panel.Footer>
            <Button theme="success" link="/user/two-factor/configure">
              Get Started
            </Button>
          </Panel.Footer>
        </Panel>
        <Panel className="mb4">
          <Panel.Header>
            Two-factor Authentication Methods
          </Panel.Header>
          <Panel.Section>

                  {this.props.viewer.totp ? (
                    <Badge className="ml0 mr3 bg-lime">ACTIVE</Badge>
                  ) : (
                    <Badge outline={true} className="ml0 mr3">INACTIVE</Badge>
                  )}

Authenticator Application

                  Authenticator Applications generate automatically refreshing, single use One Time
                  Passwords (OTPs). Some reliable Authenticator Applications include; 1Password, Google Authenticator,
                  and Authy.

                {this.props.viewer.totp ? (
                  <Dropdown width={270}>
                    <Button
                      theme="default"
                      outline={true}
                    >
                      Settings
                    </Button>

                      <React.Fragment>
                        <Button theme="warning" className="mx2" outline={true} link="/user/two-factor/configure">
                          Reconfigure
                        </Button>
                        <Button theme="error" outline={true} link="/user/two-factor/delete">
                          Deactivate
                        </Button>
                      </React.Fragment>

                  </Dropdown>
                ) : (
                  <Button
                    theme="success"
                    outline={true}
                    link="/user/two-factor/configure"
                  >
                  Activate
                  </Button>
                )}

          </Panel.Section>
          <Panel.Section>

                  {this.props.viewer.totp ? (
                    <Badge className="ml0 mr3 bg-lime">ACTIVE</Badge>
                  ) : (
                    <Badge outline={true} className="ml0 mr3">INACTIVE</Badge>
                  )}

Recovery Code

                  {this.props.viewer.totp ? (
                    {this.recoveryCodesRemaining} codes remaining
                  ) : null}

                  Recovery Codes are special, single use codes that allow you to regain access to your account if
                  you’re ever unable to use your configured autheticator application. They’re created when you
                  configure an Authenticator Applicaiton.

                {this.props.viewer.totp ? (
                  <Button theme="default" outline={true} disabled={true} link="/user/two-factor/configure">
                    View Codes
                    <Badge className="ml2" outline={true}>
                      {this.recoveryCodesRemaining}
                    </Badge>
                  </Button>
                ) : null}

          </Panel.Section>
        </Panel>
      </React.Fragment>
    );
  }
}

export default createRefetchContainer(
  TwoFactor,
  graphql`
    fragment TwoFactor_viewer on Viewer {
      totp {
        ...RecoveryCodes_totp

        id
        recoveryCodes {
          codes {
            code
            consumed
          }
        }
      }
    }
  `,
  graphql`
    query TwoFactorRefetchQuery {
      viewer {
        ...TwoFactor_viewer
      }
    }
  `
);
<commit_msg>Use RecoveryCodeDialog to view codes<commit_after>// @flow

import * as React from "react";
import DocumentTitle from 'react-document-title';
import { createRefetchContainer, graphql } from 'react-relay/compat';
import Badge from 'app/components/shared/Badge';
// import Dropdown from "app/components/shared/Dropdown";
import Button from 'app/components/shared/Button';
import Dropdown from "../../shared/Dropdown";
import Icon from "app/components/shared/Icon";
import PageHeader from "app/components/shared/PageHeader";
import Panel from 'app/components/shared/Panel';
import RecoveryCodes from './RecoveryCodes';
import RecoveryCodeDialog from './RecoveryCodes/RecoveryCodeDialog';
import type { RelayProp } from 'react-relay';
import type { TwoFactor_viewer } from './__generated__/TwoFactor_viewer.graphql';

type Props = {
  relay: RelayProp,
  viewer: TwoFactor_viewer
};

type State = {
  dialogOpen: boolean
};

class TwoFactor extends React.PureComponent<Props> {
  state = {
    dialogOpen: false
  };

  get recoveryCodesRemaining(): number | null {
    if (this.props.viewer.totp) {
      return this.props.viewer.totp.recoveryCodes.codes
        .filter(({ consumed }) => !consumed)
        .length;
    }
    return null;
  }

  componentDidMount() {
    // this.props.relay.refetch();
  }

  render() {
    return (
      <DocumentTitle title="Two-Factor Authentication">

          <PageHeader>
            <PageHeader.Icon>
              <Icon
                icon="placeholder"
                style={{ width: 34, height: 34, marginTop: 3, marginLeft: 3 }}
              />
            </PageHeader.Icon>
            <PageHeader.Title>
              Manage Two-Factor Authentication
            </PageHeader.Title>
            <PageHeader.Description>
              Manage your two-factor authentication settings.
            </PageHeader.Description>
            <PageHeader.Menu>
              <Button theme="default" outline={true} href="/user/settings">
                Back to Personal Settings
              </Button>
            </PageHeader.Menu>
          </PageHeader>
          {this.renderCurrentStatus()}

      </DocumentTitle>
    );
  }

  renderCurrentStatus() {
    return (
      <React.Fragment>
        <Panel className="mb4">
          <Panel.Header>
            Two-factor authentication is currently {this.props.viewer.totp ? 'active' : 'inactive'}
          </Panel.Header>
          <Panel.Section>

              Adding a second authentication mechanism to your account is rad! Words words words about what 2FA is etc Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quos corporis modi quo! Nostrum incidunt fugit laudantium quos rem odit, in obcaecati, ab ipsam voluptatum corrupti dicta itaque earum ipsum praesentium.

          </Panel.Section>
          <Panel.Footer>
            <Button theme="success" link="/user/two-factor/configure">
              Get Started
            </Button>
          </Panel.Footer>
        </Panel>
        <Panel className="mb4">
          <Panel.Header>
            Two-factor Authentication Methods
          </Panel.Header>
          <Panel.Section>

                  {this.props.viewer.totp ? (
                    <Badge className="ml0 mr3 bg-lime">ACTIVE</Badge>
                  ) : (
                    <Badge outline={true} className="ml0 mr3">INACTIVE</Badge>
                  )}

Authenticator Application

                  Authenticator Applications generate automatically refreshing, single use One Time
                  Passwords (OTPs). Some reliable Authenticator Applications include; 1Password, Google Authenticator,
                  and Authy.

                {this.props.viewer.totp ? (
                  <Dropdown width={270}>
                    <Button
                      theme="default"
                      outline={true}
                    >
                      Settings
                    </Button>

                      <React.Fragment>
                        <Button theme="warning" className="mx2" outline={true} link="/user/two-factor/configure">
                          Reconfigure
                        </Button>
                        <Button theme="error" outline={true} link="/user/two-factor/delete">
                          Deactivate
                        </Button>
                      </React.Fragment>

                  </Dropdown>
                ) : (
                  <Button
                    theme="success"
                    outline={true}
                    link="/user/two-factor/configure"
                  >
                  Activate
                  </Button>
                )}

          </Panel.Section>
          <Panel.Section>

                  {this.props.viewer.totp ? (
                    <Badge className="ml0 mr3 bg-lime">ACTIVE</Badge>
                  ) : (
                    <Badge outline={true} className="ml0 mr3">INACTIVE</Badge>
                  )}

Recovery Code

                  {this.props.viewer.totp ? (
                    {this.recoveryCodesRemaining} codes remaining
                  ) : null}

                  Recovery Codes are special, single use codes that allow you to regain access to your account if
                  you’re ever unable to use your configured autheticator application. They’re created when you
                  configure an Authenticator Applicaiton.

                <Button
                  onClick={this.handleOpenDialogClick}
                  theme="default"
                  outline={true}
                >
                  View Codes
                  <Badge className="ml2" outline={true}>
                    {this.recoveryCodesRemaining}
                  </Badge>
                </Button>
                {this.state.dialogOpen ? (
                  <RecoveryCodeDialog
                    onRequestClose={this.handleDialogClose}
                    totp={this.props.viewer.totp}
                  />
                ) : null}

          </Panel.Section>
        </Panel>
      </React.Fragment>
    );
  }

  handleOpenDialogClick = () => {
    this.setState({ dialogOpen: true });
  }

  handleDialogClose = () => {
    this.setState({ dialogOpen: false });
  }
}

export default createRefetchContainer(
  TwoFactor,
  graphql`
    fragment TwoFactor_viewer on Viewer {
      totp {
        ...RecoveryCodes_totp

        id
        recoveryCodes {
          codes {
            code
            consumed
          }
        }
      }
    }
  `,
  graphql`
    query TwoFactorRefetchQuery {
      viewer {
        ...TwoFactor_viewer
      }
    }
  `
);
<|endoftext|>


<commit_before>import { window } from 'global';

export function setCachedResults(output, performance) {
  return window._graphQLExplorerCachedResults = {
    output: output,
    performance: performance
  }
}

export function getCachedResults(query) {
  return window._graphQLExplorerCachedResults;
}
<commit_msg>Use a local variable instead of window for the resutls cache<commit_after>let cachedResults = null;

export function setCachedResults(output, performance) {
  return cachedResults = {
    output: output,
    performance: performance
  }
}

export function getCachedResults(query) {
  return cachedResults;
}
<|endoftext|>