<commit_before>describe('Cookies', function () {
    beforeEach(function () {
        this.addMatchers({
            toBeBoolean: function () {
                return this.actual === true || this.actual === false;
            }
        });
    });

    it('exists in the "window" object', function () {
        expect(Cookies).toBeDefined();
    });

    describe('.enabled', function () {
        it('returns whether or not the browser has cookies enabled', function () {
            expect(Cookies.enabled).toBeBoolean();
        });
    });

    var cookieKey = 'cookies-spec.js';
    describe('.set(key, value [, options])', function () {
        it('returns the "Cookies" object', function () {
            expect(Cookies.set(cookieKey)).toBe(Cookies);
        });

        it('sets a cookie in "document.cookie"', function () {
            expect(document.cookie).toContain(cookieKey + '=');
        });

        it('JSON encodes numbers', function () {
            Cookies.set(cookieKey, 1);
            expect(document.cookie).toContain(cookieKey + '=' + escape(JSON.stringify(1)));
        });

        it('JSON encodes strings', function () {
            Cookies.set(cookieKey, '1');
            expect(document.cookie).toContain(cookieKey + '=' + escape(JSON.stringify('1')));
        });

        it('JSON encodes arrays', function () {
            Cookies.set(cookieKey, [1, 2, 3]);
            expect(document.cookie).toContain(cookieKey + '=' + escape(JSON.stringify([1, 2, 3])));
        });

        it('JSON encodes objects', function () {
            Cookies.set(cookieKey, { key: 'value' });
            expect(document.cookie).toContain(cookieKey + '=' + escape(JSON.stringify({ key: 'value' })));
        });

        it('JSON encodes dates', function () {
            var date = new Date();
            Cookies.set(cookieKey, date);
            expect(document.cookie).toContain(cookieKey + '=' + escape(JSON.stringify(date)));
        });

        // No way to know if a cookie is actually secure unless HTTP is used.
        if (window.location.protocol === 'http:') {
            it('sets secure cookies when "options.secure" is true', function () {
                Cookies.set(cookieKey, 1, { secure: true });
                expect(document.cookie).not.toContain(cookieKey + '=');
                Cookies.set(cookieKey, 1, { secure: false });
            });
        }
    });

    describe('.expire(key [, options])', function () {
        it('returns the "Cookies" object', function () {
            expect(Cookies.expire(cookieKey)).toBe(Cookies);
        });

        it('removes a cookie from "document.cookie"', function () {
            expect(document.cookie).not.toContain(cookieKey + '=');
        });
    });

    describe('.get(key)', function () {
        it('is aliased by calling "Cookies" as a function', function () {
            expect(Cookies.set(cookieKey, 1).get(cookieKey)).toEqual(Cookies(cookieKey));
        });

        it('returns the most locally scoped cookie value for a specific key', function () {
            Cookies.set(cookieKey, 2, { path: '/' });
            expect(Cookies.get(cookieKey)).toEqual(1);
            Cookies.expire(cookieKey, { path: '/' });
        });

        it('returns "undefined" for cookies that don\'t exist', function () {
            Cookies.expire(cookieKey);
            expect(Cookies.get(cookieKey)).toBeUndefined();
        });

        it('parses JSON encoded numbers', function () {
            expect(Cookies.set(cookieKey, 1).get(cookieKey)).toEqual(1);
        });

        it('parses JSON encoded strings', function () {
            expect(Cookies.set(cookieKey, '1').get(cookieKey)).toEqual('1');
        });

        it('parses JSON encoded arrays', function () {
            expect(Cookies.set(cookieKey, [1, 2, 3]).get(cookieKey)).toEqual([1, 2, 3]);
        });

        it('parses JSON encoded objects', function () {
            expect(Cookies.set(cookieKey, { key: 'value' }).get(cookieKey)).toEqual({ key: 'value' });
        });

        it('caches cookie values', function () {
            Cookies.set(cookieKey, 1).get(cookieKey);
            expect(Cookies._cache[cookieKey]).toEqual(1);
        });
    });
});<commit_msg>Deleted a unit test regarding cookie paths<commit_after>describe('Cookies', function () {
    beforeEach(function () {
        this.addMatchers({
            toBeBoolean: function () {
                return this.actual === true || this.actual === false;
            }
        });
    });

    it('exists in the "window" object', function () {
        expect(Cookies).toBeDefined();
    });

    describe('.enabled', function () {
        it('returns whether or not the browser has cookies enabled', function () {
            expect(Cookies.enabled).toBeBoolean();
        });
    });

    var cookieKey = 'cookies-spec.js';
    describe('.set(key, value [, options])', function () {
        it('returns the "Cookies" object', function () {
            expect(Cookies.set(cookieKey)).toBe(Cookies);
        });

        it('sets a cookie in "document.cookie"', function () {
            expect(document.cookie).toContain(cookieKey + '=');
        });

        it('JSON encodes numbers', function () {
            Cookies.set(cookieKey, 1);
            expect(document.cookie).toContain(cookieKey + '=' + escape(JSON.stringify(1)));
        });

        it('JSON encodes strings', function () {
            Cookies.set(cookieKey, '1');
            expect(document.cookie).toContain(cookieKey + '=' + escape(JSON.stringify('1')));
        });

        it('JSON encodes arrays', function () {
            Cookies.set(cookieKey, [1, 2, 3]);
            expect(document.cookie).toContain(cookieKey + '=' + escape(JSON.stringify([1, 2, 3])));
        });

        it('JSON encodes objects', function () {
            Cookies.set(cookieKey, { key: 'value' });
            expect(document.cookie).toContain(cookieKey + '=' + escape(JSON.stringify({ key: 'value' })));
        });

        it('JSON encodes dates', function () {
            var date = new Date();
            Cookies.set(cookieKey, date);
            expect(document.cookie).toContain(cookieKey + '=' + escape(JSON.stringify(date)));
        });

        // No way to know if a cookie is actually secure unless HTTP is used.
        if (window.location.protocol === 'http:') {
            it('sets secure cookies when "options.secure" is true', function () {
                Cookies.set(cookieKey, 1, { secure: true });
                expect(document.cookie).not.toContain(cookieKey + '=');
                Cookies.set(cookieKey, 1, { secure: false });
            });
        }
    });

    describe('.expire(key [, options])', function () {
        it('returns the "Cookies" object', function () {
            expect(Cookies.expire(cookieKey)).toBe(Cookies);
        });

        it('removes a cookie from "document.cookie"', function () {
            expect(document.cookie).not.toContain(cookieKey + '=');
        });
    });

    describe('.get(key)', function () {
        it('is aliased by calling "Cookies" as a function', function () {
            expect(Cookies.set(cookieKey, 1).get(cookieKey)).toEqual(Cookies(cookieKey));
        });

        it('returns "undefined" for cookies that don\'t exist', function () {
            Cookies.expire(cookieKey);
            expect(Cookies.get(cookieKey)).toBeUndefined();
        });

        it('parses JSON encoded numbers', function () {
            expect(Cookies.set(cookieKey, 1).get(cookieKey)).toEqual(1);
        });

        it('parses JSON encoded strings', function () {
            expect(Cookies.set(cookieKey, '1').get(cookieKey)).toEqual('1');
        });

        it('parses JSON encoded arrays', function () {
            expect(Cookies.set(cookieKey, [1, 2, 3]).get(cookieKey)).toEqual([1, 2, 3]);
        });

        it('parses JSON encoded objects', function () {
            expect(Cookies.set(cookieKey, { key: 'value' }).get(cookieKey)).toEqual({ key: 'value' });
        });

        it('caches cookie values', function () {
            Cookies.set(cookieKey, 1).get(cookieKey);
            expect(Cookies._cache[cookieKey]).toEqual(1);
        });
    });
});<|endoftext|>


