<commit_before>// Constructeur de la classe ProcessingImage
function ProcessingImage(src) {

    this.img = new Image();
    this.img.src = src;

    var that = this;

    this.img.onload = function() {
        that.w = this.width;
        that.h = this.height;

        var canvas = document.getElementById('canvas');

        that.x = canvas.width/2 - this.width/2;
        that.y = canvas.height/2 - this.height/2;
    }
}

//Dessine l'image
ProcessingImage.prototype.draw = function(ctx) {
    var locx = this.x;
    var locy = this.y;
    ctx.drawImage(this.img,locx,locy);
}

// Determine si un point est dans l'image
ProcessingImage.prototype.contains = function(mx, my) {

  return  (this.x <= mx) && (this.x + this.w >= mx) &&
          (this.y <= my) && (this.y + this.h >= my);
}

//Constructeur de la baseline
function Baseline(lines) {
    this.lines = lines;
    this.visible = false;

}

Baseline.prototype.draw = function(ctx, image){
    if(this.visible)
    {
        for (index = 0; index < this.lines.length; index++) {
            ctx.beginPath();
            ctx.moveTo(image.x,image.y + this.lines[index]);
            ctx.lineTo(image.x + image.w,image.y + this.lines[index]);
            ctx.strokeStyle = '#2ecc71';
            ctx.stroke();
        }
    }

}

function CanvasState(canvas, image, baseline) {

    this.canvas = canvas;
    this.width = canvas.width;
    this.height = canvas.height;
    this.ctx = canvas.getContext('2d');

    this.image = image;
    this.baseline = baseline;

    this.dragging = false;

    this.scale = 1.0;

    //Coordonnées de la selection sur l'image
    this.dragoffx = 0;
    this.dragoffy = 0;

    var myState = this;

    canvas.addEventListener('selectstart', function(e) { e.preventDefault(); return false; }, false);

    canvas.addEventListener('mousedown', function(e) {

        var mouse = myState.getMouse(e);
        var mx = mouse.x;
        var my = mouse.y;
        var image = myState.image;

        if (image.contains(mx, my)) {

            myState.dragoffx = mx - image.x;
            myState.dragoffy = my - image.y;
            myState.dragging = true;
            return;
          }
    }, true);

    canvas.addEventListener('mousemove', function(e) {
        if (myState.dragging){
            var mouse = myState.getMouse(e);
            image.x = mouse.x - myState.dragoffx;
            image.y = mouse.y - myState.dragoffy;
        }
    }, true);

    canvas.addEventListener('mouseup', function(e) {
        myState.dragging = false;
    }, true);

    document.getElementById('zoom-in').addEventListener('click', function(e){
        console.log("zoom in");
        myState.scale += 0.1;
    }, true);

    document.getElementById('zoom-out').addEventListener('click', function(e){
        console.log("zoom out");
        myState.scale -= 0.1;
    }, true);

    document.getElementById('zoom-reset').addEventListener('click', function(e){
        console.log("zoom reset");
        myState.scale = 1;
    }, true);

    document.getElementById('baseline').addEventListener('change', function(e){
        if(this.checked){
            myState.baseline.visible = true;
        }
        else{
            myState.baseline.visible = false;
        }
    }, true);

    this.interval = 30;
    setInterval(function() { myState.draw(); }, myState.interval);
}

// Efface le canvas pour redessiner
CanvasState.prototype.clear = function() {
  this.ctx.clearRect(0, 0, this.width, this.height);
}

// Dessine le canvas avec ces éléments
CanvasState.prototype.draw = function() {
  if (!this.valid) {
    var ctx = this.ctx;

    var newWidth = this.width * this.scale;
    var newHeight = this.height * this.scale;

    this.clear();

    ctx.save();

    ctx.translate(-((newWidth-this.width)/2), -((newHeight-this.height)/2));
    ctx.scale(this.scale, this.scale);

    this.image.draw(ctx);
    this.baseline.draw(ctx, this.image);
    ctx.restore();

  }
}

// Retourne les coordonnées de la souris
CanvasState.prototype.getMouse = function(e) {
    var rect = this.canvas.getBoundingClientRect();
    mx = Math.floor((e.clientX-rect.left)/(rect.right-rect.left)*this.canvas.width);
    my = Math.floor((e.clientY-rect.top)/(rect.bottom-rect.top)*this.canvas.height);
    return {x: mx, y: my};
}

CanvasState.prototype.zoom = function(e){

        var pt = this.canvas.transformedPoint(lastX,lastY);
        ctx.translate(pt.x,pt.y);
        var factor = Math.pow(scaleFactor,clicks);
        ctx.scale(factor,factor);
        ctx.translate(-pt.x,-pt.y);
        redraw();
}

function init(src) {
    var image = new ProcessingImage(src);
    var baseline = new Baseline([33, 94, 155]);
    var s = new CanvasState(document.getElementById('canvas'), image, baseline);
}<commit_msg>bug deplacement en zoom resolue<commit_after>// Constructeur de la classe ProcessingImage
function ProcessingImage(src) {

    this.img = new Image();
    this.img.src = src;

    var that = this;

    this.img.onload = function() {
        that.w = this.width;
        that.h = this.height;

        var canvas = document.getElementById('canvas');

        that.x = canvas.width/2 - this.width/2;
        that.y = canvas.height/2 - this.height/2;
    }
}

//Dessine l'image
ProcessingImage.prototype.draw = function(ctx) {
    var locx = this.x;
    var locy = this.y;
    ctx.drawImage(this.img,locx,locy);
}

// Determine si un point est dans l'image
ProcessingImage.prototype.contains = function(mx, my) {

  return  (this.x <= mx) && (this.x + this.w >= mx) &&
          (this.y <= my) && (this.y + this.h >= my);
}

//Constructeur de la baseline
function Baseline(lines) {
    this.lines = lines;
    this.visible = false;

}

Baseline.prototype.draw = function(ctx, image){
    if(this.visible)
    {
        for (index = 0; index < this.lines.length; index++) {
            ctx.beginPath();
            ctx.moveTo(image.x,image.y + this.lines[index]);
            ctx.lineTo(image.x + image.w,image.y + this.lines[index]);
            ctx.strokeStyle = '#2ecc71';
            ctx.stroke();
        }
    }

}

function CanvasState(canvas, image, baseline) {

    this.canvas = canvas;
    this.width = canvas.width;
    this.height = canvas.height;
    this.ctx = canvas.getContext('2d');

    this.image = image;
    this.baseline = baseline;

    this.dragging = false;

    this.scale = 1.0;

    //Coordonnées de la selection sur l'image
    this.dragoffx = 0;
    this.dragoffy = 0;

    var myState = this;

    canvas.addEventListener('selectstart', function(e) { e.preventDefault(); return false; }, false);

    canvas.addEventListener('mousedown', function(e) {

        var mouse = myState.getMouse(e);
        var mx = mouse.x;
        var my = mouse.y;
        var image = myState.image;

        if (image.contains(mx, my)) {

            myState.dragoffx = mx - image.x;
            myState.dragoffy = my - image.y;
            myState.dragging = true;
            return;
          }
    }, true);

    canvas.addEventListener('mousemove', function(e) {
        if (myState.dragging){
            var mouse = myState.getMouse(e);
            image.x = mouse.x - myState.dragoffx;
            image.y = mouse.y - myState.dragoffy;
        }
    }, true);

    canvas.addEventListener('mouseup', function(e) {
        myState.dragging = false;
    }, true);

    document.getElementById('zoom-in').addEventListener('click', function(e){
        console.log("zoom in");
        myState.scale += 0.1;
    }, true);

    document.getElementById('zoom-out').addEventListener('click', function(e){
        console.log("zoom out");
        myState.scale -= 0.1;
    }, true);

    document.getElementById('zoom-reset').addEventListener('click', function(e){
        console.log("zoom reset");
        myState.scale = 1;
    }, true);

    document.getElementById('baseline').addEventListener('change', function(e){
        if(this.checked){
            myState.baseline.visible = true;
        }
        else{
            myState.baseline.visible = false;
        }
    }, true);

    this.interval = 30;
    setInterval(function() { myState.draw(); }, myState.interval);
}

// Efface le canvas pour redessiner
CanvasState.prototype.clear = function() {
  this.ctx.clearRect(0, 0, this.width, this.height);
}

// Dessine le canvas avec ces éléments
CanvasState.prototype.draw = function() {
  if (!this.valid) {
    var ctx = this.ctx;

    var newWidth = this.width * this.scale;
    var newHeight = this.height * this.scale;

    this.clear();

    ctx.save();

    ctx.translate(-((newWidth-this.width)/2), -((newHeight-this.height)/2));
    ctx.scale(this.scale, this.scale);

    this.image.draw(ctx);
    this.baseline.draw(ctx, this.image);
    ctx.restore();

  }
}

// Retourne les coordonnées de la souris
CanvasState.prototype.getMouse = function(e) {
    var rect = this.canvas.getBoundingClientRect();
    mx = Math.floor((e.clientX-rect.left)/(rect.right-rect.left)*this.canvas.width) / this.scale;
    my = Math.floor((e.clientY-rect.top)/(rect.bottom-rect.top)*this.canvas.height) / this.scale;
    return {x: mx, y: my};
}

CanvasState.prototype.zoom = function(e){

        var pt = this.canvas.transformedPoint(lastX,lastY);
        ctx.translate(pt.x,pt.y);
        var factor = Math.pow(scaleFactor,clicks);
        ctx.scale(factor,factor);
        ctx.translate(-pt.x,-pt.y);
        redraw();
}

function init(src) {
    var image = new ProcessingImage(src);
    var baseline = new Baseline([33, 94, 155]);
    var s = new CanvasState(document.getElementById('canvas'), image, baseline);
}<|endoftext|>


<commit_before>"use strict"

const title = document.getElementById("title")
const msg = document.getElementById("msg")
const msg2 = document.getElementById("msg2")
const form = document.getElementById("form")
const input = document.getElementById("input")

const onePrep = e => {
    e.preventDefault()
    if (input.value.trim() === "") {
        msg2.textContent = "that can't be empty."
        return
    }
    one(input.value)
}

const one = question => {
    input.value = ""
    msg.textContent = `what are some factors that affect '${question}'?`
    msg2.textContent = "they should also be yes/no, and separated with commas."
    form.onsubmit = twoPrep(question)
}

const twoPrep = question => e => {
    e.preventDefault()
    if (input.value.trim() === "") {
        msg2.textContent = "that can't be empty."
        return
    }
    const factors = input.value.split(",").map(x => x.trim())
    if (factors.find(x => x === "") !== undefined) {
        msg2.textContent = "you can't have an empty factor."
        return
    }
    if (factors.length > 7) {
        msg2.textContent = "you can't have more than 7 factors."
        return
    }
    two(question, factors)
}

const isGreen = x => x.className === "green"
const addRow = n => isCalculated => () => {
    const row = document.createElement("div")
    for (let i = 0; i < n; i++) {
        const el = document.createElement("span")
        row.appendChild(el)
        if (isCalculated && i === n - 1) {
            el.className = "gray"
            el.textContent = "?"
            continue
        }
        el.className = "green"
        el.textContent = "y"
        el.onclick = () => {
            const ig = isGreen(el)
            el.className = ig ? "red" : "green"
            el.textContent = ig ? "n" : "y"
        }
    }
    form.insertBefore(row, form.lastChild)
    return row
}

const two = (question, factors) => {
    input.remove()
    msg.textContent = "enter some data."
    msg2.textContent = "click to add rows and switch between yes/no."

    const header = document.createElement("div")
    let el

    for (const x of factors) {
        el = document.createElement("span")
        el.textContent = x
        el.className = "blue"
        header.appendChild(el)
    }

    el = document.createElement("span")
    el.textContent = question
    el.className = "cyan"
    header.appendChild(el)

    form.appendChild(header)

    const footer = document.createElement("div")

    const addRowBtn = document.createElement("span")
    addRowBtn.textContent = "add datapoint"
    addRowBtn.className = "gray"
    const thisAddRow = addRow(factors.length + 1)
    addRowBtn.onclick = thisAddRow(false)

    const trainBtn = document.createElement("span")
    trainBtn.textContent = "train"
    trainBtn.className = "yellow"
    trainBtn.onclick = threePrep(thisAddRow, addRowBtn, trainBtn)

    footer.appendChild(addRowBtn)
    footer.appendChild(trainBtn)
    form.appendChild(footer)
}

const toData = x => isGreen(x) ? 1 : 0
const threePrep = (thisAddRow, addRowBtn, trainBtn) => e => {
    e.preventDefault()
    // a gross hack
    // it would be better to use one of those fancy front-end libraries with
    // two-way binding and whatnot
    const fc = form.children
    const max = fc.length - 1
    const data = []
    const results = []
    // skip the header and footer
    for (let i = 1; i < max; i++) {
        fc[i].className = "grayed"
        const elems = fc[i].children
        const max = elems.length - 1
        const ary = []
        for (let j = 0; j < max; j++) {
            elems[j].onclick = null
            ary.push(toData(elems[j]))
        }
        elems[max].onclick = null
        data.push(ary)
        results.push(toData(elems[max]))
    }
    three(fetch("/train", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({d: data, r: results})
    }).then(x => x.json()), thisAddRow, addRowBtn, trainBtn)
}

const three = (train, thisAddRow, addRowBtn, calcBtn) => {
    msg.textContent = "now add some data for which you don't know the answer."
    msg2.textContent = "use the calculate button to make an educated guess."
    const pending = []
    calcBtn.textContent = "calculate"
    calcBtn.onclick = () => {
        while (pending.length !== 0) {
            const p = pending.pop()
            p.className = "grayed"
            const data = []
            const elems = p.children
            const max = elems.length - 1
            for (let j = 0; j < max; j++) {
                elems[j].onclick = null
                data.push(toData(elems[j]))
            }
            p.lastChild.textContent = "..."
            train.then(({s0, s1}) => {
                fetch("/get", {
                    method: "POST",
                    headers: { "Content-Type": "application/json" },
                    body: JSON.stringify({d: data, s0, s1})
                })
                .then(x => x.json())
                .then(({r}) => {
                    p.lastChild.className = r > 0.5 ? "green" : "red"
                    p.lastChild.textContent = r.toFixed(4)
                })
            })
        }
    }
    thisAddRow = thisAddRow(true)
    addRowBtn.onclick = () => {
        pending.push(thisAddRow())
    }
}

title.textContent = "Stairwell"
msg.textContent = "what is your question for today?"
msg2.textContent = "it should be a yes/no question."
input.focus()
form.onsubmit = onePrep
form.style.display = "block"
<commit_msg>scroll to bottom<commit_after>"use strict"

const title = document.getElementById("title")
const msg = document.getElementById("msg")
const msg2 = document.getElementById("msg2")
const form = document.getElementById("form")
const input = document.getElementById("input")

const onePrep = e => {
    e.preventDefault()
    if (input.value.trim() === "") {
        msg2.textContent = "that can't be empty."
        return
    }
    one(input.value)
}

const one = question => {
    input.value = ""
    msg.textContent = `what are some factors that affect '${question}'?`
    msg2.textContent = "they should also be yes/no, and separated with commas."
    form.onsubmit = twoPrep(question)
}

const twoPrep = question => e => {
    e.preventDefault()
    if (input.value.trim() === "") {
        msg2.textContent = "that can't be empty."
        return
    }
    const factors = input.value.split(",").map(x => x.trim())
    if (factors.find(x => x === "") !== undefined) {
        msg2.textContent = "you can't have an empty factor."
        return
    }
    if (factors.length > 7) {
        msg2.textContent = "you can't have more than 7 factors."
        return
    }
    two(question, factors)
}

const isGreen = x => x.className === "green"
const addRow = n => isCalculated => () => {
    window.scrollTo(0, document.body.scrollHeight)
    const row = document.createElement("div")
    for (let i = 0; i < n; i++) {
        const el = document.createElement("span")
        row.appendChild(el)
        if (isCalculated && i === n - 1) {
            el.className = "gray"
            el.textContent = "?"
            continue
        }
        el.className = "green"
        el.textContent = "y"
        el.onclick = () => {
            const ig = isGreen(el)
            el.className = ig ? "red" : "green"
            el.textContent = ig ? "n" : "y"
        }
    }
    form.insertBefore(row, form.lastChild)
    return row
}

const two = (question, factors) => {
    input.remove()
    msg.textContent = "enter some data."
    msg2.textContent = "click to add rows and switch between yes/no."

    const header = document.createElement("div")
    let el

    for (const x of factors) {
        el = document.createElement("span")
        el.textContent = x
        el.className = "blue"
        header.appendChild(el)
    }

    el = document.createElement("span")
    el.textContent = question
    el.className = "cyan"
    header.appendChild(el)

    form.appendChild(header)

    const footer = document.createElement("div")

    const addRowBtn = document.createElement("span")
    addRowBtn.textContent = "add datapoint"
    addRowBtn.className = "gray"
    const thisAddRow = addRow(factors.length + 1)
    addRowBtn.onclick = thisAddRow(false)

    const trainBtn = document.createElement("span")
    trainBtn.textContent = "train"
    trainBtn.className = "yellow"
    trainBtn.onclick = threePrep(thisAddRow, addRowBtn, trainBtn)

    footer.appendChild(addRowBtn)
    footer.appendChild(trainBtn)
    form.appendChild(footer)
}

const toData = x => isGreen(x) ? 1 : 0
const threePrep = (thisAddRow, addRowBtn, trainBtn) => e => {
    e.preventDefault()
    // a gross hack
    // it would be better to use one of those fancy front-end libraries with
    // two-way binding and whatnot
    const fc = form.children
    const max = fc.length - 1
    const data = []
    const results = []
    // skip the header and footer
    for (let i = 1; i < max; i++) {
        fc[i].className = "grayed"
        const elems = fc[i].children
        const max = elems.length - 1
        const ary = []
        for (let j = 0; j < max; j++) {
            elems[j].onclick = null
            ary.push(toData(elems[j]))
        }
        elems[max].onclick = null
        data.push(ary)
        results.push(toData(elems[max]))
    }
    three(fetch("/train", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({d: data, r: results})
    }).then(x => x.json()), thisAddRow, addRowBtn, trainBtn)
}

const three = (train, thisAddRow, addRowBtn, calcBtn) => {
    msg.textContent = "now add some data for which you don't know the answer."
    msg2.textContent = "use the calculate button to make an educated guess."
    const pending = []
    calcBtn.textContent = "calculate"
    calcBtn.onclick = () => {
        while (pending.length !== 0) {
            const p = pending.pop()
            p.className = "grayed"
            const data = []
            const elems = p.children
            const max = elems.length - 1
            for (let j = 0; j < max; j++) {
                elems[j].onclick = null
                data.push(toData(elems[j]))
            }
            p.lastChild.textContent = "..."
            train.then(({s0, s1}) => {
                fetch("/get", {
                    method: "POST",
                    headers: { "Content-Type": "application/json" },
                    body: JSON.stringify({d: data, s0, s1})
                })
                .then(x => x.json())
                .then(({r}) => {
                    p.lastChild.className = r > 0.5 ? "green" : "red"
                    p.lastChild.textContent = r.toFixed(4)
                })
            })
        }
    }
    thisAddRow = thisAddRow(true)
    addRowBtn.onclick = () => {
        pending.push(thisAddRow())
    }
}

title.textContent = "Stairwell"
msg.textContent = "what is your question for today?"
msg2.textContent = "it should be a yes/no question."
input.focus()
form.onsubmit = onePrep
form.style.display = "block"
<|endoftext|>