<commit_before>/**
* Copyright 2012-2017, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

var d3 = require('d3');
var render = require('./render');
var Fx = require('../../components/fx');
var Color = require('../../components/color');

function renderableValuePresent(d) {return d !== '';}

function ownTrace(selection, d) {
    return selection.filter(function(s) {return s.key === d.traceId;});
}

function makeTranslucent(element, alpha) {
    d3.select(element)
        .select('path')
        .style('fill-opacity', alpha);
    d3.select(element)
        .select('rect')
        .style('fill-opacity', alpha);
}

function makeTextContrasty(element) {
    d3.select(element)
        .select('text.name')
        .style('fill', 'black');
}

function relatedLinks(d) {
    return function(l) {
        return d.node.sourceLinks.indexOf(l.link) !== -1 || d.node.targetLinks.indexOf(l.link) !== -1;
    };
}

function relatedNodes(l) {
    return function(d) {
        return d.node.sourceLinks.indexOf(l.link) !== -1 || d.node.targetLinks.indexOf(l.link) !== -1;
    };
}

function nodeHoveredStyle(sankeyNode, d, sankey) {
    if(d && sankey) {
        ownTrace(sankey, d)
            .selectAll('.sankeyLink')
            .filter(relatedLinks(d))
            .call(linkHoveredStyle.bind(0, d, sankey, false));
    }
}

function nodeNonHoveredStyle(sankeyNode, d, sankey) {
    if(d && sankey) {
        ownTrace(sankey, d)
            .selectAll('.sankeyLink')
            .filter(relatedLinks(d))
            .call(linkNonHoveredStyle.bind(0, d, sankey, false));
    }
}

function linkHoveredStyle(d, sankey, visitNodes, sankeyLink) {

    var label = sankeyLink.datum().link.label;

    sankeyLink.style('fill-opacity', 0.4);

    if(label) {
        ownTrace(sankey, d)
            .selectAll('.sankeyLink')
            .filter(function(l) {return l.link.label === label;})
            .style('fill-opacity', 0.4);
    }

    if(visitNodes) {
        ownTrace(sankey, d)
            .selectAll('.sankeyNode')
            .filter(relatedNodes(d))
            .call(nodeHoveredStyle);
    }
}

function linkNonHoveredStyle(d, sankey, visitNodes, sankeyLink) {

    var label = sankeyLink.datum().link.label;

    sankeyLink.style('fill-opacity', function(d) {return d.tinyColorAlpha;});

    if(label) {
        ownTrace(sankey, d)
            .selectAll('.sankeyLink')
            .filter(function(l) {return l.link.label === label;})
            .style('fill-opacity', function(d) {return d.tinyColorAlpha;});
    }

    if(visitNodes) {
        ownTrace(sankey, d)
            .selectAll('.sankeyNode')
            .filter(relatedNodes(d))
            .call(nodeNonHoveredStyle);
    }
}

module.exports = function plot(gd, calcData) {

    var fullLayout = gd._fullLayout;
    var svg = fullLayout._paper;
    var size = fullLayout._size;

    var linkSelect = function(element, d) {
        gd._hoverdata = [d.link];
        gd._hoverdata.trace = calcData.trace;
        Fx.click(gd, { target: true });
    };

    var linkHover = function(element, d, sankey) {
        d3.select(element).call(linkHoveredStyle.bind(0, d, sankey, true));
        Fx.hover(gd, d.link, 'sankey');
    };

    var linkHoverFollow = function(element, d) {
        var trace = gd._fullData[d.traceId];
        var ptNumber = d.originalIndex;
        var boundingBox = element.getBoundingClientRect();
        var hoverCenterX = boundingBox.left + boundingBox.width / 2;
        var hoverCenterY = boundingBox.top + boundingBox.height / 2;

        var tooltip = Fx.loneHover({
            x: hoverCenterX + window.scrollX,
            y: hoverCenterY + window.scrollY,
            name: d3.format(d.valueFormat)(d.link.value) + d.valueSuffix,
            text: [
                d.link.label,
                ['Source:', d.link.source.label].join(' '),
                ['Target:', d.link.target.label].join(' ')
            ].filter(renderableValuePresent).join('
'),
            color: Fx.castHoverOption(trace, ptNumber, 'bgcolor') || Color.addOpacity(d.tinyColorHue, 1),
            borderColor: Fx.castHoverOption(trace, ptNumber, 'bordercolor'),
            fontFamily: Fx.castHoverOption(trace, ptNumber, 'font.family'),
            fontSize: Fx.castHoverOption(trace, ptNumber, 'font.size'),
            fontColor: Fx.castHoverOption(trace, ptNumber, 'font.color'),
            idealAlign: d3.event.x < hoverCenterX ? 'right' : 'left'
        }, {
            container: fullLayout._hoverlayer.node(),
            outerContainer: fullLayout._paper.node()
        });

        makeTranslucent(tooltip, 0.65);
        makeTextContrasty(tooltip);
    };

    var linkUnhover = function(element, d, sankey) {
        d3.select(element).call(linkNonHoveredStyle.bind(0, d, sankey, true));
        gd.emit('plotly_unhover', {
            points: [d.link]
        });

        Fx.loneUnhover(fullLayout._hoverlayer.node());
    };

    var nodeSelect = function(element, d, sankey) {
        gd._hoverdata = [d.node];
        gd._hoverdata.trace = calcData.trace;
        d3.select(element).call(nodeNonHoveredStyle, d, sankey);
        Fx.click(gd, { target: true });
    };

    var nodeHover = function(element, d, sankey) {
        d3.select(element).call(nodeHoveredStyle, d, sankey);
        Fx.hover(gd, d.node, 'sankey');
    };

    var nodeHoverFollow = function(element, d) {
        var trace = gd._fullData[d.traceId];
        var ptNumber = d.originalIndex;
        var nodeRect = d3.select(element).select('.nodeRect');
        var boundingBox = nodeRect.node().getBoundingClientRect();
        var hoverCenterX0 = boundingBox.left - 2;
        var hoverCenterX1 = boundingBox.right + 2;
        var hoverCenterY = boundingBox.top + boundingBox.height / 4;

        var tooltip = Fx.loneHover({
            x0: hoverCenterX0 + window.scrollX,
            x1: hoverCenterX1 + window.scrollX,
            y: hoverCenterY + window.scrollY,
            name: d3.format(d.valueFormat)(d.node.value) + d.valueSuffix,
            text: [
                d.node.label,
                ['Incoming flow count:', d.node.targetLinks.length].join(' '),
                ['Outgoing flow count:', d.node.sourceLinks.length].join(' ')
            ].filter(renderableValuePresent).join('
'),
            color: Fx.castHoverOption(trace, ptNumber, 'bgcolor') || d.tinyColorHue,
            borderColor: Fx.castHoverOption(trace, ptNumber, 'bordercolor'),
            fontFamily: Fx.castHoverOption(trace, ptNumber, 'font.family'),
            fontSize: Fx.castHoverOption(trace, ptNumber, 'font.size'),
            fontColor: Fx.castHoverOption(trace, ptNumber, 'font.color'),
            idealAlign: 'left'
        }, {
            container: fullLayout._hoverlayer.node(),
            outerContainer: fullLayout._paper.node()
        });

        makeTranslucent(tooltip, 0.85);
        makeTextContrasty(tooltip);
    };

    var nodeUnhover = function(element, d, sankey) {

        d3.select(element).call(nodeNonHoveredStyle, d, sankey);
        gd.emit('plotly_unhover', {
            points: [d.node]
        });

        Fx.loneUnhover(fullLayout._hoverlayer.node());
    };

    render(
        svg,
        calcData,
        {
            width: size.w,
            height: size.h,
            margin: {
                t: size.t,
                r: size.r,
                b: size.b,
                l: size.l
            }
        },
        {
            linkEvents: {
                hover: linkHover,
                follow: linkHoverFollow,
                unhover: linkUnhover,
                select: linkSelect
            },
            nodeEvents: {
                hover: nodeHover,
                follow: nodeHoverFollow,
                unhover: nodeUnhover,
                select: nodeSelect
            }
        }
    );
};
<commit_msg>fixup: don't support array value in sankey hoverlabel settings<commit_after>/**
* Copyright 2012-2017, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

var d3 = require('d3');
var render = require('./render');
var Fx = require('../../components/fx');
var Color = require('../../components/color');
var Lib = require('../../lib');

function renderableValuePresent(d) {return d !== '';}

function ownTrace(selection, d) {
    return selection.filter(function(s) {return s.key === d.traceId;});
}

function makeTranslucent(element, alpha) {
    d3.select(element)
        .select('path')
        .style('fill-opacity', alpha);
    d3.select(element)
        .select('rect')
        .style('fill-opacity', alpha);
}

function makeTextContrasty(element) {
    d3.select(element)
        .select('text.name')
        .style('fill', 'black');
}

function relatedLinks(d) {
    return function(l) {
        return d.node.sourceLinks.indexOf(l.link) !== -1 || d.node.targetLinks.indexOf(l.link) !== -1;
    };
}

function relatedNodes(l) {
    return function(d) {
        return d.node.sourceLinks.indexOf(l.link) !== -1 || d.node.targetLinks.indexOf(l.link) !== -1;
    };
}

function nodeHoveredStyle(sankeyNode, d, sankey) {
    if(d && sankey) {
        ownTrace(sankey, d)
            .selectAll('.sankeyLink')
            .filter(relatedLinks(d))
            .call(linkHoveredStyle.bind(0, d, sankey, false));
    }
}

function nodeNonHoveredStyle(sankeyNode, d, sankey) {
    if(d && sankey) {
        ownTrace(sankey, d)
            .selectAll('.sankeyLink')
            .filter(relatedLinks(d))
            .call(linkNonHoveredStyle.bind(0, d, sankey, false));
    }
}

function linkHoveredStyle(d, sankey, visitNodes, sankeyLink) {

    var label = sankeyLink.datum().link.label;

    sankeyLink.style('fill-opacity', 0.4);

    if(label) {
        ownTrace(sankey, d)
            .selectAll('.sankeyLink')
            .filter(function(l) {return l.link.label === label;})
            .style('fill-opacity', 0.4);
    }

    if(visitNodes) {
        ownTrace(sankey, d)
            .selectAll('.sankeyNode')
            .filter(relatedNodes(d))
            .call(nodeHoveredStyle);
    }
}

function linkNonHoveredStyle(d, sankey, visitNodes, sankeyLink) {

    var label = sankeyLink.datum().link.label;

    sankeyLink.style('fill-opacity', function(d) {return d.tinyColorAlpha;});

    if(label) {
        ownTrace(sankey, d)
            .selectAll('.sankeyLink')
            .filter(function(l) {return l.link.label === label;})
            .style('fill-opacity', function(d) {return d.tinyColorAlpha;});
    }

    if(visitNodes) {
        ownTrace(sankey, d)
            .selectAll('.sankeyNode')
            .filter(relatedNodes(d))
            .call(nodeNonHoveredStyle);
    }
}

// does not support array values for now
function castHoverOption(trace, attr) {
    var labelOpts = trace.hoverlabel || {};
    var val = Lib.nestedProperty(labelOpts, attr).get();
    return Array.isArray(val) ? false : val;
}

module.exports = function plot(gd, calcData) {

    var fullLayout = gd._fullLayout;
    var svg = fullLayout._paper;
    var size = fullLayout._size;

    var linkSelect = function(element, d) {
        gd._hoverdata = [d.link];
        gd._hoverdata.trace = calcData.trace;
        Fx.click(gd, { target: true });
    };

    var linkHover = function(element, d, sankey) {
        d3.select(element).call(linkHoveredStyle.bind(0, d, sankey, true));
        Fx.hover(gd, d.link, 'sankey');
    };

    var linkHoverFollow = function(element, d) {
        var trace = gd._fullData[d.traceId];
        var boundingBox = element.getBoundingClientRect();
        var hoverCenterX = boundingBox.left + boundingBox.width / 2;
        var hoverCenterY = boundingBox.top + boundingBox.height / 2;

        var tooltip = Fx.loneHover({
            x: hoverCenterX + window.scrollX,
            y: hoverCenterY + window.scrollY,
            name: d3.format(d.valueFormat)(d.link.value) + d.valueSuffix,
            text: [
                d.link.label,
                ['Source:', d.link.source.label].join(' '),
                ['Target:', d.link.target.label].join(' ')
            ].filter(renderableValuePresent).join('
'),
            color: castHoverOption(trace, 'bgcolor') || Color.addOpacity(d.tinyColorHue, 1),
            borderColor: castHoverOption(trace, 'bordercolor'),
            fontFamily: castHoverOption(trace, 'font.family'),
            fontSize: castHoverOption(trace, 'font.size'),
            fontColor: castHoverOption(trace, 'font.color'),
            idealAlign: d3.event.x < hoverCenterX ? 'right' : 'left'
        }, {
            container: fullLayout._hoverlayer.node(),
            outerContainer: fullLayout._paper.node()
        });

        makeTranslucent(tooltip, 0.65);
        makeTextContrasty(tooltip);
    };

    var linkUnhover = function(element, d, sankey) {
        d3.select(element).call(linkNonHoveredStyle.bind(0, d, sankey, true));
        gd.emit('plotly_unhover', {
            points: [d.link]
        });

        Fx.loneUnhover(fullLayout._hoverlayer.node());
    };

    var nodeSelect = function(element, d, sankey) {
        gd._hoverdata = [d.node];
        gd._hoverdata.trace = calcData.trace;
        d3.select(element).call(nodeNonHoveredStyle, d, sankey);
        Fx.click(gd, { target: true });
    };

    var nodeHover = function(element, d, sankey) {
        d3.select(element).call(nodeHoveredStyle, d, sankey);
        Fx.hover(gd, d.node, 'sankey');
    };

    var nodeHoverFollow = function(element, d) {
        var trace = gd._fullData[d.traceId];
        var nodeRect = d3.select(element).select('.nodeRect');
        var boundingBox = nodeRect.node().getBoundingClientRect();
        var hoverCenterX0 = boundingBox.left - 2;
        var hoverCenterX1 = boundingBox.right + 2;
        var hoverCenterY = boundingBox.top + boundingBox.height / 4;

        var tooltip = Fx.loneHover({
            x0: hoverCenterX0 + window.scrollX,
            x1: hoverCenterX1 + window.scrollX,
            y: hoverCenterY + window.scrollY,
            name: d3.format(d.valueFormat)(d.node.value) + d.valueSuffix,
            text: [
                d.node.label,
                ['Incoming flow count:', d.node.targetLinks.length].join(' '),
                ['Outgoing flow count:', d.node.sourceLinks.length].join(' ')
            ].filter(renderableValuePresent).join('
'),
            color: castHoverOption(trace, 'bgcolor') || d.tinyColorHue,
            borderColor: castHoverOption(trace, 'bordercolor'),
            fontFamily: castHoverOption(trace, 'font.family'),
            fontSize: castHoverOption(trace, 'font.size'),
            fontColor: castHoverOption(trace, 'font.color'),
            idealAlign: 'left'
        }, {
            container: fullLayout._hoverlayer.node(),
            outerContainer: fullLayout._paper.node()
        });

        makeTranslucent(tooltip, 0.85);
        makeTextContrasty(tooltip);
    };

    var nodeUnhover = function(element, d, sankey) {

        d3.select(element).call(nodeNonHoveredStyle, d, sankey);
        gd.emit('plotly_unhover', {
            points: [d.node]
        });

        Fx.loneUnhover(fullLayout._hoverlayer.node());
    };

    render(
        svg,
        calcData,
        {
            width: size.w,
            height: size.h,
            margin: {
                t: size.t,
                r: size.r,
                b: size.b,
                l: size.l
            }
        },
        {
            linkEvents: {
                hover: linkHover,
                follow: linkHoverFollow,
                unhover: linkUnhover,
                select: linkSelect
            },
            nodeEvents: {
                hover: nodeHover,
                follow: nodeHoverFollow,
                unhover: nodeUnhover,
                select: nodeSelect
            }
        }
    );
};
<|endoftext|>


<commit_before>/*
 *   Can 'loadMenu() be cached? Check: https://gist.github.com/Integralist'
 */