<commit_before>/**
* Wrapper on top of the Document object model javascript API,
*   to make our life easier when we need to interact with such API in our tests
*
* @constructor VirtualDom
*/
window.getJasmineRequireObj().VirtualDom = function () {
    var oldDocument,

    isAlreadyStubbed = function (el) {
        return el.events;
    },

    stubElement = function (el) {
        var original = el.addEventListener;

        el.events = {};
        el.addEventListener = function (name, listener) {
            if (this.events[name]) {
                this.events[name].push(listener);
            } else {
                this.events[name] = [listener];
            }

            original.call(this, name, listener);
        };

        return el;
    },

    processElement = function (el) {
        if (!isAlreadyStubbed.call(this, el)) {
            return stubElement.call(this, el);
        }

        return el;
    },

    processElements = function (elements) {
        var i,
            length = elements.length;

        for (i = 0; i < length; i++) {
            processElement.call(this, elements[i]);
        }

        return elements;
    },

    getElementById = function (parent, id) {
        var children = parent.childNodes,
            child,
            result,
            i;

        for (i = 0; i < children.length; i++) {
            child = children[i];

            if (child.id === id) {
                return child;
            }

            result = getElementById.call(this, child, id);

            if (result) {
                return result;
            }
        }

        return;
    },

    getSingleElement = function (el) {
        return el ? processElement.call(this, el) : null;
    },

    isAlreadyInstalled = function () {
        return !!oldDocument;
    },

    copyObjectFrom = function (source) {
        var result = {},
            property;

        /* jshint forin: false */
        for (property in source) {
            result[property] = source[property];
        }
        /* jshint forin: true */

        return result;
    },

    merge = function (target, source) {
        var result = target,
            property;

        for (property in source) {
            if (source.hasOwnProperty(property)) {
                result[property] = source[property];
            }
        }

        return result;
    },

    onEventTriggered = function (e) {
        e.preventDefault();

        e.target.removeEventListener(e.type, onEventTriggered);
    },

    shouldEventBubble = function (element) {
        return element.parentElement !== null && element.parentElement !== undefined;
    },

    callListeners = function (element, eventObject) {
        var i;

        if (element.events && element.events[eventObject.type]) {
            for (i = 0; i < element.events[eventObject.type].length; i++) {
                element.events[eventObject.type][i].call(element, merge.call(this, eventObject, {
                    currentTarget: element
                }));
            }
        }
    },

    dispatchEvent = function (element, eventObject) {
        callListeners.call(this, element, eventObject);

        if (shouldEventBubble.call(this, element)) {
            dispatchEvent.call(this, element.parentElement, eventObject);
        }
    },

    prepareEvent = function (eventObject, element, config) {
        var eventCopy = merge.call(this, copyObjectFrom.call(this, eventObject), config);

        return merge.call(this, eventCopy, {
            target: element,
            srcElement: element,
            toElement: element
        });
    },

    prepareDocument = function (dom) {
        var me = this,
            docCreateElementBackup = document.createElement;

        oldDocument = {
            getElementsByTagName: document.getElementsByTagName,
            getElementById: document.getElementById,
            querySelector: document.querySelector,
            querySelectorAll: document.querySelectorAll,
            getElementsByClassName: document.getElementsByClassName,
            addEventListener: document.addEventListener
        };

        document.createElement = function () {
            if (!oldDocument) {
                this.createElement = docCreateElementBackup;
                return this.createElement.apply(this, arguments);
            } else {
                return processElement.call(me, docCreateElementBackup.apply(this, arguments));
            }
        };

        document.getElementsByTagName = function (tagName) {
            if (tagName.toLowerCase() === 'html') {
                // This array could lead to problems
                return processElements.call(me, [dom]);
            }
            return processElements.call(me, dom.getElementsByTagName(tagName));
        };
        document.getElementById = function (id) {
            return getSingleElement.call(me, getElementById.call(me, dom, id));
        };
        document.getElementsByClassName = function (className) {
            return processElements.call(me, dom.getElementsByClassName(className));
        };
        document.querySelector = function (selector) {
            return getSingleElement.call(me, dom.querySelector(selector));
        };
        document.querySelectorAll = function (selector) {
            return processElements.call(me, dom.querySelectorAll(selector));
        };

        // Object.defineProperty(document, 'body', {
        //     get: function () {
        //         return this.getElementsByTagName('body')[0];
        //     },
        //     configurable: true
        // });

        // Object.defineProperty(document, 'head', {
        //     get: function () {
        //         return this.getElementsByTagName('head')[0];
        //     },
        //     configurable: true
        // });

        processElement.call(this, document);
    };

    /**
    * This method will override the document API to use the virtual one, instead of the real one.
    *
    * @param {String} [body] HTML template to be added into the virtual dom when installing it
    * @memberof VirtualDom
    */
    this.install = function (body) {
        var dom;

        if (isAlreadyInstalled.call(this)) {
            throw 'Virtual dom already installed';
        }

        dom = document.createElement('html');
        dom.innerHTML = body ? body : '';

        prepareDocument.call(this, dom);
    };

    /**
    * @memberof VirtualDom
    */
    this.uninstall = function () {
        var method;

        for (method in oldDocument) {
            if (oldDocument.hasOwnProperty(method)) {
                document[method] = oldDocument[method];
            }
        }

        delete document.events;
        oldDocument = null;
    };

    /**
    * Trigger any kind of event from any element, native or custom events
    * @param {Object} element Dom Element
    * @param {String} event Event name
    * @param {Object} config parameters to be added to the event object
    * @memberof VirtualDom
    */
    this.trigger = function (element, event, config) {
        var eventObject = new Event(event, {
            bubbles: true,
            cancelable: true
        }),
        preventBackup = eventObject.preventDefault;

        spyOn(eventObject, 'preventDefault').and.callFake(function () {
            preventBackup.call(eventObject);
        });
        element.addEventListener(event, onEventTriggered);

        dispatchEvent.call(this, element, prepareEvent.call(this, eventObject, element, config));

        return eventObject.preventDefault.calls.count() === 1;
    };

    /**
    * Uninstall and install the virtual dom with a new html
    * @param {String} [body] HTML template to be added into the virtual dom when installing it
    * @memberof VirtualDom
    */
    this.resetDom = function (body) {
        this.uninstall();
        this.install(body);
    };
};

(function () {
    var require = window.getJasmineRequireObj();
    window.jasmine.virtualDom = new require.VirtualDom();
})();
<commit_msg>More clean up<commit_after>/**
* Wrapper on top of the Document object model javascript API,
*   to make our life easier when we need to interact with such API in our tests
*
* @constructor VirtualDom
*/
window.getJasmineRequireObj().VirtualDom = function () {
    var oldDocument,

    isAlreadyStubbed = function (el) {
        return el.events;
    },

    stubElement = function (el) {
        var original = el.addEventListener;

        el.events = {};
        el.addEventListener = function (name, listener) {
            if (this.events[name]) {
                this.events[name].push(listener);
            } else {
                this.events[name] = [listener];
            }

            original.call(this, name, listener);
        };

        return el;
    },

    processElement = function (el) {
        if (!isAlreadyStubbed.call(this, el)) {
            return stubElement.call(this, el);
        }

        return el;
    },

    processElements = function (elements) {
        var i,
            length = elements.length;

        for (i = 0; i < length; i++) {
            processElement.call(this, elements[i]);
        }

        return elements;
    },

    getElementById = function (parent, id) {
        var children = parent.childNodes,
            child,
            result,
            i;

        for (i = 0; i < children.length; i++) {
            child = children[i];

            if (child.id === id) {
                return child;
            }

            result = getElementById.call(this, child, id);

            if (result) {
                return result;
            }
        }

        return;
    },

    getSingleElement = function (el) {
        return el ? processElement.call(this, el) : null;
    },

    isAlreadyInstalled = function () {
        return !!oldDocument;
    },

    copyObjectFrom = function (source) {
        var result = {},
            property;

        /* jshint forin: false */
        for (property in source) {
            result[property] = source[property];
        }
        /* jshint forin: true */

        return result;
    },

    merge = function (target, source) {
        var result = target,
            property;

        for (property in source) {
            if (source.hasOwnProperty(property)) {
                result[property] = source[property];
            }
        }

        return result;
    },

    onEventTriggered = function (e) {
        e.preventDefault();

        e.target.removeEventListener(e.type, onEventTriggered);
    },

    shouldEventBubble = function (element) {
        return element.parentElement !== null && element.parentElement !== undefined;
    },

    hasListeners = function (element, event) {
        return element.events && element.events[event];
    },

    callListeners = function (element, eventObject) {
        var i,
            listeners = element.events[eventObject.type];

        for (i = 0; i < listeners.length; i++) {
            listeners[i].call(element, merge.call(this, eventObject, {
                currentTarget: element
            }));
        }
    },

    dispatchEvent = function (element, eventObject) {
        if (hasListeners.call(this, element, eventObject.type)) {
            callListeners.call(this, element, eventObject);
        }

        if (shouldEventBubble.call(this, element)) {
            dispatchEvent.call(this, element.parentElement, eventObject);
        }
    },

    prepareEvent = function (eventObject, element, config) {
        var eventCopy = merge.call(this, copyObjectFrom.call(this, eventObject), config);

        return merge.call(this, eventCopy, {
            target: element,
            srcElement: element,
            toElement: element
        });
    },

    stubDomApi = function (dom) {
        var me = this,
            docCreateElementBackup = document.createElement;

        oldDocument = {
            getElementsByTagName: document.getElementsByTagName,
            getElementById: document.getElementById,
            querySelector: document.querySelector,
            querySelectorAll: document.querySelectorAll,
            getElementsByClassName: document.getElementsByClassName,
            addEventListener: document.addEventListener
        };

        document.createElement = function () {
            // when this method is spied in the specs there is a conflic because
            // the spies are set back after the virtual dom is set back
            if (!oldDocument) {
                this.createElement = docCreateElementBackup;
                return this.createElement.apply(this, arguments);
            } else {
                return processElement.call(me, docCreateElementBackup.apply(this, arguments));
            }
        };

        document.getElementsByTagName = function (tagName) {
            if (tagName.toLowerCase() === 'html') {
                // This array could lead to problems
                return processElements.call(me, [dom]);
            }
            return processElements.call(me, dom.getElementsByTagName(tagName));
        };
        document.getElementById = function (id) {
            return getSingleElement.call(me, getElementById.call(me, dom, id));
        };
        document.getElementsByClassName = function (className) {
            return processElements.call(me, dom.getElementsByClassName(className));
        };
        document.querySelector = function (selector) {
            return getSingleElement.call(me, dom.querySelector(selector));
        };
        document.querySelectorAll = function (selector) {
            return processElements.call(me, dom.querySelectorAll(selector));
        };

        // Object.defineProperty(document, 'body', {
        //     get: function () {
        //         return this.getElementsByTagName('body')[0];
        //     },
        //     configurable: true
        // });

        // Object.defineProperty(document, 'head', {
        //     get: function () {
        //         return this.getElementsByTagName('head')[0];
        //     },
        //     configurable: true
        // });

        processElement.call(this, document);
    };

    /**
    * This method will override the document API to use the virtual one, instead of the real one.
    *
    * @param {String} [body] HTML template to be added into the virtual dom when installing it
    * @memberof VirtualDom
    */
    this.install = function (body) {
        var dom;

        if (isAlreadyInstalled.call(this)) {
            throw 'Virtual dom already installed';
        }

        dom = document.createElement('html');
        dom.innerHTML = body ? body : '';

        stubDomApi.call(this, dom);
    };

    /**
    * @memberof VirtualDom
    */
    this.uninstall = function () {
        var method;

        for (method in oldDocument) {
            if (oldDocument.hasOwnProperty(method)) {
                document[method] = oldDocument[method];
            }
        }

        delete document.events;
        oldDocument = null;
    };

    /**
    * Trigger any kind of event from any element, native or custom events
    * @param {Object} element Dom Element
    * @param {String} event Event name
    * @param {Object} config parameters to be added to the event object
    * @memberof VirtualDom
    */
    this.trigger = function (element, event, config) {
        var eventObject = new Event(event, {
            bubbles: true,
            cancelable: true
        }),
        preventBackup = eventObject.preventDefault;

        spyOn(eventObject, 'preventDefault').and.callFake(function () {
            preventBackup.call(eventObject);
        });
        element.addEventListener(event, onEventTriggered);

        dispatchEvent.call(this, element, prepareEvent.call(this, eventObject, element, config));

        return eventObject.preventDefault.calls.count() === 1;
    };

    /**
    * Uninstall and install the virtual dom with a new html
    * @param {String} [body] HTML template to be added into the virtual dom when installing it
    * @memberof VirtualDom
    */
    this.resetDom = function (body) {
        this.uninstall();
        this.install(body);
    };
};

(function () {
    var require = window.getJasmineRequireObj();
    window.jasmine.virtualDom = new require.VirtualDom();
})();
<|endoftext|>


<commit_before>(function() {

	/* Views
	*******************/

	// Available as F.ListComponent.prototype.View
	var ListView = F.View.extend({
		tagName: 'ul',

		initialize: function(options) {
			options = options || {};

			// Clumsy backbone way of calling parent class' constructor
			F.View.prototype.initialize.apply(this, arguments);

			this.collection = options.collection;
			this.ItemView = options.ItemView || this.ItemView;
			this.ItemTemplate = options.ItemTemplate || this.ItemTemplate;

			// Views array for subviews
			this.subViews = [];

			// Clumsy backbone way of permabinding
			this.addSubView = this.addSubView.bind(this);
		},

		addSubView: function(model) {
			// Create view
			var view = new this.ItemView({
				model: model,
				template: this.ItemTemplate,
				component: this.component
			});
			view.render();

			// Add the list item to the List
			this.$el.append(view.el);

			// Store the position in the views array
			// Don't store the actual view to prevent circular references
			view.$el.data('viewIndex', this.subViews.length);

			// Store in views array for removal later
			this.subViews.push(view);
		},

		remove: function() {
			this.removeSubViews();

			F.View.prototype.remove.call(this, arguments);
		},

		removeSubView: function(modelOrViewIndex) {
			var view = null;
			var viewIndex = -1;
			if (typeof viewIndex != 'Number') {
				_.some(this.subViews, function(tmpView, index) {
					if (tmpView && tmpView.model === modelOrViewIndex) {
						view = tmpView;
						viewIndex = index;
					}
				}.bind(this));
			}
			else // get from view index
				view = this.subViews[viewIndex];

			if (view) {
				view.remove();
				this.subViews[viewIndex] = undefined;
			}
		},

		removeSubViews: function() {
			if (this.subViews.length) {
				_.each(this.subViews, function(view) {
					view.remove();
				});

				this.subViews = [];
			}
		},

		render: function() {
			if (F.options.debug) {
				console.log('%s: rendering list view...', this.component && this.component.toString() || 'List view');
			}

			if (this.parent && !$(this.el.parentNode).is(this.parent))
				$(this.parent).append(this.el);

			// Remove previous views from the DOM
			this.removeSubViews();

			// Add and render each list item
			this.collection.each(this.addSubView);

			// Store the last time this view was rendered
			this.rendered = new Date().getTime();

			this.trigger('renderComplete');

			return this;
		}
	});

	// Available as F.ListComponent.prototype.ItemView
	var ItemView = F.View.extend({
		tagName: 'li',
		className: 'listItem'
	});

	/* Component
	*******************/
	F.ListComponent = new Class(/** @lends F.ListComponent# */{
		toString: 'ListComponent',
		extend: F.CollectionComponent,

		/**
		 * A component that can load and render a collection as a list
		 *
		 * @constructs
		 * @extends F.CollectionComponent
		 *
		 * @param {Object} options							Options for this component and its view. Options not listed below will be passed to the view.
		 * @param {Backbone.Collection} options.Collection	The collection class this list will be rendered from
		 * @param {Backbone.View} options.ListView			The view class this list will be rendered with
		 * @param {Template} [options.ListTemplate]			The template this list will be rendered with. Renders to a UL tag by default
		 * @param {Backbone.View} options.ItemView			The view that individual items will be rendered with
		 * @param {Template} options.ItemTemplate			The template that individual items will be rendered with
		 *
		 * @property {Backbone.Collection} Collection	The collection class this list will be rendered from
		 * @property {Backbone.View} ListView			The view class this list will be rendered with
		 * @property {Template} ListTemplate			The template this list will be rendered with. Renders to a UL tag by default
		 * @property {Backbone.View} ItemView			The view that individual items will be rendered with
		 * @property {Template} ItemTemplate			The template that individual items will be rendered with
		 */
		construct: function(options) {
			// Set object properties from options object, removing them from the object thereafter
			this.setPropsFromOptions(options, [
				'Collection',
				'ListTemplate',
				'ListView',
				'ItemTemplate',
				'ItemView'
			]);

			this.view = new this.ListView(_.extend({
				component: this, // pass this as component so ItemView can trigger handleSelect if it likes
				collection: this.collection,
				ItemView: this.ItemView,
				ItemTemplate: this.ItemTemplate,
				events: {
					'click li': 'handleSelect'
				}
			}, options));

			this.selectedItem = null;
		},

		Collection: Backbone.Collection, // Collection component expects to have prototype.Collection or options.Collection

		ListTemplate: null,
		ListView: ListView,

		ItemTemplate: null,
		ItemView: ItemView,

		addModel: function(model) {
			// Add a subview for this model
			this.view.addSubView(model);
		},

		removeModel: function(model) {
			// Add a subview for this model
			this.view.removeSubView(model);
		},

		/**
		 * Get the model associated with a list item
		 *
		 * @param {Node}	Node or jQuery Object to get model from
		 *
		 * @returns {Backbone.Model}	The model associated with the passed DOM element
		 */
		getModelFromLi: function(listItem) {
			return this.view.subViews[$(listItem).data('viewIndex')].model;
		},

		/**
		 * Get the view associated with a list item
		 *
		 * @param {Node}	Node or jQuery Object to get model from
		 *
		 * @returns {Backbone.View}	The view associated with the passed DOM element
		 */
		getViewFromLi: function(listItem) {
			return this.view.subViews[$(listItem).data('viewIndex')];
		},

		/**
		 * Handles item selection events
		 *
		 * @param {Event} evt	The jQuery event object
		 */
		handleSelect: function(evt) {
			// Get model from DOM el's data
			var model = this.getModelFromLi(evt.currentTarget);

			// Store ID of selected item
			this.selectedItem = model.id;

			this.trigger('itemSelected', {
				listItem: $(evt.currentTarget),
				model: model
			});
		}
	});
}());
<commit_msg>Triple equals for comparisons<commit_after>(function() {

	/* Views
	*******************/

	// Available as F.ListComponent.prototype.View
	var ListView = F.View.extend({
		tagName: 'ul',

		initialize: function(options) {
			options = options || {};

			// Clumsy backbone way of calling parent class' constructor
			F.View.prototype.initialize.apply(this, arguments);

			this.collection = options.collection;
			this.ItemView = options.ItemView || this.ItemView;
			this.ItemTemplate = options.ItemTemplate || this.ItemTemplate;

			// Views array for subviews
			this.subViews = [];

			// Clumsy backbone way of permabinding
			this.addSubView = this.addSubView.bind(this);
		},

		addSubView: function(model) {
			// Create view
			var view = new this.ItemView({
				model: model,
				template: this.ItemTemplate,
				component: this.component
			});
			view.render();

			// Add the list item to the List
			this.$el.append(view.el);

			// Store the position in the views array
			// Don't store the actual view to prevent circular references
			view.$el.data('viewIndex', this.subViews.length);

			// Store in views array for removal later
			this.subViews.push(view);
		},

		remove: function() {
			this.removeSubViews();

			F.View.prototype.remove.call(this, arguments);
		},

		removeSubView: function(modelOrViewIndex) {
			var view = null;
			var viewIndex = -1;
			if (typeof viewIndex !== 'Number') {
				_.some(this.subViews, function(tmpView, index) {
					if (tmpView && tmpView.model === modelOrViewIndex) {
						view = tmpView;
						viewIndex = index;
					}
				}.bind(this));
			}
			else // get from view index
				view = this.subViews[viewIndex];

			if (view) {
				view.remove();
				this.subViews[viewIndex] = undefined;
			}
		},

		removeSubViews: function() {
			if (this.subViews.length) {
				_.each(this.subViews, function(view) {
					view.remove();
				});

				this.subViews = [];
			}
		},

		render: function() {
			if (F.options.debug) {
				console.log('%s: rendering list view...', this.component && this.component.toString() || 'List view');
			}

			if (this.parent && !$(this.el.parentNode).is(this.parent))
				$(this.parent).append(this.el);

			// Remove previous views from the DOM
			this.removeSubViews();

			// Add and render each list item
			this.collection.each(this.addSubView);

			// Store the last time this view was rendered
			this.rendered = new Date().getTime();

			this.trigger('renderComplete');

			return this;
		}
	});

	// Available as F.ListComponent.prototype.ItemView
	var ItemView = F.View.extend({
		tagName: 'li',
		className: 'listItem'
	});

	/* Component
	*******************/
	F.ListComponent = new Class(/** @lends F.ListComponent# */{
		toString: 'ListComponent',
		extend: F.CollectionComponent,

		/**
		 * A component that can load and render a collection as a list
		 *
		 * @constructs
		 * @extends F.CollectionComponent
		 *
		 * @param {Object} options							Options for this component and its view. Options not listed below will be passed to the view.
		 * @param {Backbone.Collection} options.Collection	The collection class this list will be rendered from
		 * @param {Backbone.View} options.ListView			The view class this list will be rendered with
		 * @param {Template} [options.ListTemplate]			The template this list will be rendered with. Renders to a UL tag by default
		 * @param {Backbone.View} options.ItemView			The view that individual items will be rendered with
		 * @param {Template} options.ItemTemplate			The template that individual items will be rendered with
		 *
		 * @property {Backbone.Collection} Collection	The collection class this list will be rendered from
		 * @property {Backbone.View} ListView			The view class this list will be rendered with
		 * @property {Template} ListTemplate			The template this list will be rendered with. Renders to a UL tag by default
		 * @property {Backbone.View} ItemView			The view that individual items will be rendered with
		 * @property {Template} ItemTemplate			The template that individual items will be rendered with
		 */
		construct: function(options) {
			// Set object properties from options object, removing them from the object thereafter
			this.setPropsFromOptions(options, [
				'Collection',
				'ListTemplate',
				'ListView',
				'ItemTemplate',
				'ItemView'
			]);

			this.view = new this.ListView(_.extend({
				component: this, // pass this as component so ItemView can trigger handleSelect if it likes
				collection: this.collection,
				ItemView: this.ItemView,
				ItemTemplate: this.ItemTemplate,
				events: {
					'click li': 'handleSelect'
				}
			}, options));

			this.selectedItem = null;
		},

		Collection: Backbone.Collection, // Collection component expects to have prototype.Collection or options.Collection

		ListTemplate: null,
		ListView: ListView,

		ItemTemplate: null,
		ItemView: ItemView,

		addModel: function(model) {
			// Add a subview for this model
			this.view.addSubView(model);
		},

		removeModel: function(model) {
			// Add a subview for this model
			this.view.removeSubView(model);
		},

		/**
		 * Get the model associated with a list item
		 *
		 * @param {Node}	Node or jQuery Object to get model from
		 *
		 * @returns {Backbone.Model}	The model associated with the passed DOM element
		 */
		getModelFromLi: function(listItem) {
			return this.view.subViews[$(listItem).data('viewIndex')].model;
		},

		/**
		 * Get the view associated with a list item
		 *
		 * @param {Node}	Node or jQuery Object to get model from
		 *
		 * @returns {Backbone.View}	The view associated with the passed DOM element
		 */
		getViewFromLi: function(listItem) {
			return this.view.subViews[$(listItem).data('viewIndex')];
		},

		/**
		 * Handles item selection events
		 *
		 * @param {Event} evt	The jQuery event object
		 */
		handleSelect: function(evt) {
			// Get model from DOM el's data
			var model = this.getModelFromLi(evt.currentTarget);

			// Store ID of selected item
			this.selectedItem = model.id;

			this.trigger('itemSelected', {
				listItem: $(evt.currentTarget),
				model: model
			});
		}
	});
}());
<|endoftext|>