define(function() {

  var loadMenu, cssdisabled, testcss, currstyle; // 4 variables global to this RequireJS module only.

  /*
   *  Dynamically create a form that looks like this:
   *
   *  <form action="/search.html" id="js-searchbox" class="form">
   *    <input type="text" name="q" id="tipue_search_input"
   *     placeholder="Search...">
   *    <input type="submit" id="tipue_search_button" value="Search">
   *  </form>
   */
  loadMenu = function() {
    var loadBox = document.getElementById("searchbox"),
      frag = document.createDocumentFragment(),
      form = document.createElement("form"),
      searchTextBox = document.createElement("input"),
      searchButton = document.createElement("input");

    // set attributes for form
    form.action = "/search.html";
    form.setAttribute("role", "search");
    form.id = "js-searchbox";
    form.setAttribute("class", "form");

    // set attributes for Search text box
    searchTextBox.type = "text";
    searchTextBox.name = "q";
    searchTextBox.id = "tipue_search_input";
    searchTextBox.placeholder = "Search...";

    // set attributes for Submit button
    searchButton.type = "submit";
    searchButton.setAttribute("class", "btnSearch");
    searchButton.value = "Search";

    // Arrange elements
    form.appendChild(searchTextBox);
    form.appendChild(searchButton);

    // Load arranged elements into document fragment
    frag.appendChild(form);

    // Load document fragment into #searchbox, which is already on the page
    loadBox.appendChild(frag);
  }

  /* IS CSS DISABLED ON PAGE-LOAD?
   *
   * A very clever way to test if CSS is enabled in the browser. First, create
   * a Boolean-type variable called 'cssdisabled' and set its value to 'false'.
   * Then create a <div> with an inline style of 'position:absolute' and place
   * it directly below the opening <body> tag. Then detect the <div> tag's
   * position property, but doing this is different between oldIE and everyone
   * else.
   *
   * Next, we check to see if the <div> tag has a 'currentStyle' property
   * attached to it: if it does, we're in IE8 or lower so we use
   * 'currentStyle' to store the value of the 'position' property inside of
   * variable called 'currstyle'. Then we check to see if the browser has a
   * 'getComputedStyle' property attached to it: if it does, we're in another
   * browser so we use 'getComputedStyle' to store the value of the 'position'
   * property inside of the 'currstyle' variable.
   *
   * Now that the <div>'s postion value is stored in 'currstyle' regardless of
   * what browser we're in, use a ternary operation to check its value. If
   * the value is 'static', it means that the browser was unable to detect the <div> tag's absolute positioning we set up earlier with "testcss.style.position = 'absolute'".  Therefore, CSS is disabled in the browser and the value of the 'cssdisabled' variable is 'true'. But if the value is anything else (in this case,
   * the 'absolute' value we set earlier), CSS is enabled so the value of our
   * 'cssdisabled' variable is 'false' (what it was set to initially). Our test is done so we can remove
   * the <div> tag from the page.
   *
   * The 'cssdisabled' varibale is still available to our module's namespace so if it's set
   * to 'false', it means that CSS is enabled in the browser so it's safe to run the loadMenu() method above and display our fancy search box. But 'cssdisabled' is set to
   * 'true', CSS is NOT enabled so don't run the loadMenu() method and, instead, return
   * a value of 'false' as it's a best practice in this case.
   *
   * We've set thngs up
   * so that if either any type of CSS is disabled (extenal stylesheets, embedded or inline), our
   * Google searchbox will show up.  All this means that a searchbox will
   * appear on our page regardless of whether or not either CSS and/or JS is
   * available in the browser.
   *
   *  Attribution for this trick goes to Kethinov who discussed it over at:
   *  http://bit.ly/11iKpZh
   */

  cssdisabled = false; // must be proven otherwise

  testcss = document.createElement('div');

  testcss.style.position = 'absolute';

  document.getElementsByTagName('body')[0].appendChild(testcss);

  if (testcss.currentStyle) {
    currstyle = testcss.currentStyle['position'];
  }

  else if (window.getComputedStyle) {
    currstyle = document.defaultView.getComputedStyle(testcss, null).getPropertyValue('position');
  }

  cssdisabled = (currstyle === 'static') ? true : false;

  document.getElementsByTagName('body')[0].removeChild(testcss);

  if (cssdisabled === false) {
    loadMenu();
  } else {
    return false;
  }

});<commit_msg>fix typo in comments of "js/buildform.js"<commit_after>/*
 *   Can 'loadMenu()' be cached? Check: https://gist.github.com/Integralist
 */

define(function() {

  var loadMenu, cssdisabled, testcss, currstyle; // 4 variables global to this RequireJS module only.

  /*
   *  Dynamically create a form that looks like this:
   *
   *  <form action="/search.html" id="js-searchbox" class="form">
   *    <input type="text" name="q" id="tipue_search_input"
   *     placeholder="Search...">
   *    <input type="submit" id="tipue_search_button" value="Search">
   *  </form>
   */
  loadMenu = function() {
    var loadBox = document.getElementById("searchbox"),
      frag = document.createDocumentFragment(),
      form = document.createElement("form"),
      searchTextBox = document.createElement("input"),
      searchButton = document.createElement("input");

    // set attributes for form
    form.action = "/search.html";
    form.setAttribute("role", "search");
    form.id = "js-searchbox";
    form.setAttribute("class", "form");

    // set attributes for Search text box
    searchTextBox.type = "text";
    searchTextBox.name = "q";
    searchTextBox.id = "tipue_search_input";
    searchTextBox.placeholder = "Search...";

    // set attributes for Submit button
    searchButton.type = "submit";
    searchButton.setAttribute("class", "btnSearch");
    searchButton.value = "Search";

    // Arrange elements
    form.appendChild(searchTextBox);
    form.appendChild(searchButton);

    // Load arranged elements into document fragment
    frag.appendChild(form);

    // Load document fragment into #searchbox, which is already on the page
    loadBox.appendChild(frag);
  }

  /* IS CSS DISABLED ON PAGE-LOAD?
   *
   * A very clever way to test if CSS is enabled in the browser. First, create
   * a Boolean-type variable called 'cssdisabled' and set its value to 'false'.
   * Then create a <div> with an inline style of 'position:absolute' and place
   * it directly below the opening <body> tag. Then detect the <div> tag's
   * position property, but doing this is different between oldIE and everyone
   * else.
   *
   * Next, we check to see if the <div> tag has a 'currentStyle' property
   * attached to it: if it does, we're in IE8 or lower so we use
   * 'currentStyle' to store the value of the 'position' property inside of
   * variable called 'currstyle'. Then we check to see if the browser has a
   * 'getComputedStyle' property attached to it: if it does, we're in another
   * browser so we use 'getComputedStyle' to store the value of the 'position'
   * property inside of the 'currstyle' variable.
   *
   * Now that the <div>'s postion value is stored in 'currstyle' regardless of
   * what browser we're in, use a ternary operation to check its value. If
   * the value is 'static', it means that the browser was unable to detect the <div> tag's absolute positioning we set up earlier with "testcss.style.position = 'absolute'".  Therefore, CSS is disabled in the browser and the value of the 'cssdisabled' variable is 'true'. But if the value is anything else (in this case,
   * the 'absolute' value we set earlier), CSS is enabled so the value of our
   * 'cssdisabled' variable is 'false' (what it was set to initially). Our test is done so we can remove
   * the <div> tag from the page.
   *
   * The 'cssdisabled' varibale is still available to our module's namespace so if it's set
   * to 'false', it means that CSS is enabled in the browser so it's safe to run the loadMenu() method above and display our fancy search box. But 'cssdisabled' is set to
   * 'true', CSS is NOT enabled so don't run the loadMenu() method and, instead, return
   * a value of 'false' as it's a best practice in this case.
   *
   * We've set thngs up
   * so that if either any type of CSS is disabled (extenal stylesheets, embedded or inline), our
   * Google searchbox will show up.  All this means that a searchbox will
   * appear on our page regardless of whether or not either CSS and/or JS is
   * available in the browser.
   *
   *  Attribution for this trick goes to Kethinov who discussed it over at:
   *  http://bit.ly/11iKpZh
   */

  cssdisabled = false; // must be proven otherwise

  testcss = document.createElement('div');

  testcss.style.position = 'absolute';

  document.getElementsByTagName('body')[0].appendChild(testcss);

  if (testcss.currentStyle) {
    currstyle = testcss.currentStyle['position'];
  }

  else if (window.getComputedStyle) {
    currstyle = document.defaultView.getComputedStyle(testcss, null).getPropertyValue('position');
  }

  cssdisabled = (currstyle === 'static') ? true : false;

  document.getElementsByTagName('body')[0].removeChild(testcss);

  if (cssdisabled === false) {
    loadMenu();
  } else {
    return false;
  }

});<|endoftext|>


<commit_before>var download = require('download-git-repo');
var path = require('path');
var ora = require('ora');
var home = require('user-home');

var vueCliRoot = '../vue-cli';
var logger = require(`${vueCliRoot}/lib/logger`);
var generate = require(`${vueCliRoot}/lib/generate`);
var checkVersion = require(`${vueCliRoot}/lib/check-version`)
var warnings = require(`${vueCliRoot}/lib/warnings`)

module.exports = runWrapper;

var template = 'webpack'
var hasSlash = false
var inPlace = false
var name = 'frontend'
var to = path.resolve(name);
var clone = false;

var tmp = path.join(home, '.vue-templates', template.replace(/\//g, '-'))

function runWrapper(scope, cb) {
  console.log(scope);
  template = template;
  hasSlash = template.indexOf('/') > -1
  to = scope.rootPath;
  run(cb);
}

/**
 * Check, download and generate the project.
 */

function run(cb) {
  // check if template is local
  if (/^[./]|(\w:)/.test(template)) {
    var templatePath = template.charAt(0) === '/' || /^\w:/.test(template)
      ? template
      : path.normalize(path.join(process.cwd(), template))
    if (exists(templatePath)) {
      generate(name, templatePath, to, cb)
    } else {
      logger.fatal('Local template "%s" not found.', template)
    }
  } else {
    checkVersion(function () {
      if (!hasSlash) {
        // use official templates
        var officialTemplate = 'vuejs-templates/' + template
        if (template.indexOf('#') !== -1) {
          downloadAndGenerate(officialTemplate, cb)
        } else {
          if (template.indexOf('-2.0') !== -1) {
            warnings.v2SuffixTemplatesDeprecated(template, inPlace ? '' : name)
            return
          }

          warnings.v2BranchIsNowDefault(template, inPlace ? '' : name)
          downloadAndGenerate(officialTemplate, cb)
        }
      } else {
        downloadAndGenerate(template, cb)
      }
    })
  }
}

/**
 * Download a generate from a template repo.
 *
 * @param {String} template
 */

function downloadAndGenerate (template, cb) {
  var spinner = ora('downloading template')
  spinner.start()
  download(template, tmp, { clone: clone }, function (err) {
    spinner.stop()
    if (err) logger.fatal('Failed to download repo ' + template + ': ' + err.message.trim())
    generate(name, tmp, to, cb)
  })
}
<commit_msg>remove useless console log<commit_after>var download = require('download-git-repo');
var path = require('path');
var ora = require('ora');
var home = require('user-home');

var vueCliRoot = '../vue-cli';
var logger = require(`${vueCliRoot}/lib/logger`);
var generate = require(`${vueCliRoot}/lib/generate`);
var checkVersion = require(`${vueCliRoot}/lib/check-version`)
var warnings = require(`${vueCliRoot}/lib/warnings`)

module.exports = runWrapper;

var template = 'webpack'
var hasSlash = false
var inPlace = false
var name = 'frontend'
var to = path.resolve(name);
var clone = false;

var tmp = path.join(home, '.vue-templates', template.replace(/\//g, '-'))

function runWrapper(scope, cb) {
  hasSlash = template.indexOf('/') > -1
  to = scope.rootPath;
  run(cb);
}

/**
 * Check, download and generate the project.
 */

function run(cb) {
  // check if template is local
  if (/^[./]|(\w:)/.test(template)) {
    var templatePath = template.charAt(0) === '/' || /^\w:/.test(template)
      ? template
      : path.normalize(path.join(process.cwd(), template))
    if (exists(templatePath)) {
      generate(name, templatePath, to, cb)
    } else {
      logger.fatal('Local template "%s" not found.', template)
    }
  } else {
    checkVersion(function () {
      if (!hasSlash) {
        // use official templates
        var officialTemplate = 'vuejs-templates/' + template
        if (template.indexOf('#') !== -1) {
          downloadAndGenerate(officialTemplate, cb)
        } else {
          if (template.indexOf('-2.0') !== -1) {
            warnings.v2SuffixTemplatesDeprecated(template, inPlace ? '' : name)
            return
          }

          warnings.v2BranchIsNowDefault(template, inPlace ? '' : name)
          downloadAndGenerate(officialTemplate, cb)
        }
      } else {
        downloadAndGenerate(template, cb)
      }
    })
  }
}

/**
 * Download a generate from a template repo.
 *
 * @param {String} template
 */

function downloadAndGenerate (template, cb) {
  var spinner = ora('downloading template')
  spinner.start()
  download(template, tmp, { clone: clone }, function (err) {
    spinner.stop()
    if (err) logger.fatal('Failed to download repo ' + template + ': ' + err.message.trim())
    generate(name, tmp, to, cb)
  })
}
<|endoftext|>


<commit_before>/**
 * Copyright 2013-2014 Facebook, Inc.
 *
 * 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.
 *
 * @emails react-core
 */

"use strict";

var ImmutableObject;
var Immutable;

/**
 * To perform performance testing of using `ImmutableObject` vs. not using
 * `ImmutableObject`, such testing must be done with __DEV__ set to false.
 */
describe('ImmutableObject', function() {
  var message;
  beforeEach(function() {
    ImmutableObject = require('ImmutableObject');
    Immutable = require('Immutable');
  });

  var testDev = function(message, testFunc) {
    it(message, function() {
      var old = window.__DEV__;
      window.__DEV__ = true;
      testFunc();
      window.__DEV__ = old;
    });
  };

  var testProd = function(message, testFunc) {
    it(message, function() {
      // Temporarily enter production mode
      var old = window.__DEV__;
      window.__DEV__ = false;
      testFunc();
      window.__DEV__ = old;
    });
  };

  var testDevAndProd = function(message, testFunc) {
    testDev(message + ':DEV', testFunc);
    testProd(message + ':PROD', testFunc);
  };

  /**
   * Deep clone a JSON-ifiable object. Jasmine doesn't support comparing frozen
   * objects, so we clone before asserting equality.
   */
  var deepClone = function(obj) {
    return JSON.parse(JSON.stringify(obj));
  };

  testDev('should be running in DEV', function() {
    expect(window.__DEV__).toBe(true);
  });

  testDev('should require initial map to be an object', function() {
    expect(function() {
      new ImmutableObject([1,2,3]);
    }).toThrow();

    expect(function() {
      new ImmutableObject('asdf');
    }).toThrow();

    expect(function() {
      new ImmutableObject({oldField: 'asdf', fieldTwo: null});
    }).not.toThrow();
  });

  testDevAndProd('should extend Immutable', function() {
    var object = new ImmutableObject({foo: 'bar'});
    expect (object instanceof Immutable).toBe(true);
    expect (object instanceof ImmutableObject).toBe(true);
  });

  testDev('should not exceed maximum call stack size with nodes', function() {
    var node = document.createElement('div');
    var object = new ImmutableObject({node: node});
    expect(object.node).toBe(node);
  });

  testDevAndProd('should not throw when not mutating directly', function() {
    var io = new ImmutableObject({oldField: 'asdf'});
    expect(function() {
      ImmutableObject.set(io, {newField: null}); // not a mutation!
    }).not.toThrow();
  });

  testDev('should prevent shallow field addition when strict', function() {
    if (window.callPhantom) return;
    expect(function() {
      var io = new ImmutableObject({oldField: 'asdf'});
      io.newField = 'this will not work';
    }).toThrow();
  });

  testDev('should prevent shallow field mutation when strict', function() {
    if (window.callPhantom) return;
    expect(function() {
      var io = new ImmutableObject({oldField: 'asdf'});
      io.oldField = 'this will not work!';
    }).toThrow();
  });

  testDev('should prevent deep field addition when strict', function() {
    if (window.callPhantom) return;
    expect(function() {
      var io =
        new ImmutableObject({shallowField: {deepField: {oldField: null}}});
      io.shallowField.deepField.oldField = 'this will not work!';
    }).toThrow();
  });

  testDev('should prevent deep field mutation when strict', function() {
    if (window.callPhantom) return;
    expect(function() {
      var io =
        new ImmutableObject({shallowField: {deepField: {oldField: null}}});
      io.shallowField.deepField.newField = 'this will not work!';
    }).toThrow();
  });

  testDevAndProd(
    'should create object with same structure when set with {}',
    function() {
      var beforeIO =
        new ImmutableObject({shallowField: {deepField: {oldField: null}}});
      var afterIO = ImmutableObject.set(beforeIO, {});
      expect(afterIO).toEqual(beforeIO);
      expect(afterIO).not.toBe(beforeIO);
    }
  );

  testDevAndProd(
    'should create distinct object with shallow field insertion',
    function() {
      if (window.callPhantom) return;
      var beforeStructure = {
        oldShallowField: {
          deepField: {
            oldField: null
          }
        }
      };

      var delta = {
        newShallowField: 'newShallowFieldHere'
      };

      var expectedAfterStructure = {
        oldShallowField: {
          deepField: {
            oldField: null
          }
        },
        newShallowField: 'newShallowFieldHere'
      };

      var beforeIO = new ImmutableObject(beforeStructure);
      var afterIO = ImmutableObject.set(beforeIO, delta);
      expect(deepClone(afterIO)).toEqual(expectedAfterStructure);
      expect(afterIO).not.toBe(beforeIO);
    }
  );

  testDevAndProd(
    'should create distinct object with shallow field mutation',
      function() {
      if (window.callPhantom) return;
      var beforeStructure = {
        oldShallowField: {
          deepField: {
            oldField: null
          }
        }
      };

      var delta = {
        oldShallowField: 'this will clobber the old field'
      };

      var expectedAfterStructure = {
        oldShallowField: 'this will clobber the old field'
      };

      var beforeIO = new ImmutableObject(beforeStructure);
      var afterIO = ImmutableObject.set(beforeIO, delta);
      expect(deepClone(afterIO)).toEqual(expectedAfterStructure);
      expect(afterIO).not.toBe(beforeIO);
    }
  );

  message = 'should create distinct object with deep field insertion';
  testDevAndProd(message, function() {
    if (window.callPhantom) return;
    var beforeStructure = {
      oldShallowField: {
        deepField: {
          oldField: null
        }
      }
    };

    var delta = {
      oldShallowField: {newDeepField: 'hello'}
    };

    // ImmutableObject does not yet support deep merging with
    // ImmutableObject.set().
    var expectedAfterStructure = {
      oldShallowField: {newDeepField: 'hello'}
    };

    var beforeIO = new ImmutableObject(beforeStructure);
    var afterIO = ImmutableObject.set(beforeIO, delta);
    expect(deepClone(afterIO)).toEqual(expectedAfterStructure);
    expect(afterIO).not.toBe(beforeIO);
  });

  message =
    'should tolerate arrays at deeper levels and prevent mutation on them';
  testDev(message, function() {
    if (window.callPhantom) {
      // PhantomJS has a bug with Object.freeze and Arrays.
      // https://github.com/ariya/phantomjs/issues/10817
      return;
    }
    var beforeStructure = {
      shallowField: [1,'second field',3]
    };
    var io = new ImmutableObject(beforeStructure);
    expect(function() {
      io.newField = 'nope!';
    }).toThrow();
    expect(function() {
      io.shallowField[0] = 'nope!';
    }).toThrow();
    expect(io.shallowField[1]).toEqual('second field');
  });

  message = 'should provide a setProperty interface as sugar for set()';
  testDevAndProd(message, function() {
    if (window.callPhantom) return;
    var beforeIO = new ImmutableObject({initialField: null});
    var afterIO =
      ImmutableObject.setProperty(beforeIO, 'anotherField', 'anotherValue');
    expect(deepClone(afterIO)).toEqual({
      initialField: null,
      anotherField: 'anotherValue'
    });
    expect(afterIO).not.toBe(beforeIO);
  });

  message = 'should recursively create distinct objects when deep copying';
  testDevAndProd(message, function() {
    if (window.callPhantom) return;
    var beforeIO = new ImmutableObject({
      a: {b: 'b', c: {}, d: 'd', e: new ImmutableObject({f: 'f'}) }
    });
    var afterIO = ImmutableObject.setDeep(beforeIO, {
      a: {b: {}, c: 'C', e: {f: 'F', g: 'G'}, h: 'H'}
    });
    expect(deepClone(afterIO)).toEqual({
      a: {b: {}, c: 'C', d: 'd', e: {f: 'F', g: 'G'}, h: 'H'}
    });
    expect(afterIO).not.toBe(beforeIO);
    expect(afterIO.a).not.toBe(beforeIO.a);
    expect(afterIO.a.e).not.toBe(beforeIO.a.e);
  });

  testDevAndProd('should deep copy member immutability', function() {
    if (window.callPhantom) return;
    var beforeIO = new ImmutableObject({
      a: {b: new ImmutableObject({c: 'c'}), e: {f: 'f'}}
    });
    var afterIO = ImmutableObject.setDeep(beforeIO, {
      a: {b: {d: 'D'}, e: new ImmutableObject({g: 'G'})}
    });
    expect(deepClone(afterIO)).toEqual({
      a: {b: {c: 'c', d: 'D'}, e: {f: 'f', g: 'G'}}
    });
    expect(afterIO instanceof Immutable).toBe(true);
    expect(afterIO.a.b instanceof Immutable).toBe(true);
    expect(afterIO.a.e instanceof Immutable).toBe(true);
  });
});

<commit_msg>Delete ImmutableObject-test.js<commit_after><|endoftext|>


<commit_before>'use strict';

describe('networks', function () {

  var $scope, element, $routeParams, q, deferred, $httpBackend, networkFactory, zoneFactory, $location;

  beforeEach(module('templates'));

  beforeEach(module('myApp', function($provide) {
    networkFactory = {
      query: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      destroy: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      update: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      }
    };
    zoneFactory = {
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
    };
    $provide.value("Zone", zoneFactory);
    $provide.value("Network", networkFactory);
  }));

  beforeEach(inject(function($injector) {
    $httpBackend = $injector.get('$httpBackend');
    $httpBackend.whenGET('/translations/en_GB.json').respond("");
  }));

  describe('lists the networks for a location', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector) {
      $scope = $rootScope;
      q = $q;
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.q = 'my-filter';
      $routeParams.page = '10';
      $routeParams.per = '100';
      $scope.loading = true;
      var elem = angular.element('<list-networks loading="loading"></list-networks>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    it("should set the default scopes vals", function() {
      spyOn(networkFactory, 'get').and.callThrough();
      expect(element.isolateScope().location.slug).toEqual('xxx');

      var results = [{ id: 123 }];
      deferred.resolve(results);
      $scope.$apply();

      expect(element.isolateScope().menu.length).toEqual(4);
      expect(element.isolateScope().menu[0].name).toEqual('Edit Settings');
      expect(element.isolateScope().menu[0].type).toEqual('settings');
      expect(element.isolateScope().menu[1].name).toEqual('Change SSID');
      expect(element.isolateScope().menu[1].type).toEqual('ssid');
      expect(element.isolateScope().menu[2].name).toEqual('Share Details');
      expect(element.isolateScope().menu[2].type).toEqual('share');
      expect(element.isolateScope().menu[3].name).toEqual('Delete Network');
      expect(element.isolateScope().menu[3].type).toEqual('delete');

      expect(element.isolateScope().query.page).toEqual('10');
      expect(element.isolateScope().query.limit).toEqual('100');
    });

    it("should get the networks and save to scope", function() {
      spyOn(networkFactory, 'get').and.callThrough();
      var results = [{ id: 123 }];
      deferred.resolve(results);
      $scope.$apply();
      expect(element.isolateScope().networks[0].id).toEqual(123);
    });

    it("should update the band to 2.4Ghz or 5Ghz", function() {
      element.isolateScope().updateBand('two');
      expect(element.isolateScope().band).toEqual('two');

      element.isolateScope().updateBand('five');
      expect(element.isolateScope().band).toEqual('five');

      element.isolateScope().updateBand();
      expect(element.isolateScope().band).toEqual('');
    });

    it("should delete a network and remove from array", function() {
      spyOn(networkFactory, 'destroy').and.callThrough();
      var network = { id: 123 };
      element.isolateScope().networks = [network];

      element.isolateScope().destroy(network)
      deferred.resolve();
      $scope.$apply();
      expect(element.isolateScope().networks.length).toEqual(0);
    });

    // To fix - breaks since we need to sort the errors popup
    xit("should not delete a network and not remove from array", function() {
      spyOn(networkFactory, 'destroy').and.callThrough();
      var network = { id: 123 };
      element.isolateScope().networks = [network];

      element.isolateScope().destroy(network)
      deferred.reject({errors: {data: [{a: 123}]}});
      $scope.$apply();
      expect(element.isolateScope().networks.length).toEqual(1);
    });

    it("should update a network", function() {
      spyOn(networkFactory, 'update').and.callThrough();
      var network = { id: 123, state: 'foo' };
      element.isolateScope().networks = [network];

      element.isolateScope().update(network)
      deferred.resolve();
      $scope.$apply();
      expect(element.isolateScope().networks[0].state).toEqual(undefined);
    });

    // To fix - breaks since we need to sort the errors popup
    xit("should fail to update a network", function() {
      spyOn(networkFactory, 'update').and.callThrough();
      var network = { id: 123, state: 'foo' };
      element.isolateScope().networks = [network];

      element.isolateScope().update(network)
      deferred.reject();
      $scope.$apply();
      expect(element.isolateScope().networks[0].state).toEqual(undefined);
    });

  });

  describe('creates new network for a location', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector) {
      $scope = $rootScope;
      q = $q;
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.q = 'my-filter';
      $routeParams.page = '10';
      $routeParams.per = '100';
      $scope.loading = true;
      var elem = angular.element('<new-network loading="loading"></new-network>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    it("should set the default scopes vals", function() {
      spyOn(networkFactory, 'get').and.callThrough();
      expect(element.isolateScope().location.slug).toEqual('xxx');

      // Would prefer to not use a scope //
      element.isolateScope().init();

      var cf = [
        {key: 'Danger', value:'Danger'},
        {key: 'Adult', value: 'Adult'},
        {key: 'Security', value: 'Security'},
        {key: 'Family', value: 'Family'},
        {key: 'Off', value: 'Off'}
      ];

      expect(element.isolateScope().content_filters[0].key).toEqual(cf[0].key);
      expect(element.isolateScope().content_filters[0].value).toEqual(cf[0].value);
      expect(element.isolateScope().content_filters[1].key).toEqual(cf[1].key);
      expect(element.isolateScope().content_filters[1].value).toEqual(cf[1].value);
      expect(element.isolateScope().content_filters[2].key).toEqual(cf[2].key);
      expect(element.isolateScope().content_filters[2].value).toEqual(cf[2].value);
      expect(element.isolateScope().content_filters[3].key).toEqual(cf[3].key);
      expect(element.isolateScope().content_filters[3].value).toEqual(cf[3].value);
      expect(element.isolateScope().content_filters[4].key).toEqual(cf[4].key);
      expect(element.isolateScope().content_filters[4].value).toEqual(cf[4].value);

      var network = element.isolateScope().network
      expect(network.ssid).toEqual('My WiFi Network')
      expect(network.access_type).toEqual('password')
      expect(network.encryption_type).toEqual('psk2')
      expect(network.band_steering).toEqual(true)
      expect(network.active).toEqual(true)
      expect(network.interface_ipaddr === '').toEqual(false)
      expect(network.dhcp_enabled).toEqual(true)
      expect(network.dns_1).toEqual('8.8.8.8')
      expect(network.dns_2).toEqual('8.8.4.4')
      expect(network.interface_netmask).toEqual(24)
      expect(network.use_ps_radius).toEqual(true)
      expect(network.captive_portal_ps).toEqual(true)
      expect(network.content_filter).toEqual('Off')
      expect(network.captive_portal_enabled).toEqual(false)
    });

  });

  describe('displays the network for a location', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector, _$location_) {
      $scope = $rootScope;
      q = $q;
      $location = _$location_
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.q = 'my-filter';
      $routeParams.page = '10';
      $routeParams.per = '100';
      $scope.loading = true;
      var elem = angular.element('<display-network emoji-picker="{content: '.ssid-input', pickerPosition: 'bottom'}" class="ssid-input" loading="loading"></display-network>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    it("should set the default vars for the network", function() {
      spyOn(networkFactory, 'query').and.callThrough();
      expect(element.isolateScope().location.slug).toEqual('xxx');

      var network = { id: '123' };
      deferred.resolve(network);
      $scope.$apply();

      var cf = [
        { key: 'Off', value: 'off' },
        { key: 'Allow White-listed Clients', value: 'allow'},
        { key: 'Block Banned Clients', value: 'deny'}
      ];

      expect(element.isolateScope().client_filters[0].key).toEqual('Off');
      expect(element.isolateScope().client_filters[0].value).toEqual('off');
      expect(element.isolateScope().client_filters[1].key).toEqual('Allow White-listed Clients');
      expect(element.isolateScope().client_filters[1].value).toEqual('allow');
      expect(element.isolateScope().client_filters[2].key).toEqual('Block Banned Clients');
      expect(element.isolateScope().client_filters[2].value).toEqual('deny');

      expect(element.isolateScope().menu.length).toEqual(1);
      expect(element.isolateScope().menu[0].name).toEqual('Delete Network');
      expect(element.isolateScope().menu[0].type).toEqual('delete');
    });

    it("should show the network", function() {
      spyOn(networkFactory, 'query').and.callThrough();

      var network = { id: '123', ssid_hidden: '1' };
      deferred.resolve(network);
      $scope.$apply();

      expect(element.isolateScope().network.id).toEqual('123');
      expect(element.isolateScope().network.ssid_hidden).toEqual(false);
      expect(element.isolateScope().short_ip).toEqual('10.168.210.');
    });

    it("should destroy the network", function() {
      spyOn(networkFactory, 'destroy').and.callThrough();

      var network = { id: '123', ssid_hidden: '1' };
      element.isolateScope().network = network;
      element.isolateScope().destroy();
      deferred.resolve(network);
      $scope.$apply();
      expect($location.path()).toEqual('/locations/xxx/networks');
    });
  });
});
<commit_msg>emoji tests<commit_after>'use strict';