<commit_before>module.exports = function (data, process) {

    // @TODO - get data.parameters.branch. If null, default to 'master'
    //
    // Listen for the 'push' event:
    // https://developer.github.com/v3/activity/events/types/#pushevent
    //
    // If the push was a standard push (i.e. commits, not tags), check the branch.
    // If the branch was data.parameters.branch, we need to branch off, open a pull request,
    // switch back to data.parameters.branch, and revert the pushed commit.

    process.succeed();
}<commit_msg>detect pushed branch<commit_after>module.exports = function (data, process) {

    var branchToProtect = data.parameters.branch || 'master';

    if ( data.payload.ref === ('refs/heads/' + branchToProtect) ) {
        process.fail('direct push to ' + branchToProtect + ' detected!');
        // @TODO we need to branch off, open a pull request,
        // switch back to branchToProtect, and revert the pushed commit.
    }
    else {
        process.succeed('the commit was to ' + data.payload.ref + ' and thus was not a problem');
    }
}<|endoftext|>


<commit_before>import _ from 'lodash'

const initialState = {
  members: [
    // {
    //   username,
    //   publicKey
    // }
  ],
  id: '',
  isLocked: false,
}

const room = (state = initialState, action) => {
  switch (action.type) {
    case 'USER_EXIT':
      const memberPubKeys = action.payload.members.map(m => m.publicKey.n)
      return {
        ...state,
        members: state.members
          .filter(member => memberPubKeys.includes(member.publicKey.n))
      }
    case 'RECEIVE_ENCRYPTED_MESSAGE_ADD_USER':
      return {
        ...state,
        members: state.members.map((member) => {
          if (member.publicKey.n === action.payload.payload.publicKey.n) {
            return {
              ...member,
              username: action.payload.payload.username,
              isOwner: action.payload.payload.isOwner,
              id: action.payload.payload.publicKey.n,
            }
          }
          return member
        }),
      }
    case 'CREATE_USER':
      return {
        ...state,
        members: [
          ...state.members,
          {
            username: action.payload.username,
            publicKey: action.payload.publicKey,
            id: action.payload.publicKey.n,
          },
        ],
      }
    case 'USER_ENTER':
      const members = _.uniqBy(action.payload.users, member => member.publicKey.n);

      return {
        ...state,
        id: action.payload.id,
        isLocked: Boolean(action.payload.isLocked),
        members: members.reduce((acc, user) => {
          const exists = state.members.find(m => m.publicKey.n === user.publicKey.n)
          if (exists) {
            return [
              ...acc,
              {
                ...user,
                ...exists,
              }
            ]
          }
          return [
            ...acc,
            {
              publicKey: user.publicKey,
              isOwner: user.isOwner,
              id: user.id,
            }
          ]
        }, []),
      }
    case 'TOGGLE_LOCK_ROOM':
      return {
        ...state,
        isLocked: !state.isLocked,
      }
    case 'RECEIVE_TOGGLE_LOCK_ROOM':
      return {
        ...state,
        isLocked: action.payload.locked,
      }
    case 'SEND_ENCRYPTED_MESSAGE_CHANGE_USERNAME':
      const newUsername = action.payload.newUsername
      const userId = action.payload.id
      return {
        ...state,
        members: state.members.map(member => (
          member.id === userId ?
            {
              ...member,
              username: newUsername,
            } : member
        )),
      }
    case 'RECEIVE_ENCRYPTED_MESSAGE_CHANGE_USERNAME':
      const newUsername2 = action.payload.payload.newUsername
      const userId2 = action.payload.payload.id
      return {
        ...state,
        members: state.members.map(member => (
          member.id === userId2 ?
            {
              ...member,
              username: newUsername2,
            } : member
        )),
      }
    default:
      return state
  }
}