describe('networks', function () {

  var $scope, element, $routeParams, q, deferred, $httpBackend, networkFactory, zoneFactory, $location;

  beforeEach(module('templates'));

  beforeEach(module('myApp', function($provide) {
    networkFactory = {
      query: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      destroy: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      update: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      }
    };
    zoneFactory = {
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
    };
    $provide.value("Zone", zoneFactory);
    $provide.value("Network", networkFactory);
  }));

  beforeEach(inject(function($injector) {
    $httpBackend = $injector.get('$httpBackend');
    $httpBackend.whenGET('/translations/en_GB.json').respond("");
  }));

  describe('lists the networks for a location', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector) {
      $scope = $rootScope;
      q = $q;
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.q = 'my-filter';
      $routeParams.page = '10';
      $routeParams.per = '100';
      $scope.loading = true;
      var elem = angular.element('<list-networks loading="loading"></list-networks>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    it("should set the default scopes vals", function() {
      spyOn(networkFactory, 'get').and.callThrough();
      expect(element.isolateScope().location.slug).toEqual('xxx');

      var results = [{ id: 123 }];
      deferred.resolve(results);
      $scope.$apply();

      expect(element.isolateScope().menu.length).toEqual(4);
      expect(element.isolateScope().menu[0].name).toEqual('Edit Settings');
      expect(element.isolateScope().menu[0].type).toEqual('settings');
      expect(element.isolateScope().menu[1].name).toEqual('Change SSID');
      expect(element.isolateScope().menu[1].type).toEqual('ssid');
      expect(element.isolateScope().menu[2].name).toEqual('Share Details');
      expect(element.isolateScope().menu[2].type).toEqual('share');
      expect(element.isolateScope().menu[3].name).toEqual('Delete Network');
      expect(element.isolateScope().menu[3].type).toEqual('delete');

      expect(element.isolateScope().query.page).toEqual('10');
      expect(element.isolateScope().query.limit).toEqual('100');
    });

    it("should get the networks and save to scope", function() {
      spyOn(networkFactory, 'get').and.callThrough();
      var results = [{ id: 123 }];
      deferred.resolve(results);
      $scope.$apply();
      expect(element.isolateScope().networks[0].id).toEqual(123);
    });

    it("should update the band to 2.4Ghz or 5Ghz", function() {
      element.isolateScope().updateBand('two');
      expect(element.isolateScope().band).toEqual('two');

      element.isolateScope().updateBand('five');
      expect(element.isolateScope().band).toEqual('five');

      element.isolateScope().updateBand();
      expect(element.isolateScope().band).toEqual('');
    });

    it("should delete a network and remove from array", function() {
      spyOn(networkFactory, 'destroy').and.callThrough();
      var network = { id: 123 };
      element.isolateScope().networks = [network];

      element.isolateScope().destroy(network)
      deferred.resolve();
      $scope.$apply();
      expect(element.isolateScope().networks.length).toEqual(0);
    });

    // To fix - breaks since we need to sort the errors popup
    xit("should not delete a network and not remove from array", function() {
      spyOn(networkFactory, 'destroy').and.callThrough();
      var network = { id: 123 };
      element.isolateScope().networks = [network];

      element.isolateScope().destroy(network)
      deferred.reject({errors: {data: [{a: 123}]}});
      $scope.$apply();
      expect(element.isolateScope().networks.length).toEqual(1);
    });

    it("should update a network", function() {
      spyOn(networkFactory, 'update').and.callThrough();
      var network = { id: 123, state: 'foo' };
      element.isolateScope().networks = [network];

      element.isolateScope().update(network)
      deferred.resolve();
      $scope.$apply();
      expect(element.isolateScope().networks[0].state).toEqual(undefined);
    });

    // To fix - breaks since we need to sort the errors popup
    xit("should fail to update a network", function() {
      spyOn(networkFactory, 'update').and.callThrough();
      var network = { id: 123, state: 'foo' };
      element.isolateScope().networks = [network];

      element.isolateScope().update(network)
      deferred.reject();
      $scope.$apply();
      expect(element.isolateScope().networks[0].state).toEqual(undefined);
    });

  });

  describe('creates new network for a location', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector) {
      $scope = $rootScope;
      q = $q;
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.q = 'my-filter';
      $routeParams.page = '10';
      $routeParams.per = '100';
      $scope.loading = true;
      var elem = angular.element('<new-network loading="loading"></new-network>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    it("should set the default scopes vals", function() {
      spyOn(networkFactory, 'get').and.callThrough();
      expect(element.isolateScope().location.slug).toEqual('xxx');

      // Would prefer to not use a scope //
      element.isolateScope().init();

      var cf = [
        {key: 'Danger', value:'Danger'},
        {key: 'Adult', value: 'Adult'},
        {key: 'Security', value: 'Security'},
        {key: 'Family', value: 'Family'},
        {key: 'Off', value: 'Off'}
      ];

      expect(element.isolateScope().content_filters[0].key).toEqual(cf[0].key);
      expect(element.isolateScope().content_filters[0].value).toEqual(cf[0].value);
      expect(element.isolateScope().content_filters[1].key).toEqual(cf[1].key);
      expect(element.isolateScope().content_filters[1].value).toEqual(cf[1].value);
      expect(element.isolateScope().content_filters[2].key).toEqual(cf[2].key);
      expect(element.isolateScope().content_filters[2].value).toEqual(cf[2].value);
      expect(element.isolateScope().content_filters[3].key).toEqual(cf[3].key);
      expect(element.isolateScope().content_filters[3].value).toEqual(cf[3].value);
      expect(element.isolateScope().content_filters[4].key).toEqual(cf[4].key);
      expect(element.isolateScope().content_filters[4].value).toEqual(cf[4].value);

      var network = element.isolateScope().network
      expect(network.ssid).toEqual('My WiFi Network')
      expect(network.access_type).toEqual('password')
      expect(network.encryption_type).toEqual('psk2')
      expect(network.band_steering).toEqual(true)
      expect(network.active).toEqual(true)
      expect(network.interface_ipaddr === '').toEqual(false)
      expect(network.dhcp_enabled).toEqual(true)
      expect(network.dns_1).toEqual('8.8.8.8')
      expect(network.dns_2).toEqual('8.8.4.4')
      expect(network.interface_netmask).toEqual(24)
      expect(network.use_ps_radius).toEqual(true)
      expect(network.captive_portal_ps).toEqual(true)
      expect(network.content_filter).toEqual('Off')
      expect(network.captive_portal_enabled).toEqual(false)
    });

  });

  describe('displays the network for a location', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector, _$location_) {
      $scope = $rootScope;
      q = $q;
      $location = _$location_
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.q = 'my-filter';
      $routeParams.page = '10';
      $routeParams.per = '100';
      $scope.loading = true;
      var elem = angular.element('<display-network emoji-picker="{content: \".ssid-input\", pickerPosition: \"bottom\"}" class="ssid-input" loading="loading"></display-network>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    it("should set the default vars for the network", function() {
      spyOn(networkFactory, 'query').and.callThrough();
      expect(element.isolateScope().location.slug).toEqual('xxx');

      var network = { id: '123' };
      deferred.resolve(network);
      $scope.$apply();

      var cf = [
        { key: 'Off', value: 'off' },
        { key: 'Allow White-listed Clients', value: 'allow'},
        { key: 'Block Banned Clients', value: 'deny'}
      ];

      expect(element.isolateScope().client_filters[0].key).toEqual('Off');
      expect(element.isolateScope().client_filters[0].value).toEqual('off');
      expect(element.isolateScope().client_filters[1].key).toEqual('Allow White-listed Clients');
      expect(element.isolateScope().client_filters[1].value).toEqual('allow');
      expect(element.isolateScope().client_filters[2].key).toEqual('Block Banned Clients');
      expect(element.isolateScope().client_filters[2].value).toEqual('deny');

      expect(element.isolateScope().menu.length).toEqual(1);
      expect(element.isolateScope().menu[0].name).toEqual('Delete Network');
      expect(element.isolateScope().menu[0].type).toEqual('delete');
    });

    it("should show the network", function() {
      spyOn(networkFactory, 'query').and.callThrough();

      var network = { id: '123', ssid_hidden: '1' };
      deferred.resolve(network);
      $scope.$apply();

      expect(element.isolateScope().network.id).toEqual('123');
      expect(element.isolateScope().network.ssid_hidden).toEqual(false);
      expect(element.isolateScope().short_ip).toEqual('10.168.210.');
    });

    it("should destroy the network", function() {
      spyOn(networkFactory, 'destroy').and.callThrough();

      var network = { id: '123', ssid_hidden: '1' };
      element.isolateScope().network = network;
      element.isolateScope().destroy();
      deferred.resolve(network);
      $scope.$apply();
      expect($location.path()).toEqual('/locations/xxx/networks');
    });
  });
});
<|endoftext|>


<commit_before>
exports = module.exports = lifecycle
exports.cmd = cmd

var log = require("npmlog")
  , exec = require("./exec.js")
  , npm = require("../npm.js")
  , path = require("path")
  , fs = require("graceful-fs")
  , chain = require("slide").chain
  , constants = require("constants")
  , Stream = require("stream").Stream
  , PATH = "PATH"

// windows calls it's path "Path" usually, but this is not guaranteed.
if (process.platform === "win32") {
  PATH = "Path"
  Object.keys(process.env).forEach(function (e) {
    if (e.match(/^PATH$/i)) {
      PATH = e
    }
  })
}

function lifecycle (pkg, stage, wd, unsafe, failOk, cb) {
  if (typeof cb !== "function") cb = failOk, failOk = false
  if (typeof cb !== "function") cb = unsafe, unsafe = false
  if (typeof cb !== "function") cb = wd, wd = null

  while (pkg && pkg._data) pkg = pkg._data
  if (!pkg) return cb(new Error("Invalid package data"))

  log.info(stage, pkg._id)
  if (!pkg.scripts) pkg.scripts = {}

  validWd(wd || path.resolve(npm.dir, pkg.name), function (er, wd) {
    if (er) return cb(er)

    unsafe = unsafe || npm.config.get("unsafe-perm")

    if ((wd.indexOf(npm.dir) !== 0 || path.basename(wd) !== pkg.name)
        && !unsafe && pkg.scripts[stage]) {
      log.warn( "cannot run in wd", "%s %s (wd=%s)"
              , pkg._id, pkg.scripts[stage], wd)
      return cb()
    }

    // set the env variables, then run scripts as a child process.
    var env = makeEnv(pkg)
    env.npm_lifecycle_event = stage

    // "nobody" typically doesn't have permission to write to /tmp
    // even if it's never used, sh freaks out.
    if (!npm.config.get("unsafe-perm")) env.TMPDIR = wd

    lifecycle_(pkg, stage, wd, env, unsafe, failOk, cb)
  })
}

function checkForLink (pkg, cb) {
  var f = path.join(npm.dir, pkg.name)
  fs.lstat(f, function (er, s) {
    cb(null, !(er || !s.isSymbolicLink()))
  })
}

function lifecycle_ (pkg, stage, wd, env, unsafe, failOk, cb) {
  var pathArr = []
    , p = wd.split("node_modules")
    , acc = path.resolve(p.shift())
  p.forEach(function (pp) {
    pathArr.unshift(path.join(acc, "node_modules", ".bin"))
    acc = path.join(acc, "node_modules", pp)
  })
  pathArr.unshift(path.join(acc, "node_modules", ".bin"))

  // we also unshift the bundled node-gyp-bin folder so that
  // the bundled one will be used for installing things.
  pathArr.unshift(path.join(__dirname, "..", "..", "bin", "node-gyp-bin"))

  if (env[PATH]) pathArr.push(env[PATH])
  env[PATH] = pathArr.join(process.platform === "win32" ? ";" : ":")

  var packageLifecycle = pkg.scripts && pkg.scripts.hasOwnProperty(stage)

  if (packageLifecycle) {
    // define this here so it's available to all scripts.
    env.npm_lifecycle_script = pkg.scripts[stage]
  }

  if (failOk) {
    cb = (function (cb_) { return function (er) {
      if (er) log.warn("continuing anyway", er.message)
      cb_()
    }})(cb)
  }

  if (npm.config.get("force")) {
    cb = (function (cb_) { return function (er) {
      if (er) log.info("forced, continuing", er)
      cb_()
    }})(cb)
  }

  chain
    ( [ packageLifecycle && [runPackageLifecycle, pkg, env, wd, unsafe]
      , [runHookLifecycle, pkg, env, wd, unsafe] ]
    , cb )
}

function validWd (d, cb) {
  fs.stat(d, function (er, st) {
    if (er || !st.isDirectory()) {
      var p = path.dirname(d)
      if (p === d) {
        return cb(new Error("Could not find suitable wd"))
      }
      return validWd(p, cb)
    }
    return cb(null, d)
  })
}

function runPackageLifecycle (pkg, env, wd, unsafe, cb) {
  // run package lifecycle scripts in the package root, or the nearest parent.
  var stage = env.npm_lifecycle_event
    , user = unsafe ? null : npm.config.get("user")
    , group = unsafe ? null : npm.config.get("group")
    , cmd = env.npm_lifecycle_script
    , sh = "sh"
    , shFlag = "-c"

  if (process.platform === "win32") {
    sh = "cmd"
    shFlag = "/c"
  }

  log.verbose("unsafe-perm in lifecycle", unsafe)

  var note = "\n> " + pkg._id + " " + stage + " " + wd
           + "\n> " + cmd + "\n"

  console.log(note)
  exec( sh, [shFlag, cmd], env, true, wd
      , user, group
      , function (er, code, stdout, stderr) {
    if (er && !npm.ROLLBACK) {
      log.info(pkg._id, "Failed to exec "+stage+" script")
      er.message = pkg._id + " "
                 + stage + ": `" + env.npm_lifecycle_script+"`\n"
                 + er.message
      if (er.code !== "EPERM") {
        er.code = "ELIFECYCLE"
      }
      er.pkgid = pkg._id
      er.stage = stage
      er.script = env.npm_lifecycle_script
      er.pkgname = pkg.name
      return cb(er)
    } else if (er) {
      log.error(pkg._id+"."+stage, er)
      log.error(pkg._id+"."+stage, "continuing anyway")
      return cb()
    }
    cb(er)
  })
}

function runHookLifecycle (pkg, env, wd, unsafe, cb) {
  // check for a hook script, run if present.
  var stage = env.npm_lifecycle_event
    , hook = path.join(npm.dir, ".hooks", stage)
    , user = unsafe ? null : npm.config.get("user")
    , group = unsafe ? null : npm.config.get("group")
    , cmd = hook

  fs.stat(hook, function (er) {
    if (er) return cb()

    exec( "sh", ["-c", cmd], env, true, wd
        , user, group
        , function (er) {
      if (er) {
        er.message += "\nFailed to exec "+stage+" hook script"
        log.info(pkg._id, er)
      }
      if (npm.ROLLBACK) return cb()
      cb(er)
    })
  })
}