export default room
<commit_msg>Fix for passing ownership on user exit (#78)<commit_after>import _ from 'lodash'

const initialState = {
  members: [
    // {
    //   username,
    //   publicKey
    // }
  ],
  id: '',
  isLocked: false,
}

const room = (state = initialState, action) => {
  switch (action.type) {
    case 'USER_EXIT':
      const memberPubKeys = action.payload.members.map(m => m.publicKey.n)
      return {
        ...state,
        members: state.members
          .filter(member => memberPubKeys.includes(member.publicKey.n))
          .map(member => {
            const thisMember = action.payload.members.find(mem => mem.publicKey.n === member.id)
            return {
              ...member,
              isOwner: thisMember.isOwner
            }
          })
      }
    case 'RECEIVE_ENCRYPTED_MESSAGE_ADD_USER':
      return {
        ...state,
        members: state.members.map((member) => {
          if (member.publicKey.n === action.payload.payload.publicKey.n) {
            return {
              ...member,
              username: action.payload.payload.username,
              isOwner: action.payload.payload.isOwner,
              id: action.payload.payload.publicKey.n,
            }
          }
          return member
        }),
      }
    case 'CREATE_USER':
      return {
        ...state,
        members: [
          ...state.members,
          {
            username: action.payload.username,
            publicKey: action.payload.publicKey,
            id: action.payload.publicKey.n,
          },
        ],
      }
    case 'USER_ENTER':
      const members = _.uniqBy(action.payload.users, member => member.publicKey.n);

      return {
        ...state,
        id: action.payload.id,
        isLocked: Boolean(action.payload.isLocked),
        members: members.reduce((acc, user) => {
          const exists = state.members.find(m => m.publicKey.n === user.publicKey.n)
          if (exists) {
            return [
              ...acc,
              {
                ...user,
                ...exists,
              }
            ]
          }
          return [
            ...acc,
            {
              publicKey: user.publicKey,
              isOwner: user.isOwner,
              id: user.id,
            }
          ]
        }, []),
      }
    case 'TOGGLE_LOCK_ROOM':
      return {
        ...state,
        isLocked: !state.isLocked,
      }
    case 'RECEIVE_TOGGLE_LOCK_ROOM':
      return {
        ...state,
        isLocked: action.payload.locked,
      }
    case 'SEND_ENCRYPTED_MESSAGE_CHANGE_USERNAME':
      const newUsername = action.payload.newUsername
      const userId = action.payload.id
      return {
        ...state,
        members: state.members.map(member => (
          member.id === userId ?
            {
              ...member,
              username: newUsername,
            } : member
        )),
      }
    case 'RECEIVE_ENCRYPTED_MESSAGE_CHANGE_USERNAME':
      const newUsername2 = action.payload.payload.newUsername
      const userId2 = action.payload.payload.id
      return {
        ...state,
        members: state.members.map(member => (
          member.id === userId2 ?
            {
              ...member,
              username: newUsername2,
            } : member
        )),
      }
    default:
      return state
  }
}

export default room
<|endoftext|>


<commit_before>// Copyright 2013-2015, University of Colorado Boulder

//Render a simple vertical check box group, where the buttons all have the same sizes
//TODO: not ready for use in simulations, it will need further development & discussion first.
//TODO: Abstract out common functionality between this and VerticalCheckBoxGroup
define( function( require ) {
  'use strict';

  var AquaRadioButton = require( 'SUN/AquaRadioButton' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Path = require( 'SCENERY/nodes/Path' );
  var Shape = require( 'KITE/Shape' );
  var sun = require( 'SUN/sun' );
  var VBox = require( 'SCENERY/nodes/VBox' );

  /**
   * Main constructor.
   *
   * @param items  an array of {content, property}
   * @param {Object} [options]
   * @constructor
   */
  function VerticalAquaRadioButtonGroup( items, options ) {
    options = _.extend( {
      spacing: 3,
      padding: 8,
      radius: 12,
      radioButtonOptions: {}, // will be passed to the AquaRadioButtons
      touchXPadding: 5,
      mouseXPadding: 0
    }, options );

    var width = 0;
    for ( var i = 0; i < items.length; i++ ) {
      width = Math.max( width, items[ i ].node.width );
    }

    var children = [];
    for ( i = 0; i < items.length; i++ ) {

      //Add an invisible strut to each content to make the widths match
      var content = new Path( Shape.rect( 0, 0, width + options.padding, 0 ), { children: [ items[ i ].node ] } );
      var radioButton = new AquaRadioButton( items[ i ].property, items[ i ].value, content, _.extend( {}, options.radioButtonOptions, { radius: options.radius } ) );
      radioButton.mouseArea = Shape.bounds( radioButton.bounds.dilatedXY( options.mouseXPadding, options.spacing / 2 ) );
      radioButton.touchArea = Shape.bounds( radioButton.bounds.dilatedXY( options.touchXPadding, options.spacing / 2 ) );
      children.push( radioButton );
    }

    //TODO these options should be added using _.extend(options, {children:..., renderer:....})
    options.children = children;
    VBox.call( this, options );
  }

  sun.register( 'VerticalAquaRadioButtonGroup', VerticalAquaRadioButtonGroup );

  inherit( VBox, VerticalAquaRadioButtonGroup );

  return VerticalAquaRadioButtonGroup;
} );
<commit_msg>Accessible content for VerticalAquaRadioButtonGroup<commit_after>// Copyright 2013-2015, University of Colorado Boulder

//Render a simple vertical check box group, where the buttons all have the same sizes
//TODO: not ready for use in simulations, it will need further development & discussion first.
//TODO: Abstract out common functionality between this and VerticalCheckBoxGroup
define( function( require ) {
  'use strict';

  var AquaRadioButton = require( 'SUN/AquaRadioButton' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Path = require( 'SCENERY/nodes/Path' );
  var Shape = require( 'KITE/Shape' );
  var sun = require( 'SUN/sun' );
  var VBox = require( 'SCENERY/nodes/VBox' );
  var AccessiblePeer = require( 'SCENERY/accessibility/AccessiblePeer' );

  /**
   * Main constructor.
   *
   * @param items  an array of {content, property}
   * @param {Object} [options]
   * @constructor
   */
  function VerticalAquaRadioButtonGroup( items, options ) {
    options = _.extend( {
      spacing: 3,
      padding: 8,
      radius: 12,
      radioButtonOptions: {}, // will be passed to the AquaRadioButtons
      touchXPadding: 5,
      mouseXPadding: 0,
      accessibleLabel: '', // label for the entire radio button group, invisible for a11y
      accessibleDescription: '' // description for the radio buttongroup, invisible for a11y
    }, options );

    var width = 0;
    for ( var i = 0; i < items.length; i++ ) {
      width = Math.max( width, items[ i ].node.width );
    }

    var children = [];
    for ( i = 0; i < items.length; i++ ) {

      //Add an invisible strut to each content to make the widths match
      var content = new Path( Shape.rect( 0, 0, width + options.padding, 0 ), { children: [ items[ i ].node ] } );
      var radioButton = new AquaRadioButton( items[ i ].property, items[ i ].value, content, _.extend( {}, options.radioButtonOptions, { radius: options.radius } ) );
      radioButton.mouseArea = Shape.bounds( radioButton.bounds.dilatedXY( options.mouseXPadding, options.spacing / 2 ) );
      radioButton.touchArea = Shape.bounds( radioButton.bounds.dilatedXY( options.touchXPadding, options.spacing / 2 ) );
      children.push( radioButton );
    }

    //TODO these options should be added using _.extend(options, {children:..., renderer:....})
    options.children = children;
    VBox.call( this, options );

    // a11y
    this.accessibleContent = {
      createPeer: function( accessibleInstance ) {
        var trail = accessibleInstance.trail;
        var uniqueId = trail.getUniqueId();

        /**
         * Elements of the parallel DOM should look like:
         * <fieldset id="radio-button-group" role="radiogroup" aria-describedby="legend-id group-description">
         * <legend id="legend-id">Translatable Legend Text</legend>
         *    ... ( elements inside the fieldset )
         *
Translatable description of the entire group.

         * </fieldset>
         **/
        // create the fieldset holding all radio buttons
        var domElement = document.createElement( 'fieldset' );
        domElement.id = 'radio-button-group-' + uniqueId;
        domElement.setAttribute( 'role', 'radioGroup' );

        // create the legend
        var legendElement = document.createElement( 'legend' );
        legendElement.id = 'legend-id-' + uniqueId;
        legendElement.innerHTML = options.accessibleLabel;

        // create the description element
        var descriptionElement = document.createElement( 'p' );
        descriptionElement.id = 'group-description-' + uniqueId;
        descriptionElement.innerText = options.accessibleDescription;

        // aria-describedby can have two id's
        var descriptionId = legendElement.id + ' ' + descriptionElement.id;
        domElement.setAttribute( 'aria-describedby', descriptionId );

        // structure the elements
        domElement.appendChild( legendElement );
        domElement.appendChild( descriptionElement );

        return new AccessiblePeer( accessibleInstance, domElement );

      }
    };
  }

  sun.register( 'VerticalAquaRadioButtonGroup', VerticalAquaRadioButtonGroup );

  inherit( VBox, VerticalAquaRadioButtonGroup );

  return VerticalAquaRadioButtonGroup;
} );
<|endoftext|>


<commit_before>module.exports = function (data, process) {

    var branchToProtect = data.parameters.branch || 'master';

    if ( data.payload.ref === ('refs/heads/' + branchToProtect) ) {

        // STEP 1 - branch off.

        var newBranchName = branchToProtect + "--super-protected--" + Date.now(),
            options = {
                url: data.payload.repository.git_refs_url.replace('{/sha}', ''),
                headers: {
                    'Content-Type':  'application/json',
                    'User-Agent':    'super-protected-branches',
                    'Authorization': 'token ' + data.access_token
                },
                json: {
                    "ref": "refs/heads/" + newBranchName,
                    "sha": data.payload.after
                }
            };

        request.post(options, function newBranchCreated(err, httpResponse, body) {
            if (err) {
                process.fail('Could not send POST request: ' + err);
            }
            else {

                // STEP 2 - revert the pushed commit
                var theCommitBeforeThePush = data.payload.before;

                options.url = data.payload.repository.git_refs_url.replace('{/sha}', '') + '/' + data.payload.after;
                options.json = {
                    "sha": data.payload.before,
                    "force": true
                };

                request.patch(options, function protectedBranchReverted(err, httpResponse, body) {
                    if (err) {
                        process.fail('Could not send POST request: ' + err);
                    }
                    else {
                        process.succeed('Reverting was successful. Response: ' + JSON.stringify(body));
                    }

                    // // STEP 3 - open a Pull Request with the new branch.

                    // options.url = data.payload.repository.pulls_url.replace('{/number}', '');
                    // options.json = {
                    //     title: data.payload.head_commit.message,
                    //     body:  'This pull request was automatically generated by the [Super Protected Branches GitHook](http://githooks.io/githooks/GitHooksIO/githook-super-protected-branches) when ' + data.payload.head_commit.author.username + ' tried to push directly to ' + branchToProtect + '.',
                    //     head:  newBranchName,
                    //     base:  branchToProtect
                    // };

                    // request.post(options, function pullRequestOpened(err, httpResponse, body) {
                    //     if (err) {
                    //         process.fail('Could not send POST request: ' + err);
                    //     }
                    //     else {
                    //         process.succeed('Pull request creation was successful. Response: ' + JSON.stringify(body));
                    //     }
                });

            }
        });

    }
    else {
        process.succeed('the commit was to ' + data.payload.ref + ' and thus was not a problem');
    }
}<commit_msg>another attempt<commit_after>module.exports = function (data, process) {

    var branchToProtect = data.parameters.branch || 'master';

    if ( data.payload.ref === ('refs/heads/' + branchToProtect) ) {

        // STEP 1 - branch off.

        var newBranchName = branchToProtect + "--super-protected--" + Date.now(),
            options = {
                url: data.payload.repository.git_refs_url.replace('{/sha}', ''),
                headers: {
                    'Content-Type':  'application/json',
                    'User-Agent':    'super-protected-branches',
                    'Authorization': 'token ' + data.access_token
                },
                json: {
                    "ref": "refs/heads/" + newBranchName,
                    "sha": data.payload.after
                }
            };

        request.post(options, function newBranchCreated(err, httpResponse, body) {
            if (err) {
                process.fail('Could not send POST request: ' + err);
            }
            else {

                // STEP 2 - revert the pushed commit
                var theCommitBeforeThePush = data.payload.before;

                options.url = data.payload.repository.git_refs_url.replace('{/sha}', '') + '/heads/' + branchToProtect;
                options.json = {
                    "sha": data.payload.before,
                    "force": true
                };

                request.patch(options, function protectedBranchReverted(err, httpResponse, body) {
                    if (err) {
                        process.fail('Could not send POST request: ' + err);
                    }
                    else {
                        process.succeed('Reverting was successful. Response: ' + JSON.stringify(body));
                    }

                    // // STEP 3 - open a Pull Request with the new branch.

                    // options.url = data.payload.repository.pulls_url.replace('{/number}', '');
                    // options.json = {
                    //     title: data.payload.head_commit.message,
                    //     body:  'This pull request was automatically generated by the [Super Protected Branches GitHook](http://githooks.io/githooks/GitHooksIO/githook-super-protected-branches) when ' + data.payload.head_commit.author.username + ' tried to push directly to ' + branchToProtect + '.',
                    //     head:  newBranchName,
                    //     base:  branchToProtect
                    // };

                    // request.post(options, function pullRequestOpened(err, httpResponse, body) {
                    //     if (err) {
                    //         process.fail('Could not send POST request: ' + err);
                    //     }
                    //     else {
                    //         process.succeed('Pull request creation was successful. Response: ' + JSON.stringify(body));
                    //     }
                });

            }
        });

    }
    else {
        process.succeed('the commit was to ' + data.payload.ref + ' and thus was not a problem');
    }
}<|endoftext|>


<commit_before>/*
 * Copyright 2011 eBay Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';
var createError = require('raptor-util').createError;
var forEachEntry = require('raptor-util').forEachEntry;
var ok = require('assert').ok;

function Taglib(id) {
    ok(id, '"id" expected');
    this.id = id;
    this.dirname = null;
    this.namespace = null;
    this.namespaces = [];
    this.tags = {};
    this.textTransformers = [];
    this.attributeMap = {};
    this.functions = [];
    this.helperObject = null;
    this.patternAttributes = [];
    this.importPaths = [];
}

Taglib.prototype = {
    addAttribute: function (attribute) {
        if (attribute.namespace) {
            throw createError(new Error('"namespace" is not allowed for taglib attributes'));
        }
        if (attribute.name) {
            this.attributeMap[attribute.name] = attribute;
        } else {
            this.patternAttributes.push(attribute);
        }
    },
    getAttribute: function (name) {
        var attribute = this.attributeMap[name];
        if (!attribute) {
            for (var i = 0, len = this.patternAttributes.length; i < len; i++) {
                var patternAttribute = this.patternAttributes[i];
                if (patternAttribute.pattern.test(name)) {
                    attribute = patternAttribute;
                }
            }
        }
        return attribute;
    },
    addTag: function (tag) {
        ok(arguments.length === 1, 'Invalid args');
        ok(tag.name, '"tag.name" is required');

        var key = (tag.namespace == null ? this.id : tag.namespace) + ':' + tag.name;
        this.tags[key] = tag;
    },
    addTextTransformer: function (transformer) {
        this.textTransformers.push(transformer);
    },
    forEachTag: function (callback, thisObj) {
        forEachEntry(this.tags, function (key, tag) {
            callback.call(thisObj, tag);
        }, this);
    },
    addFunction: function (func) {
        this.functions.push(func);
    },
    setHelperObject: function (helperObject) {
        this.helperObject = helperObject;
    },
    getHelperObject: function () {
        return this.helperObject;
    },
    addNamespace: function (ns) {
        this.namespaces.push(ns);
    }
};
Taglib.Tag = (function () {
    function Tag(taglib) {
        ok(taglib, '"taglib" expected');
        this.taglib = taglib;
        this.renderer = null;
        this.nodeClass = null;
        this.template = null;
        this.attributeMap = {};
        this.transformers = {};
        this.nestedVariables = {};
        this.importedVariables = {};
        this.patternAttributes = [];

    }
    Tag.prototype = {
        inheritFrom: function (superTag) {
            var subTag = this;
            /*
             * Have the sub tag inherit any properties from the super tag that are not in the sub tag
             */
            forEachEntry(superTag, function (k, v) {
                if (subTag[k] === undefined) {
                    subTag[k] = v;
                }
            });
            function inheritProps(sub, sup) {
                forEachEntry(sup, function (k, v) {
                    if (!sub[k]) {
                        sub[k] = v;
                    }
                });
            }
            [
                'attributeMap',
                'transformers',
                'nestedVariables',
                'importedVariables'
            ].forEach(function (propName) {
                inheritProps(subTag[propName], superTag[propName]);
            });
            subTag.patternAttributes = superTag.patternAttributes.concat(subTag.patternAttributes);
        },
        forEachVariable: function (callback, thisObj) {
            forEachEntry(this.nestedVariables, function (key, variable) {
                callback.call(thisObj, variable);
            });
        },
        forEachImportedVariable: function (callback, thisObj) {
            forEachEntry(this.importedVariables, function (key, importedVariable) {
                callback.call(thisObj, importedVariable);
            });
        },
        forEachTransformer: function (callback, thisObj) {
            forEachEntry(this.transformers, function (key, transformer) {
                callback.call(thisObj, transformer);
            });
        },
        hasTransformers: function () {
            /*jshint unused:false */
            for (var k in this.transformers) {
                return true;
            }
            return false;
        },
        addAttribute: function (attr) {
            if (attr.pattern) {
                this.patternAttributes.push(attr);
            } else {
                var namespace = attr.namespace;
                if (namespace == null) {
                    namespace = this.taglib.id;
                }

                if (attr.name === '*') {
                    attr.dynamicAttribute = true;

                    if (attr.targetProperty === null || attr.targetProperty === '') {
                        attr.targetProperty = null;

                    }
                    else if (!attr.targetProperty) {
                        attr.targetProperty = '*';
                    }
                }

                this.attributeMap[namespace + ':' + attr.name] = attr;
            }
        },
        getAttribute: function (tagNS, localName) {

            if (tagNS == null) {
                tagNS = this.taglib.id;
            }

            var attr = this.attributeMap[tagNS + ':' + localName] || this.attributeMap[tagNS + ':*'] || this.attributeMap['*:' + localName] || this.attributeMap['*:*'];
            if (!attr && this.patternAttributes.length) {
                for (var i = 0, len = this.patternAttributes.length; i < len; i++) {
                    var patternAttribute = this.patternAttributes[i];

                    var attrNS = patternAttribute.namespace;
                    if (attrNS == null) {
                        attrNS = tagNS;
                    }

                    if (attrNS === tagNS && patternAttribute.pattern.test(localName)) {
                        attr = patternAttribute;
                        break;
                    }
                }
            }
            return attr;
        },
        toString: function () {
            var qName = this.namespace ? this.namespace + ':' + this.name : this.name;
            return '[Tag: <' + qName + '@' + this.taglib.id + '>]';
        },
        forEachAttribute: function (callback, thisObj) {
            forEachEntry(this.attributeMap, function (attrName, attr) {
                callback.call(thisObj, attr);
            });
        },
        addNestedVariable: function (nestedVariable) {
            var key = nestedVariable.nameFromAttribute ? 'attr:' + nestedVariable.nameFromAttribute : nestedVariable.name;
            this.nestedVariables[key] = nestedVariable;
        },
        addImportedVariable: function (importedVariable) {
            var key = importedVariable.targetProperty;
            this.importedVariables[key] = importedVariable;
        },
        addTransformer: function (transformer) {
            var key = transformer.path;
            transformer.taglib = this.taglib;
            this.transformers[key] = transformer;
        }
    };
    return Tag;
}());
Taglib.Attribute = (function () {
    function Attribute(namespace, name) {
        this.namespace = namespace;
        this.name = name;
        this.type = null;
        this.required = false;
        this.type = 'string';
        this.allowExpressions = true;
    }
    Attribute.prototype = {};
    return Attribute;
}());
Taglib.Property = (function () {
    function Property() {
        this.name = null;
        this.type = 'string';
        this.value = undefined;
    }
    Property.prototype = {};
    return Property;
}());
Taglib.NestedVariable = (function () {
    function NestedVariable() {
        this.name = null;
    }
    NestedVariable.prototype = {};
    return NestedVariable;
}());
Taglib.ImportedVariable = (function () {
    function ImportedVariable() {
        this.targetProperty = null;
        this.expression = null;
    }
    ImportedVariable.prototype = {};
    return ImportedVariable;
}());
Taglib.Transformer = (function () {
    var uniqueId = 0;
    function Transformer() {
        this.id = uniqueId++;
        this.name = null;
        this.tag = null;
        this.path = null;
        this.after = null;
        this.before = null;
        this.instance = null;
        this.properties = {};
    }
    Transformer.prototype = {
        getInstance: function () {
            if (!this.path) {
                throw createError(new Error('Transformer class not defined for tag transformer (tag=' + this.tag + ')'));
            }
            if (!this.instance) {
                var Clazz = require(this.path);
                if (Clazz.process) {
                    return Clazz;
                }

                if (typeof Clazz !== 'function') {
                    console.error('Invalid transformer: ', Clazz);
                    throw new Error('Invalid transformer at path "' + this.path + '": ' + Clazz);
                }
                this.instance = new Clazz();
                this.instance.id = this.id;
            }
            return this.instance;
        },
        toString: function () {
            return '[Taglib.Transformer: ' + this.filename + ']';
        }
    };
    return Transformer;
}());
Taglib.Function = (function () {
    function Func() {
        this.name = null;
        this.path = null;
        this.bindToContext = false;
    }
    Func.prototype = {};
    return Func;
}());
Taglib.HelperObject = (function () {
    function HelperObject() {
        this.path = null;
    }
    HelperObject.prototype = {};
    return HelperObject;
}());
module.exports = Taglib;<commit_msg>Fix pattern attributes<commit_after>/*
 * Copyright 2011 eBay Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';
var createError = require('raptor-util').createError;
var forEachEntry = require('raptor-util').forEachEntry;
var ok = require('assert').ok;

function Taglib(id) {
    ok(id, '"id" expected');
    this.id = id;
    this.dirname = null;
    this.namespace = null;
    this.namespaces = [];
    this.tags = {};
    this.textTransformers = [];
    this.attributeMap = {};
    this.functions = [];
    this.helperObject = null;
    this.patternAttributes = [];
    this.importPaths = [];
}

Taglib.prototype = {
    addAttribute: function (attribute) {
        if (attribute.namespace) {
            throw createError(new Error('"namespace" is not allowed for taglib attributes'));
        }
        if (attribute.pattern) {
            this.patternAttributes.push(attribute);
        } else if (attribute.name) {
            this.attributeMap[attribute.name] = attribute;
        } else {
            throw new Error('Invalid attribute: ' + require('util').inspect(attribute));
        }
    },
    getAttribute: function (name) {
        var attribute = this.attributeMap[name];
        if (!attribute) {
            for (var i = 0, len = this.patternAttributes.length; i < len; i++) {
                var patternAttribute = this.patternAttributes[i];
                if (patternAttribute.pattern.test(name)) {
                    attribute = patternAttribute;
                }
            }
        }
        return attribute;
    },
    addTag: function (tag) {
        ok(arguments.length === 1, 'Invalid args');
        ok(tag.name, '"tag.name" is required');

        var key = (tag.namespace == null ? this.id : tag.namespace) + ':' + tag.name;
        this.tags[key] = tag;
    },
    addTextTransformer: function (transformer) {
        this.textTransformers.push(transformer);
    },
    forEachTag: function (callback, thisObj) {
        forEachEntry(this.tags, function (key, tag) {
            callback.call(thisObj, tag);
        }, this);
    },
    addFunction: function (func) {
        this.functions.push(func);
    },
    setHelperObject: function (helperObject) {
        this.helperObject = helperObject;
    },
    getHelperObject: function () {
        return this.helperObject;
    },
    addNamespace: function (ns) {
        this.namespaces.push(ns);
    }
};
Taglib.Tag = (function () {
    function Tag(taglib) {
        ok(taglib, '"taglib" expected');
        this.taglib = taglib;
        this.renderer = null;
        this.nodeClass = null;
        this.template = null;
        this.attributeMap = {};
        this.transformers = {};
        this.nestedVariables = {};
        this.importedVariables = {};
        this.patternAttributes = [];

    }
    Tag.prototype = {
        inheritFrom: function (superTag) {
            var subTag = this;
            /*
             * Have the sub tag inherit any properties from the super tag that are not in the sub tag
             */
            forEachEntry(superTag, function (k, v) {
                if (subTag[k] === undefined) {
                    subTag[k] = v;
                }
            });
            function inheritProps(sub, sup) {
                forEachEntry(sup, function (k, v) {
                    if (!sub[k]) {
                        sub[k] = v;
                    }
                });
            }
            [
                'attributeMap',
                'transformers',
                'nestedVariables',
                'importedVariables'
            ].forEach(function (propName) {
                inheritProps(subTag[propName], superTag[propName]);
            });
            subTag.patternAttributes = superTag.patternAttributes.concat(subTag.patternAttributes);
        },
        forEachVariable: function (callback, thisObj) {
            forEachEntry(this.nestedVariables, function (key, variable) {
                callback.call(thisObj, variable);
            });
        },
        forEachImportedVariable: function (callback, thisObj) {
            forEachEntry(this.importedVariables, function (key, importedVariable) {
                callback.call(thisObj, importedVariable);
            });
        },
        forEachTransformer: function (callback, thisObj) {
            forEachEntry(this.transformers, function (key, transformer) {
                callback.call(thisObj, transformer);
            });
        },
        hasTransformers: function () {
            /*jshint unused:false */
            for (var k in this.transformers) {
                return true;
            }
            return false;
        },
        addAttribute: function (attr) {
            if (attr.pattern) {
                this.patternAttributes.push(attr);
            } else {
                var namespace = attr.namespace;
                if (namespace == null) {
                    namespace = this.taglib.id;
                }

                if (attr.name === '*') {
                    attr.dynamicAttribute = true;

                    if (attr.targetProperty === null || attr.targetProperty === '') {
                        attr.targetProperty = null;

                    }
                    else if (!attr.targetProperty) {
                        attr.targetProperty = '*';
                    }
                }

                this.attributeMap[namespace + ':' + attr.name] = attr;
            }
        },
        getAttribute: function (tagNS, localName) {

            if (tagNS == null) {
                tagNS = this.taglib.id;
            }

            var attr = this.attributeMap[tagNS + ':' + localName] || this.attributeMap[tagNS + ':*'] || this.attributeMap['*:' + localName] || this.attributeMap['*:*'];
            if (!attr && this.patternAttributes.length) {
                for (var i = 0, len = this.patternAttributes.length; i < len; i++) {
                    var patternAttribute = this.patternAttributes[i];

                    var attrNS = patternAttribute.namespace;
                    if (attrNS == null) {
                        attrNS = tagNS;
                    }

                    if (attrNS === tagNS && patternAttribute.pattern.test(localName)) {
                        attr = patternAttribute;
                        break;
                    }
                }
            }
            return attr;
        },
        toString: function () {
            var qName = this.namespace ? this.namespace + ':' + this.name : this.name;
            return '[Tag: <' + qName + '@' + this.taglib.id + '>]';
        },
        forEachAttribute: function (callback, thisObj) {
            for (var attrName in this.attributeMap) {
                if (this.attributeMap.hasOwnProperty(attrName)) {
                    callback.call(thisObj, this.attributeMap[attrName]);
                }
            }
        },
        addNestedVariable: function (nestedVariable) {
            var key = nestedVariable.nameFromAttribute ? 'attr:' + nestedVariable.nameFromAttribute : nestedVariable.name;
            this.nestedVariables[key] = nestedVariable;
        },
        addImportedVariable: function (importedVariable) {
            var key = importedVariable.targetProperty;
            this.importedVariables[key] = importedVariable;
        },
        addTransformer: function (transformer) {
            var key = transformer.path;
            transformer.taglib = this.taglib;
            this.transformers[key] = transformer;
        }
    };
    return Tag;
}());
Taglib.Attribute = (function () {
    function Attribute(namespace, name) {
        this.namespace = namespace;
        this.name = name;
        this.type = null;
        this.required = false;
        this.type = 'string';
        this.allowExpressions = true;
    }
    Attribute.prototype = {};
    return Attribute;
}());
Taglib.Property = (function () {
    function Property() {
        this.name = null;
        this.type = 'string';
        this.value = undefined;
    }
    Property.prototype = {};
    return Property;
}());
Taglib.NestedVariable = (function () {
    function NestedVariable() {
        this.name = null;
    }
    NestedVariable.prototype = {};
    return NestedVariable;
}());
Taglib.ImportedVariable = (function () {
    function ImportedVariable() {
        this.targetProperty = null;
        this.expression = null;
    }
    ImportedVariable.prototype = {};
    return ImportedVariable;
}());
Taglib.Transformer = (function () {
    var uniqueId = 0;
    function Transformer() {
        this.id = uniqueId++;
        this.name = null;
        this.tag = null;
        this.path = null;
        this.after = null;
        this.before = null;
        this.instance = null;
        this.properties = {};
    }
    Transformer.prototype = {
        getInstance: function () {
            if (!this.path) {
                throw createError(new Error('Transformer class not defined for tag transformer (tag=' + this.tag + ')'));
            }
            if (!this.instance) {
                var Clazz = require(this.path);
                if (Clazz.process) {
                    return Clazz;
                }

                if (typeof Clazz !== 'function') {
                    console.error('Invalid transformer: ', Clazz);
                    throw new Error('Invalid transformer at path "' + this.path + '": ' + Clazz);
                }
                this.instance = new Clazz();
                this.instance.id = this.id;
            }
            return this.instance;
        },
        toString: function () {
            return '[Taglib.Transformer: ' + this.filename + ']';
        }
    };
    return Transformer;
}());
Taglib.Function = (function () {
    function Func() {
        this.name = null;
        this.path = null;
        this.bindToContext = false;
    }
    Func.prototype = {};
    return Func;
}());
Taglib.HelperObject = (function () {
    function HelperObject() {
        this.path = null;
    }
    HelperObject.prototype = {};
    return HelperObject;
}());
module.exports = Taglib;<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// @brief test the compaction
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