function makeEnv (data, prefix, env) {
  prefix = prefix || "npm_package_"
  if (!env) {
    env = {}
    for (var i in process.env) if (!i.match(/^npm_/)) {
      env[i] = process.env[i]
    }

    // npat asks for tap output
    if (npm.config.get("npat")) env.TAP = 1

    // express and others respect the NODE_ENV value.
    if (npm.config.get("production")) env.NODE_ENV = "production"

  } else if (!data.hasOwnProperty("_lifecycleEnv")) {
    Object.defineProperty(data, "_lifecycleEnv",
      { value : env
      , enumerable : false
      })
  }

  for (var i in data) if (i.charAt(0) !== "_") {
    var envKey = (prefix+i).replace(/[^a-zA-Z0-9_]/g, '_')
    if (data[i] && typeof(data[i]) === "object") {
      try {
        // quick and dirty detection for cyclical structures
        JSON.stringify(data[i])
        makeEnv(data[i], envKey+"_", env)
      } catch (ex) {
        // usually these are package objects.
        // just get the path and basic details.
        var d = data[i]
        makeEnv( { name: d.name, version: d.version, path:d.path }
               , envKey+"_", env)
      }
    } else {
      env[envKey] = String(data[i])
      env[envKey] = -1 !== env[envKey].indexOf("\n")
                  ? JSON.stringify(env[envKey])
                  : env[envKey]
    }

  }

  if (prefix !== "npm_package_") return env

  prefix = "npm_config_"
  var pkgConfig = {}
    , ini = require("./ini.js")
    , keys = ini.keys
    , pkgVerConfig = {}
    , namePref = data.name + ":"
    , verPref = data.name + "@" + data.version + ":"

  keys.forEach(function (i) {
    if (i.charAt(0) === "_" && i.indexOf("_"+namePref) !== 0) {
      return
    }
    var value = ini.get(i)
    if (value instanceof Stream) return
    if (!value) value = ""
    else if (typeof value !== "string") value = JSON.stringify(value)

    value = -1 !== value.indexOf("\n")
          ? JSON.stringify(value)
          : value
    i = i.replace(/^_+/, "")
    if (i.indexOf(namePref) === 0) {
      var k = i.substr(namePref.length).replace(/[^a-zA-Z0-9_]/g, "_")
      pkgConfig[ k ] = value
    } else if (i.indexOf(verPref) === 0) {
      var k = i.substr(verPref.length).replace(/[^a-zA-Z0-9_]/g, "_")
      pkgVerConfig[ k ] = value
    }
    var envKey = (prefix+i).replace(/[^a-zA-Z0-9_]/g, "_")
    env[envKey] = value
  })

  prefix = "npm_package_config_"
  ;[pkgConfig, pkgVerConfig].forEach(function (conf) {
    for (var i in conf) {
      var envKey = (prefix+i)
      env[envKey] = conf[i]
    }
  })

  return env
}

function cmd (stage) {
  function CMD (args, cb) {
    if (args.length) {
      chain(args.map(function (p) {
        return [npm.commands, "run-script", [p, stage]]
      }), cb)
    } else npm.commands["run-script"]([stage], cb)
  }
  CMD.usage = "npm "+stage+" <name>"
  var installedShallow = require("./completion/installed-shallow.js")
  CMD.completion = function (opts, cb) {
    installedShallow(opts, function (d) {
      return d.scripts && d.scripts[stage]
    }, cb)
  }
  return CMD
}
<commit_msg>node exe dir to the PATH for lifestyle scripts<commit_after>
exports = module.exports = lifecycle
exports.cmd = cmd

var log = require("npmlog")
  , exec = require("./exec.js")
  , npm = require("../npm.js")
  , path = require("path")
  , fs = require("graceful-fs")
  , chain = require("slide").chain
  , constants = require("constants")
  , Stream = require("stream").Stream
  , PATH = "PATH"

// windows calls it's path "Path" usually, but this is not guaranteed.
if (process.platform === "win32") {
  PATH = "Path"
  Object.keys(process.env).forEach(function (e) {
    if (e.match(/^PATH$/i)) {
      PATH = e
    }
  })
}

function lifecycle (pkg, stage, wd, unsafe, failOk, cb) {
  if (typeof cb !== "function") cb = failOk, failOk = false
  if (typeof cb !== "function") cb = unsafe, unsafe = false
  if (typeof cb !== "function") cb = wd, wd = null

  while (pkg && pkg._data) pkg = pkg._data
  if (!pkg) return cb(new Error("Invalid package data"))

  log.info(stage, pkg._id)
  if (!pkg.scripts) pkg.scripts = {}

  validWd(wd || path.resolve(npm.dir, pkg.name), function (er, wd) {
    if (er) return cb(er)

    unsafe = unsafe || npm.config.get("unsafe-perm")

    if ((wd.indexOf(npm.dir) !== 0 || path.basename(wd) !== pkg.name)
        && !unsafe && pkg.scripts[stage]) {
      log.warn( "cannot run in wd", "%s %s (wd=%s)"
              , pkg._id, pkg.scripts[stage], wd)
      return cb()
    }

    // set the env variables, then run scripts as a child process.
    var env = makeEnv(pkg)
    env.npm_lifecycle_event = stage

    // "nobody" typically doesn't have permission to write to /tmp
    // even if it's never used, sh freaks out.
    if (!npm.config.get("unsafe-perm")) env.TMPDIR = wd

    lifecycle_(pkg, stage, wd, env, unsafe, failOk, cb)
  })
}

function checkForLink (pkg, cb) {
  var f = path.join(npm.dir, pkg.name)
  fs.lstat(f, function (er, s) {
    cb(null, !(er || !s.isSymbolicLink()))
  })
}

function lifecycle_ (pkg, stage, wd, env, unsafe, failOk, cb) {
  var pathArr = []
    , p = wd.split("node_modules")
    , acc = path.resolve(p.shift())
  p.forEach(function (pp) {
    pathArr.unshift(path.join(acc, "node_modules", ".bin"))
    acc = path.join(acc, "node_modules", pp)
  })
  pathArr.unshift(path.join(acc, "node_modules", ".bin"))

  // we also unshift the bundled node-gyp-bin folder so that
  // the bundled one will be used for installing things.
  pathArr.unshift(path.join(__dirname, "..", "..", "bin", "node-gyp-bin"))

  // add the directory containing the `node` executable currently running, so
  // that any lifecycle script that invoke "node" will execute this same one.
  pathArr.unshift(path.dirname(process.execPath))

  if (env[PATH]) pathArr.push(env[PATH])
  env[PATH] = pathArr.join(process.platform === "win32" ? ";" : ":")

  var packageLifecycle = pkg.scripts && pkg.scripts.hasOwnProperty(stage)

  if (packageLifecycle) {
    // define this here so it's available to all scripts.
    env.npm_lifecycle_script = pkg.scripts[stage]
  }

  if (failOk) {
    cb = (function (cb_) { return function (er) {
      if (er) log.warn("continuing anyway", er.message)
      cb_()
    }})(cb)
  }

  if (npm.config.get("force")) {
    cb = (function (cb_) { return function (er) {
      if (er) log.info("forced, continuing", er)
      cb_()
    }})(cb)
  }

  chain
    ( [ packageLifecycle && [runPackageLifecycle, pkg, env, wd, unsafe]
      , [runHookLifecycle, pkg, env, wd, unsafe] ]
    , cb )
}

function validWd (d, cb) {
  fs.stat(d, function (er, st) {
    if (er || !st.isDirectory()) {
      var p = path.dirname(d)
      if (p === d) {
        return cb(new Error("Could not find suitable wd"))
      }
      return validWd(p, cb)
    }
    return cb(null, d)
  })
}

function runPackageLifecycle (pkg, env, wd, unsafe, cb) {
  // run package lifecycle scripts in the package root, or the nearest parent.
  var stage = env.npm_lifecycle_event
    , user = unsafe ? null : npm.config.get("user")
    , group = unsafe ? null : npm.config.get("group")
    , cmd = env.npm_lifecycle_script
    , sh = "sh"
    , shFlag = "-c"

  if (process.platform === "win32") {
    sh = "cmd"
    shFlag = "/c"
  }

  log.verbose("unsafe-perm in lifecycle", unsafe)

  var note = "\n> " + pkg._id + " " + stage + " " + wd
           + "\n> " + cmd + "\n"

  console.log(note)
  exec( sh, [shFlag, cmd], env, true, wd
      , user, group
      , function (er, code, stdout, stderr) {
    if (er && !npm.ROLLBACK) {
      log.info(pkg._id, "Failed to exec "+stage+" script")
      er.message = pkg._id + " "
                 + stage + ": `" + env.npm_lifecycle_script+"`\n"
                 + er.message
      if (er.code !== "EPERM") {
        er.code = "ELIFECYCLE"
      }
      er.pkgid = pkg._id
      er.stage = stage
      er.script = env.npm_lifecycle_script
      er.pkgname = pkg.name
      return cb(er)
    } else if (er) {
      log.error(pkg._id+"."+stage, er)
      log.error(pkg._id+"."+stage, "continuing anyway")
      return cb()
    }
    cb(er)
  })
}

function runHookLifecycle (pkg, env, wd, unsafe, cb) {
  // check for a hook script, run if present.
  var stage = env.npm_lifecycle_event
    , hook = path.join(npm.dir, ".hooks", stage)
    , user = unsafe ? null : npm.config.get("user")
    , group = unsafe ? null : npm.config.get("group")
    , cmd = hook

  fs.stat(hook, function (er) {
    if (er) return cb()

    exec( "sh", ["-c", cmd], env, true, wd
        , user, group
        , function (er) {
      if (er) {
        er.message += "\nFailed to exec "+stage+" hook script"
        log.info(pkg._id, er)
      }
      if (npm.ROLLBACK) return cb()
      cb(er)
    })
  })
}

function makeEnv (data, prefix, env) {
  prefix = prefix || "npm_package_"
  if (!env) {
    env = {}
    for (var i in process.env) if (!i.match(/^npm_/)) {
      env[i] = process.env[i]
    }

    // npat asks for tap output
    if (npm.config.get("npat")) env.TAP = 1

    // express and others respect the NODE_ENV value.
    if (npm.config.get("production")) env.NODE_ENV = "production"

  } else if (!data.hasOwnProperty("_lifecycleEnv")) {
    Object.defineProperty(data, "_lifecycleEnv",
      { value : env
      , enumerable : false
      })
  }

  for (var i in data) if (i.charAt(0) !== "_") {
    var envKey = (prefix+i).replace(/[^a-zA-Z0-9_]/g, '_')
    if (data[i] && typeof(data[i]) === "object") {
      try {
        // quick and dirty detection for cyclical structures
        JSON.stringify(data[i])
        makeEnv(data[i], envKey+"_", env)
      } catch (ex) {
        // usually these are package objects.
        // just get the path and basic details.
        var d = data[i]
        makeEnv( { name: d.name, version: d.version, path:d.path }
               , envKey+"_", env)
      }
    } else {
      env[envKey] = String(data[i])
      env[envKey] = -1 !== env[envKey].indexOf("\n")
                  ? JSON.stringify(env[envKey])
                  : env[envKey]
    }

  }

  if (prefix !== "npm_package_") return env

  prefix = "npm_config_"
  var pkgConfig = {}
    , ini = require("./ini.js")
    , keys = ini.keys
    , pkgVerConfig = {}
    , namePref = data.name + ":"
    , verPref = data.name + "@" + data.version + ":"

  keys.forEach(function (i) {
    if (i.charAt(0) === "_" && i.indexOf("_"+namePref) !== 0) {
      return
    }
    var value = ini.get(i)
    if (value instanceof Stream) return
    if (!value) value = ""
    else if (typeof value !== "string") value = JSON.stringify(value)

    value = -1 !== value.indexOf("\n")
          ? JSON.stringify(value)
          : value
    i = i.replace(/^_+/, "")
    if (i.indexOf(namePref) === 0) {
      var k = i.substr(namePref.length).replace(/[^a-zA-Z0-9_]/g, "_")
      pkgConfig[ k ] = value
    } else if (i.indexOf(verPref) === 0) {
      var k = i.substr(verPref.length).replace(/[^a-zA-Z0-9_]/g, "_")
      pkgVerConfig[ k ] = value
    }
    var envKey = (prefix+i).replace(/[^a-zA-Z0-9_]/g, "_")
    env[envKey] = value
  })

  prefix = "npm_package_config_"
  ;[pkgConfig, pkgVerConfig].forEach(function (conf) {
    for (var i in conf) {
      var envKey = (prefix+i)
      env[envKey] = conf[i]
    }
  })

  return env
}