var jsunity = require("jsunity");
var internal = require("internal");

// -----------------------------------------------------------------------------
// --SECTION--                                                collection methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief test suite: collection
////////////////////////////////////////////////////////////////////////////////

function CompactionSuite () {
  var ERRORS = require("internal").errors;

  return {

////////////////////////////////////////////////////////////////////////////////
/// @brief read by name
////////////////////////////////////////////////////////////////////////////////

    testCompactAfterTruncate : function () {
      var maxWait;
      var waited;
      var cn = "example";
      var n = 400;
      var payload = "the quick brown fox jumped over the lazy dog. a quick dog jumped over the lazy fox";

      for (var i = 0; i < 5; ++i) {
        payload += payload;
      }

      internal.db._drop(cn);
      internal.wait(5);
      var c1 = internal.db._create(cn, { "journalSize" : 1048576 } );
      internal.wait(2);

      for (var i = 0; i < n; ++i) {
        c1.save({ value : i, payload : payload });
        if ((i > 0) && (i % 100 == 0)) {
          internal.wait(2);
        }
      }

      var fig = c1.figures();
      assertEqual(n, c1.count());
      assertEqual(n, fig["alive"]["count"]);
      assertEqual(0, fig["dead"]["count"]);
      assertEqual(0, fig["dead"]["deletion"]);
      assertTrue(0 < fig["datafiles"]["count"]);
      assertTrue(0 < fig["journals"]["count"]);

      c1.truncate();
      c1.unload();
      internal.wait(2);

      c1 = null;

      // wait for compactor to run
      require("console").log("waiting for compactor to run");

      // set max wait time
      if (internal.VALGRIND) {
        maxWait = 750;
      }
      else {
        maxWait = 75;
      }

      waited = 0;

      while (waited < maxWait) {
        internal.wait(5);
        waited += 5;

        c1 = internal.db[cn];
        c1.load();

        fig = c1.figures();
        if (fig["dead"]["deletion"] >= n && fig["dead"]["count"] >= n) {
          break;
        }

        c1.unload();
      }

      c1 = internal.db[cn];
      c1.load();
      fig = c1.figures();
      assertEqual(0, c1.count());
      assertEqual(0, fig["alive"]["count"]);
      assertEqual(n, fig["dead"]["count"]);
      assertEqual(n, fig["dead"]["deletion"]);

      internal.db._drop(cn);
    }

  };
}

// -----------------------------------------------------------------------------
// --SECTION--                                                              main
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief executes the test suites
////////////////////////////////////////////////////////////////////////////////

jsunity.run(CompactionSuite);

return jsunity.done();

// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
// End:

<commit_msg>increase wait time<commit_after>////////////////////////////////////////////////////////////////////////////////
/// @brief test the compaction
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

var jsunity = require("jsunity");
var internal = require("internal");

// -----------------------------------------------------------------------------
// --SECTION--                                                collection methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief test suite: collection
////////////////////////////////////////////////////////////////////////////////

function CompactionSuite () {
  var ERRORS = require("internal").errors;

  return {

////////////////////////////////////////////////////////////////////////////////
/// @brief read by name
////////////////////////////////////////////////////////////////////////////////

    testCompactAfterTruncate : function () {
      var maxWait;
      var waited;
      var cn = "example";
      var n = 400;
      var payload = "the quick brown fox jumped over the lazy dog. a quick dog jumped over the lazy fox";

      for (var i = 0; i < 5; ++i) {
        payload += payload;
      }

      internal.db._drop(cn);
      internal.wait(5);
      var c1 = internal.db._create(cn, { "journalSize" : 1048576 } );
      internal.wait(2);

      for (var i = 0; i < n; ++i) {
        c1.save({ value : i, payload : payload });
        if ((i > 0) && (i % 100 == 0)) {
          internal.wait(2);
        }
      }

      var fig = c1.figures();
      assertEqual(n, c1.count());
      assertEqual(n, fig["alive"]["count"]);
      assertEqual(0, fig["dead"]["count"]);
      assertEqual(0, fig["dead"]["deletion"]);
      assertTrue(0 < fig["datafiles"]["count"]);
      assertTrue(0 < fig["journals"]["count"]);

      c1.truncate();
      c1.unload();
      internal.wait(2);

      c1 = null;

      // wait for compactor to run
      require("console").log("waiting for compactor to run");

      // set max wait time
      if (internal.VALGRIND) {
        maxWait = 750;
      }
      else {
        maxWait = 90;
      }

      waited = 0;

      while (waited < maxWait) {
        internal.wait(5);
        waited += 5;

        c1 = internal.db[cn];
        c1.load();

        fig = c1.figures();
        if (fig["dead"]["deletion"] >= n && fig["dead"]["count"] >= n) {
          break;
        }

        c1.unload();
      }

      c1 = internal.db[cn];
      c1.load();
      fig = c1.figures();
      assertEqual(0, c1.count());
      assertEqual(0, fig["alive"]["count"]);
      assertEqual(n, fig["dead"]["count"]);
      assertEqual(n, fig["dead"]["deletion"]);

      internal.db._drop(cn);
    }

  };
}

// -----------------------------------------------------------------------------
// --SECTION--                                                              main
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief executes the test suites
////////////////////////////////////////////////////////////////////////////////

jsunity.run(CompactionSuite);

return jsunity.done();

// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
// End:

<|endoftext|>