function cmd (stage) {
  function CMD (args, cb) {
    if (args.length) {
      chain(args.map(function (p) {
        return [npm.commands, "run-script", [p, stage]]
      }), cb)
    } else npm.commands["run-script"]([stage], cb)
  }
  CMD.usage = "npm "+stage+" <name>"
  var installedShallow = require("./completion/installed-shallow.js")
  CMD.completion = function (opts, cb) {
    installedShallow(opts, function (d) {
      return d.scripts && d.scripts[stage]
    }, cb)
  }
  return CMD
}
<|endoftext|>


<commit_before>/* global Virastar, ClipboardJS, Diff, syncscroll */

(function (w) {
  var virastar;
  var clipboard;
  var app = {

    settings: undefined,
    storage: typeof (Storage) !== 'undefined',

    input: document.getElementById('input'),
    output: document.getElementById('output'),
    diff: document.getElementById('diff'),
    reset: document.getElementById('settings-reset'),

    // demo default options
    options: {
      // skip_markdown_ordered_lists_numbers_conversion: false,
      // preserve_brackets: false,
      // preserve_braces: false
    },

    // @REF: https://remysharp.com/2010/07/21/throttling-function-calls
    debounce: function (fn, delay) {
      var timer = null;
      return function () {
        var context = this;
        var args = arguments;
        clearTimeout(timer);
        timer = setTimeout(function () {
          fn.apply(context, args);
        }, delay);
      };
    },

    // @REF: https://stackoverflow.com/a/5574446
    toProperCase: function (txt) {
      return txt.replace(/\w\S*/g, function (str) {
        return str.charAt(0).toUpperCase() + str.substr(1).toLowerCase();
      });
    },

    renderSettings: function (defaults) {
      var options = this.getStorage(this.options, 'options');
      var ul = document.getElementById('options');
      ul.innerHTML = ''; // list must be empty!

      for (var option in defaults) {
        var row = document.createElement('li');
        var checkbox = document.createElement('input');
        var label = document.createElement('label');

        var name = this.toProperCase(option.replace(new RegExp(/_/, 'g'), ' '));

        checkbox.type = 'checkbox';
        checkbox.checked = options.hasOwnProperty(option) ? options[option] : defaults[option]; // eslint-disable-line no-prototype-builtins
        checkbox.name = 'opt[]';
        checkbox.value = option;
        checkbox.id = option;
        checkbox.setAttribute('class', 'option');

        label.htmlFor = option;
        label.appendChild(document.createTextNode(name));

        row.appendChild(checkbox);
        row.appendChild(label);

        ul.appendChild(row);
      }

      this.settings = document.querySelectorAll('.option');
    },

    getStorage: function (def, key) {
      if (!this.storage) {
        return def;
      }

      var stored = w.localStorage.getItem(key);
      return stored ? JSON.parse(stored) : def;
    },

    setStorage: function (data, key) {
      if (this.storage) {
        w.localStorage.setItem(key, JSON.stringify(data));
      }
    },

    removeStorage: function (key) {
      if (this.storage) {
        w.localStorage.removeItem(key);
      }
    },

    getOptions: function () {
      var options = {};

      this.settings.forEach(function (option) {
        options[option.value] = option.checked;
      });

      return options;
    },

    doVirastar: function (input, options) {
      this.output.innerHTML = virastar.cleanup(input, options);
      this.diff.innerHTML = '';
      this.diff.appendChild(this.renderDiff());
    },

    doChange: function () {
      var input = this.input.value;
      var options = this.getOptions();
      this.doVirastar(input, options);
      this.setStorage(options, 'options');
      this.setStorage(input, 'text');
      syncscroll.reset();
    },

    renderDiff: function () {
      // @REF: https://github.com/kpdecker/jsdiff
      var diff = Diff.diffChars(this.input.value, this.output.value, { ignoreWhitespace: false });
      var fragment = document.createDocumentFragment();
      var pre = document.createElement('pre');
      var span = null;
      var status = '';

      diff.forEach(function (part) {
        span = document.createElement('span');

        status = part.added ? '-added' : part.removed ? '-removed' : '-none';
        span.classList.add(status);

        // zwnj
        if (part.value === '') {
          span.classList.add('-zwnj');
          part.value = '⋅';
        } else {
          // extra zwnj for better visibility
          // part.value = part.value + '';
        }

        span.appendChild(document.createTextNode(part.value));
        fragment.appendChild(span);
      });

      pre.appendChild(fragment);
      return pre;
    },

    init: function () {
      var that = this;
      virastar = new Virastar(this.options);

      this.input.addEventListener('keyup', this.debounce(function () {
        that.doChange();
      }, 1000));

      this.reset.addEventListener('click', function (event) {
        event.preventDefault();
        that.removeStorage('options');
        that.initSettings();
        that.doChange();
      });

      this.initSettings();
      this.initVirastar();
      syncscroll.reset();
    },

    initSettings: function () {
      var that = this;
      this.renderSettings(virastar.defaults);

      this.settings.forEach(function (option) {
        option.addEventListener('change', function () {
          that.doChange();
        });
      });
    },

    initVirastar: function () {
      var initial = this.input.value;
      var input = this.getStorage(initial, 'text');
      var options = this.getOptions();

      if (input.trim()) {
        this.input.value = input;
        this.doVirastar(input, options);
      } else {
        this.doVirastar(initial, options);
      }
    },

    initClipboard: function () {
      clipboard = new ClipboardJS('.copy');

      clipboard.on('success', function (e) {
        console.log(e);
      });

      clipboard.on('error', function (e) {
        console.log(e);
      });
    }
  };

  w.onload = function () {
    app.init();
  };
})(window);
<commit_msg>demo: copy in clipboard (missed)<commit_after>/* global Virastar, ClipboardJS, Diff, syncscroll */

(function (w) {
  var virastar;
  var clipboard;
  var app = {

    settings: undefined,
    storage: typeof (Storage) !== 'undefined',

    input: document.getElementById('input'),
    output: document.getElementById('output'),
    diff: document.getElementById('diff'),
    reset: document.getElementById('settings-reset'),

    // demo default options
    options: {
      // skip_markdown_ordered_lists_numbers_conversion: false,
      // preserve_brackets: false,
      // preserve_braces: false
    },

    // @REF: https://remysharp.com/2010/07/21/throttling-function-calls
    debounce: function (fn, delay) {
      var timer = null;
      return function () {
        var context = this;
        var args = arguments;
        clearTimeout(timer);
        timer = setTimeout(function () {
          fn.apply(context, args);
        }, delay);
      };
    },

    // @REF: https://stackoverflow.com/a/5574446
    toProperCase: function (txt) {
      return txt.replace(/\w\S*/g, function (str) {
        return str.charAt(0).toUpperCase() + str.substr(1).toLowerCase();
      });
    },

    renderSettings: function (defaults) {
      var options = this.getStorage(this.options, 'options');
      var ul = document.getElementById('options');
      ul.innerHTML = ''; // list must be empty!

      for (var option in defaults) {
        var row = document.createElement('li');
        var checkbox = document.createElement('input');
        var label = document.createElement('label');

        var name = this.toProperCase(option.replace(new RegExp(/_/, 'g'), ' '));

        checkbox.type = 'checkbox';
        checkbox.checked = options.hasOwnProperty(option) ? options[option] : defaults[option]; // eslint-disable-line no-prototype-builtins
        checkbox.name = 'opt[]';
        checkbox.value = option;
        checkbox.id = option;
        checkbox.setAttribute('class', 'option');

        label.htmlFor = option;
        label.appendChild(document.createTextNode(name));

        row.appendChild(checkbox);
        row.appendChild(label);

        ul.appendChild(row);
      }

      this.settings = document.querySelectorAll('.option');
    },

    getStorage: function (def, key) {
      if (!this.storage) {
        return def;
      }

      var stored = w.localStorage.getItem(key);
      return stored ? JSON.parse(stored) : def;
    },

    setStorage: function (data, key) {
      if (this.storage) {
        w.localStorage.setItem(key, JSON.stringify(data));
      }
    },

    removeStorage: function (key) {
      if (this.storage) {
        w.localStorage.removeItem(key);
      }
    },

    getOptions: function () {
      var options = {};

      this.settings.forEach(function (option) {
        options[option.value] = option.checked;
      });

      return options;
    },

    doVirastar: function (input, options) {
      this.output.innerHTML = virastar.cleanup(input, options);
      this.diff.innerHTML = '';
      this.diff.appendChild(this.renderDiff());
    },

    doChange: function () {
      var input = this.input.value;
      var options = this.getOptions();
      this.doVirastar(input, options);
      this.setStorage(options, 'options');
      this.setStorage(input, 'text');
      syncscroll.reset();
    },

    renderDiff: function () {
      // @REF: https://github.com/kpdecker/jsdiff
      var diff = Diff.diffChars(this.input.value, this.output.value, { ignoreWhitespace: false });
      var fragment = document.createDocumentFragment();
      var pre = document.createElement('pre');
      var span = null;
      var status = '';

      diff.forEach(function (part) {
        span = document.createElement('span');

        status = part.added ? '-added' : part.removed ? '-removed' : '-none';
        span.classList.add(status);

        // zwnj
        if (part.value === '') {
          span.classList.add('-zwnj');
          part.value = '⋅';
        } else {
          // extra zwnj for better visibility
          // part.value = part.value + '';
        }

        span.appendChild(document.createTextNode(part.value));
        fragment.appendChild(span);
      });

      pre.appendChild(fragment);
      return pre;
    },

    init: function () {
      var that = this;
      virastar = new Virastar(this.options);

      this.input.addEventListener('keyup', this.debounce(function () {
        that.doChange();
      }, 1000));

      this.reset.addEventListener('click', function (event) {
        event.preventDefault();
        that.removeStorage('options');
        that.initSettings();
        that.doChange();
      });

      this.initSettings();
      this.initVirastar();
      this.initClipboard();
      syncscroll.reset();
    },

    initSettings: function () {
      var that = this;
      this.renderSettings(virastar.defaults);

      this.settings.forEach(function (option) {
        option.addEventListener('change', function () {
          that.doChange();
        });
      });
    },

    initVirastar: function () {
      var initial = this.input.value;
      var input = this.getStorage(initial, 'text');
      var options = this.getOptions();

      if (input.trim()) {
        this.input.value = input;
        this.doVirastar(input, options);
      } else {
        this.doVirastar(initial, options);
      }
    },

    initClipboard: function () {
      clipboard = new ClipboardJS('.copy');

      clipboard.on('success', function (e) {
        console.log(e);
      });

      clipboard.on('error', function (e) {
        console.log(e);
      });
    }
  };

  w.onload = function () {
    app.init();
  };
})(window);
<|endoftext|>