<commit_before>describe('ns.View', function() {

    describe('ns.View.define', function() {

        beforeEach(function() {
            sinon.spy(ns.View, 'define');

            this.view = ns.View.define('test-view-define');
        });

        afterEach(function() {
            ns.View.define.restore();
            ns.View.undefine('test-view-define');
        });

        it('should throw exception if I define View twice', function() {
            try {
                ns.View.define('test-view-define');
            } catch(e) {}

            expect(ns.View.define.getCall(1).threw()).to.be.ok();
        });

        it('should return new view', function() {
            expect(this.view).to.be.ok();
        });

        it('instance of new view should be ns.View', function() {
            var instance = ns.View.create('test-view-define', {});
            expect(instance instanceof ns.View).to.be.ok();
        });
    });

    describe('Наследование от другого view', function() {

        beforeEach(function() {

            var parentMegaView = ns.View.define('parentMegaView', {
                methods: {
                    superMethod: function() {}
                }
            });

            ns.View.define('childMegaView', {
                methods: {
                    oneMore: function() {}
                }
            }, parentMegaView);

            this.view = ns.View.create('childMegaView', {});
        });

        afterEach(function() {
            delete this.view;
            ns.View.undefine('parentMegaView');
            ns.View.undefine('childMegaView');
        });

        it('наследуемый view должен быть ns.View', function() {
            expect(this.view instanceof ns.View).to.be.ok();
        });

        it('методы наследуются от базового view', function() {
            expect(this.view.superMethod).to.be.ok();
        });

        it('методы от базового view не ушли в ns.View', function() {
            expect(ns.View.prototype.superMethod).to.not.be.ok();
        });

        it('методы ns.View на месте', function() {
            expect(this.view.isOk).to.be.ok();
        });

        it('методы из info.methods тоже не потерялись', function() {
            expect(this.view.oneMore).to.be.ok();
        });
    });

    describe('ns.View.info events parse', function() {

        ns.View.define('test-view-info-events-parse', {
            events: {
                'scroll window': no.pe,
                'scroll document': no.pe,

                'scroll@init window': no.pe,
                'scroll@init document': no.pe,

                'resize window': no.pe,
                'resize document': no.pe,

                'resize@init window': no.pe,
                'resize@init document': no.pe,

                'scroll .foo-init': no.pe,
                'scroll': no.pe,
                'click': no.pe,
                'click .bar-init': no.pe,

                'scroll@show .foo-show': no.pe,
                'scroll@show': no.pe,
                'click@show': no.pe,
                'click@show .bar-show': no.pe,

                'my-global-init-event-short': no.pe,
                'my-local-init-event-short .': no.pe,

                'my-global-init-event@init': no.pe,
                'my-local-init-event@init .': no.pe,

                'my-global-show-event@show': no.pe,
                'my-local-show-event@show .': no.pe
            }
        });

        beforeEach(function() {
            this.viewInfo = ns.View.info('test-view-info-events-parse');
        });

        afterEach(function() {
            delete this.viewInfo;
        });

        describe('DOM events', function() {

            it('"initEvents" should be the object', function() {
                expect(this.viewInfo.initEvents).to.be.a('object');
            });

            it('"initEvents.bind" should be the array', function() {
                expect(this.viewInfo.initEvents['bind']).to.be.a('array');
            });

            it('"initEvents.delegate" should be the array', function() {
                expect(this.viewInfo.initEvents['delegate']).to.be.a('array');
            });

            it('"showEvents" should be the object', function() {
                expect(this.viewInfo.showEvents).to.be.a('object');
            });

            it('"showEvents.bind" should be the array', function() {
                expect(this.viewInfo.showEvents['bind']).to.be.a('array');
            });

            it('"showEvents.delegate" should be the array', function() {
                expect(this.viewInfo.showEvents['delegate']).to.be.a('array');
            });

            it('should parse delegated init events properly', function() {
                expect(this.viewInfo.initEvents['delegate']).to.be.eql([
                    ['scroll', 'window', no.pe],
                    ['scroll', 'document', no.pe],

                    ['resize', 'window', no.pe],
                    ['resize', 'document', no.pe],

                    ['scroll', '', no.pe],
                    ['click', '', no.pe],
                    ['click', '.bar-init', no.pe]
                ]);
            });

            it('should parse bind init events properly', function() {
                expect(this.viewInfo.initEvents['bind']).to.be.eql([
                    ['scroll', '.foo-init', no.pe]
                ]);
            });

            it('should parse show events properly', function() {
                expect(this.viewInfo.showEvents['delegate']).to.be.eql([
                    ['scroll', 'window', no.pe],
                    ['scroll', 'document', no.pe],
                    ['resize', 'window', no.pe],
                    ['resize', 'document', no.pe],

                    ['scroll', '', no.pe],
                    ['click', '', no.pe],
                    ['click', '.bar-show', no.pe]
                ]);
            });

            it('should parse show events properly', function() {
                expect(this.viewInfo.showEvents['bind']).to.be.eql([
                    ['scroll', '.foo-show', no.pe]
                ]);
            });
        });

        describe('no.events', function() {
            it('"initNoevents" should be the object', function() {
                expect(this.viewInfo.initNoevents).to.be.a('object');
            });

            it('"initNoevents.global" should be the array', function() {
                expect(this.viewInfo.initNoevents['global']).to.be.a('array');
            });

            it('"initNoevents.local" should be the array', function() {
                expect(this.viewInfo.initNoevents['local']).to.be.a('array');
            });

            it('"showNoevents" should be the object', function() {
                expect(this.viewInfo.showNoevents).to.be.a('object');
            });

            it('"showNoevents.global" should be the array', function() {
                expect(this.viewInfo.showNoevents['global']).to.be.a('array');
            });

            it('"showNoevents.local" should be the array', function() {
                expect(this.viewInfo.showNoevents['local']).to.be.a('array');
            });

            it('should parse global init noevents properly', function() {
                expect(this.viewInfo.initNoevents['global']).to.be.eql([
                    ['my-global-init-event-short', no.pe],
                    ['my-global-init-event', no.pe]
                ]);
            });

            it('should parse local init noevents properly', function() {
                expect(this.viewInfo.initNoevents['local']).to.be.eql([
                    ['my-local-init-event-short', no.pe],
                    ['my-local-init-event', no.pe]
                ]);
            });

            it('should parse global show noevents properly', function() {
                expect(this.viewInfo.showNoevents['global']).to.be.eql([
                    ['my-global-show-event', no.pe]
                ]);
            });

            it('should parse local show noevents properly', function() {
                expect(this.viewInfo.showNoevents['local']).to.be.eql([
                    ['my-local-show-event', no.pe]
                ]);
            });
        });
    });

    describe('ns.View.info models parse', function() {

        describe('no models specified', function() {

            beforeEach(function() {
                ns.Model.define('a');
                ns.Model.define('b');
                ns.Model.define('c');
            });

            afterEach(function() {
                ns.Model.undefine();
            });

            it('no models at all', function() {
                ns.View.define('test-view-info-models-parse_no-models', {});

                var info = ns.View.info('test-view-info-models-parse_no-models');
                expect(info.models).to.be.eql({});

                ns.View.undefine('test-view-info-models-parse_no-models');
            });

            it('models specified as empty array', function() {
                ns.View.define('test-view-info-models-parse_empty-array', { models: [] });

                var info = ns.View.info('test-view-info-models-parse_empty-array');
                expect(info.models).to.be.eql({});

                ns.View.undefine('test-view-info-models-parse_empty-array');
            });

            it('models array is converted to object', function() {
                ns.View.define('test-view-info-models-parse_array', { models: [ 'a', 'b' ] });

                var info = ns.View.info('test-view-info-models-parse_array');
                expect(info.models).to.be.eql({ a: true, b: true });

                ns.View.undefine('test-view-info-models-parse_array');
            });
        });
    });

    describe('ns.View render', function() {

        describe('ns.View render with some invalid models', function() {

            beforeEach(function() {
                ns.Model.define('a');
                ns.Model.define('b');
                ns.Model.define('c');

                var models = {
                    a: ns.Model.create('a', { id: 1 }),
                    b: ns.Model.create('b', { id: 2 }),
                    c: ns.Model.create('c', { id: 3 })
                };

                models.a.setData({ data: 'a' });
                models.b.setError({ error: 'b invalid' });
                models.c.setError({ error: 'c invalid' });

                ns.View.define('test-view-render_complex', {
                    models: {
                        a: true,
                        b: false,
                        c: null
                    }
                });

                this.view = ns.View.create('test-view-render_complex', {}, false);
            });

            afterEach(function() {
                ns.Model.undefine();
                ns.View.undefine();
                delete this.view;
            });

            it('models are valid for view', function() {
                expect( this.view.isModelsValid() ).to.be.ok();
            });

            it('errors are also rendered', function() {
                expect( this.view._getModelsData() ).to.be.eql({
                    a: { data: 'a' },
                    b: { error: 'b invalid' },
                    c: { error: 'c invalid' }
                });
            });

        });

    });

    describe('ns.View._bindEventHandlers', function() {

        beforeEach(function() {
            this.view = new ns.View();
            this.view.myTestFunc = function() {return this};

            this.eventArr = [
                [ '1', function(){return this} ],
                [ '2', 'myTestFunc' ]
            ];

            this.bindedEventArr = this.view._bindEventHandlers(this.eventArr, 1);
        });

        afterEach(function() {
            delete this.view;
            delete this.eventArr;
            delete this.bindedEventArr;
        });

        it('should return array copy', function() {
            expect(this.bindedEventArr !== this.eventArr).to.be.ok();
        });

        it('should return array with same length', function() {
            expect(this.bindedEventArr.length).to.be(this.eventArr.length);
        });

        it('should process handler as function', function() {
            expect(this.bindedEventArr[0][1]).to.be.a('function');
        });

        it('should return binded function', function() {
            expect(this.bindedEventArr[0][1]()).to.be(this.view);
        });

        it('should return prototype method if handler is string', function() {
            expect(this.bindedEventArr[1][1]).to.be.a('function');
        });

        it('should return binded prototype method if handler is string', function() {
            expect(this.bindedEventArr[1][1]()).to.be(this.view);
        });
    });

    describe('ns.View._getEvents', function() {

        beforeEach(function() {
            this.view = new ns.View();

            this.bindArr = [1];
            this.delegateArr = [2];
            this.localArr = [3];
            this.globalArr = [4];

            this.view.info = {
                initEvents: {
                    'bind': this.bindArr,
                    'delegate': this.delegateArr
                },
                initNoevents: {
                    'local': this.localArr,
                    'global': this.globalArr
                }
            };

            sinon.stub(this.view, '_bindEventHandlers', function() {
                return [];
            });

            this.result = this.view._getEvents('init');
        });

        afterEach(function() {
            this.view._bindEventHandlers.restore();
            delete this.view;

            delete this.bindArr;
            delete this.delegateArr;
            delete this.localArr;
            delete this.globalArr;
            delete this.result;
        });

        it('should return properly object', function() {
            expect(this.result).to.be.eql({
                'bind': [],
                'delegate': [],
                'no-local': [],
                'no-global': []
            });
        });

        it('should call _bindEventHandlers 4 times', function() {
            expect(this.view._bindEventHandlers.callCount).to.be(4)
        });

        it('should call _bindEventHandlers for delegated events', function() {
            expect(this.view._bindEventHandlers.calledWithExactly(this.delegateArr, 2)).to.be.ok()
        });

        it('should call _bindEventHandlers for bind events', function() {
            expect(this.view._bindEventHandlers.calledWithExactly(this.bindArr, 2)).to.be.ok()
        });

        it('should call _bindEventHandlers for local no.events', function() {
            expect(this.view._bindEventHandlers.calledWithExactly(this.localArr, 1)).to.be.ok()
        });

        it('should call _bindEventHandlers for global no.events', function() {
            expect(this.view._bindEventHandlers.calledWithExactly(this.globalArr, 1)).to.be.ok()
        });
    });
});
<commit_msg>refactor view render test<commit_after>describe('ns.View', function() {

    describe('ns.View.define', function() {

        beforeEach(function() {
            sinon.spy(ns.View, 'define');

            this.view = ns.View.define('test-view-define');
        });

        afterEach(function() {
            ns.View.define.restore();
            ns.View.undefine('test-view-define');
        });

        it('should throw exception if I define View twice', function() {
            try {
                ns.View.define('test-view-define');
            } catch(e) {}

            expect(ns.View.define.getCall(1).threw()).to.be.ok();
        });

        it('should return new view', function() {
            expect(this.view).to.be.ok();
        });

        it('instance of new view should be ns.View', function() {
            var instance = ns.View.create('test-view-define', {});
            expect(instance instanceof ns.View).to.be.ok();
        });
    });

    describe('Наследование от другого view', function() {

        beforeEach(function() {

            var parentMegaView = ns.View.define('parentMegaView', {
                methods: {
                    superMethod: function() {}
                }
            });

            ns.View.define('childMegaView', {
                methods: {
                    oneMore: function() {}
                }
            }, parentMegaView);

            this.view = ns.View.create('childMegaView', {});
        });

        afterEach(function() {
            delete this.view;
            ns.View.undefine('parentMegaView');
            ns.View.undefine('childMegaView');
        });

        it('наследуемый view должен быть ns.View', function() {
            expect(this.view instanceof ns.View).to.be.ok();
        });

        it('методы наследуются от базового view', function() {
            expect(this.view.superMethod).to.be.ok();
        });

        it('методы от базового view не ушли в ns.View', function() {
            expect(ns.View.prototype.superMethod).to.not.be.ok();
        });

        it('методы ns.View на месте', function() {
            expect(this.view.isOk).to.be.ok();
        });

        it('методы из info.methods тоже не потерялись', function() {
            expect(this.view.oneMore).to.be.ok();
        });
    });

    describe('ns.View.info events parse', function() {

        ns.View.define('test-view-info-events-parse', {
            events: {
                'scroll window': no.pe,
                'scroll document': no.pe,

                'scroll@init window': no.pe,
                'scroll@init document': no.pe,

                'resize window': no.pe,
                'resize document': no.pe,

                'resize@init window': no.pe,
                'resize@init document': no.pe,

                'scroll .foo-init': no.pe,
                'scroll': no.pe,
                'click': no.pe,
                'click .bar-init': no.pe,

                'scroll@show .foo-show': no.pe,
                'scroll@show': no.pe,
                'click@show': no.pe,
                'click@show .bar-show': no.pe,

                'my-global-init-event-short': no.pe,
                'my-local-init-event-short .': no.pe,

                'my-global-init-event@init': no.pe,
                'my-local-init-event@init .': no.pe,

                'my-global-show-event@show': no.pe,
                'my-local-show-event@show .': no.pe
            }
        });

        beforeEach(function() {
            this.viewInfo = ns.View.info('test-view-info-events-parse');
        });

        afterEach(function() {
            delete this.viewInfo;
        });

        describe('DOM events', function() {

            it('"initEvents" should be the object', function() {
                expect(this.viewInfo.initEvents).to.be.a('object');
            });

            it('"initEvents.bind" should be the array', function() {
                expect(this.viewInfo.initEvents['bind']).to.be.a('array');
            });

            it('"initEvents.delegate" should be the array', function() {
                expect(this.viewInfo.initEvents['delegate']).to.be.a('array');
            });

            it('"showEvents" should be the object', function() {
                expect(this.viewInfo.showEvents).to.be.a('object');
            });

            it('"showEvents.bind" should be the array', function() {
                expect(this.viewInfo.showEvents['bind']).to.be.a('array');
            });

            it('"showEvents.delegate" should be the array', function() {
                expect(this.viewInfo.showEvents['delegate']).to.be.a('array');
            });

            it('should parse delegated init events properly', function() {
                expect(this.viewInfo.initEvents['delegate']).to.be.eql([
                    ['scroll', 'window', no.pe],
                    ['scroll', 'document', no.pe],

                    ['resize', 'window', no.pe],
                    ['resize', 'document', no.pe],

                    ['scroll', '', no.pe],
                    ['click', '', no.pe],
                    ['click', '.bar-init', no.pe]
                ]);
            });

            it('should parse bind init events properly', function() {
                expect(this.viewInfo.initEvents['bind']).to.be.eql([
                    ['scroll', '.foo-init', no.pe]
                ]);
            });

            it('should parse show events properly', function() {
                expect(this.viewInfo.showEvents['delegate']).to.be.eql([
                    ['scroll', 'window', no.pe],
                    ['scroll', 'document', no.pe],
                    ['resize', 'window', no.pe],
                    ['resize', 'document', no.pe],

                    ['scroll', '', no.pe],
                    ['click', '', no.pe],
                    ['click', '.bar-show', no.pe]
                ]);
            });

            it('should parse show events properly', function() {
                expect(this.viewInfo.showEvents['bind']).to.be.eql([
                    ['scroll', '.foo-show', no.pe]
                ]);
            });
        });

        describe('no.events', function() {
            it('"initNoevents" should be the object', function() {
                expect(this.viewInfo.initNoevents).to.be.a('object');
            });

            it('"initNoevents.global" should be the array', function() {
                expect(this.viewInfo.initNoevents['global']).to.be.a('array');
            });

            it('"initNoevents.local" should be the array', function() {
                expect(this.viewInfo.initNoevents['local']).to.be.a('array');
            });

            it('"showNoevents" should be the object', function() {
                expect(this.viewInfo.showNoevents).to.be.a('object');
            });

            it('"showNoevents.global" should be the array', function() {
                expect(this.viewInfo.showNoevents['global']).to.be.a('array');
            });

            it('"showNoevents.local" should be the array', function() {
                expect(this.viewInfo.showNoevents['local']).to.be.a('array');
            });

            it('should parse global init noevents properly', function() {
                expect(this.viewInfo.initNoevents['global']).to.be.eql([
                    ['my-global-init-event-short', no.pe],
                    ['my-global-init-event', no.pe]
                ]);
            });

            it('should parse local init noevents properly', function() {
                expect(this.viewInfo.initNoevents['local']).to.be.eql([
                    ['my-local-init-event-short', no.pe],
                    ['my-local-init-event', no.pe]
                ]);
            });

            it('should parse global show noevents properly', function() {
                expect(this.viewInfo.showNoevents['global']).to.be.eql([
                    ['my-global-show-event', no.pe]
                ]);
            });

            it('should parse local show noevents properly', function() {
                expect(this.viewInfo.showNoevents['local']).to.be.eql([
                    ['my-local-show-event', no.pe]
                ]);
            });
        });
    });

    describe('ns.View.info models parse', function() {

        describe('no models specified', function() {

            beforeEach(function() {
                ns.Model.define('a');
                ns.Model.define('b');
                ns.Model.define('c');
            });

            afterEach(function() {
                ns.Model.undefine();
            });

            it('no models at all', function() {
                ns.View.define('test-view-info-models-parse_no-models', {});

                var info = ns.View.info('test-view-info-models-parse_no-models');
                expect(info.models).to.be.eql({});

                ns.View.undefine('test-view-info-models-parse_no-models');
            });

            it('models specified as empty array', function() {
                ns.View.define('test-view-info-models-parse_empty-array', { models: [] });

                var info = ns.View.info('test-view-info-models-parse_empty-array');
                expect(info.models).to.be.eql({});

                ns.View.undefine('test-view-info-models-parse_empty-array');
            });

            it('models array is converted to object', function() {
                ns.View.define('test-view-info-models-parse_array', { models: [ 'a', 'b' ] });

                var info = ns.View.info('test-view-info-models-parse_array');
                expect(info.models).to.be.eql({ a: true, b: true });

                ns.View.undefine('test-view-info-models-parse_array');
            });
        });
    });

    describe('ns.View render', function() {

        describe('ns.View render with some invalid models', function() {

            beforeEach(function() {
                ns.Model.define('a');
                ns.Model.define('b');
                ns.Model.define('c');

                ns.View.define('test-view-render_complex', {
                    models: {
                        a: true,
                        b: false,
                        c: null
                    }
                });
            });

            afterEach(function() {
                ns.Model.undefine();
                ns.View.undefine();
            });

            it('models are valid for view', function() {
                var a = ns.Model.create('a', { id: 1 });
                var b = ns.Model.create('b', { id: 2 });
                var c = ns.Model.create('c', { id: 3 });

                a.setData({ data: 'a' });
                b.setError({ error: 'b invalid' });
                c.setError({ error: 'c invalid' });

                var view = ns.View.create('test-view-render_complex', {}, false);

                expect( view.isModelsValid() ).to.be.ok();
            });

            it('errors are also rendered', function() {
                var a = ns.Model.create('a', { id: 1 });
                var b = ns.Model.create('b', { id: 2 });
                var c = ns.Model.create('c', { id: 3 });

                a.setData({ data: 'a' });
                b.setError({ error: 'b invalid' });
                c.setError({ error: 'c invalid' });

                var view = ns.View.create('test-view-render_complex', {}, false);

                expect( view._getModelsData() ).to.be.eql({
                    a: { data: 'a' },
                    b: { error: 'b invalid' },
                    c: { error: 'c invalid' }
                });
            });
        });
    });

    describe('ns.View._bindEventHandlers', function() {

        beforeEach(function() {
            this.view = new ns.View();
            this.view.myTestFunc = function() {return this};

            this.eventArr = [
                [ '1', function(){return this} ],
                [ '2', 'myTestFunc' ]
            ];

            this.bindedEventArr = this.view._bindEventHandlers(this.eventArr, 1);
        });

        afterEach(function() {
            delete this.view;
            delete this.eventArr;
            delete this.bindedEventArr;
        });

        it('should return array copy', function() {
            expect(this.bindedEventArr !== this.eventArr).to.be.ok();
        });

        it('should return array with same length', function() {
            expect(this.bindedEventArr.length).to.be(this.eventArr.length);
        });

        it('should process handler as function', function() {
            expect(this.bindedEventArr[0][1]).to.be.a('function');
        });

        it('should return binded function', function() {
            expect(this.bindedEventArr[0][1]()).to.be(this.view);
        });

        it('should return prototype method if handler is string', function() {
            expect(this.bindedEventArr[1][1]).to.be.a('function');
        });

        it('should return binded prototype method if handler is string', function() {
            expect(this.bindedEventArr[1][1]()).to.be(this.view);
        });
    });

    describe('ns.View._getEvents', function() {

        beforeEach(function() {
            this.view = new ns.View();

            this.bindArr = [1];
            this.delegateArr = [2];
            this.localArr = [3];
            this.globalArr = [4];

            this.view.info = {
                initEvents: {
                    'bind': this.bindArr,
                    'delegate': this.delegateArr
                },
                initNoevents: {
                    'local': this.localArr,
                    'global': this.globalArr
                }
            };

            sinon.stub(this.view, '_bindEventHandlers', function() {
                return [];
            });

            this.result = this.view._getEvents('init');
        });

        afterEach(function() {
            this.view._bindEventHandlers.restore();
            delete this.view;

            delete this.bindArr;
            delete this.delegateArr;
            delete this.localArr;
            delete this.globalArr;
            delete this.result;
        });

        it('should return properly object', function() {
            expect(this.result).to.be.eql({
                'bind': [],
                'delegate': [],
                'no-local': [],
                'no-global': []
            });
        });

        it('should call _bindEventHandlers 4 times', function() {
            expect(this.view._bindEventHandlers.callCount).to.be(4)
        });

        it('should call _bindEventHandlers for delegated events', function() {
            expect(this.view._bindEventHandlers.calledWithExactly(this.delegateArr, 2)).to.be.ok()
        });

        it('should call _bindEventHandlers for bind events', function() {
            expect(this.view._bindEventHandlers.calledWithExactly(this.bindArr, 2)).to.be.ok()
        });

        it('should call _bindEventHandlers for local no.events', function() {
            expect(this.view._bindEventHandlers.calledWithExactly(this.localArr, 1)).to.be.ok()
        });

        it('should call _bindEventHandlers for global no.events', function() {
            expect(this.view._bindEventHandlers.calledWithExactly(this.globalArr, 1)).to.be.ok()
        });
    });
});
<|endoftext|>


<commit_before>(function () {

    var axisList = { width: [ ], height: [ ] };

    (function () {
        getAxisBreakpoints();
        createActionPanel( );
    })();

    function Breakpoint(mediaSizeSelector) {

        var mediaQuery = initMediaQuery();
        var property = initProperty();
        var propertyAxis = initPropertyAxis();
        var propertyOperator = initPropertyOperator();
        var value = initValue();
        var valueUnit = initValueUnit();
        var valueNumber = initValueNumber();
        var valuePixel = initValuePixel();

        function initMediaQuery() {
            return mediaSizeSelector.split(')')[ 0 ].trim();
        }

        function initProperty() {
            return mediaQuery.split(':')[ 0 ].trim();
        }

        function initPropertyAxis() {
            if (property == 'max-width' || property == 'min-width') {
                return 'width';
            }
            if (property == 'max-height' || property == 'min-height') {
                return 'height';
            }
        }

        function initPropertyOperator() {
            if (property == 'max-height' || property == 'max-width') {
                return 'max';
            }
            if (property == 'min-height' || property == 'min-width') {
                return 'min';
            }
        }

        function initValue() {
            return mediaQuery.split(':')[ 1 ].trim();
        }

        function initValueUnit() {
            return value.replace(/[\d\.]/g, '');
        }

        function initValueNumber() {
            return Number(value.replace(/[^\d\.]/g, ''));
        }

        function initValuePixel() {
            var valuePixel;
            if (valueUnit == 'em') {
                valuePixel = valueNumber * getEmInPxRatio();
            } else if (valueUnit == 'px') {
                valuePixel =  valueNumber;
            }
            if (propertyOperator == 'max') {
                valuePixel++;
            }
            return roundPixel(valuePixel);

            function roundPixel(number) {
                return Math.ceil(number);
            }

            function getEmInPxRatio() {
                var html = document.documentElement;
                var style = html.getAttribute('style');
                html.setAttribute('style', style + ';font-size:1em !important');
                var baseline = parseFloat(getComputedStyle(html).fontSize);
                html.setAttribute('style', style);
                return baseline;
            }
        }

        function getCriticalSize(isSizeBeforeBreakpoint) {
            if (isSizeBeforeBreakpoint) {
                return valuePixel-1;
            }
            return valuePixel;
        }

        function getCriticalSizeEmLabel(isSizeBeforeBreakpoint) {
            if (isSizeBeforeBreakpoint && propertyOperator == 'min') {
                return value+"-";
            }
            if (!isSizeBeforeBreakpoint && propertyOperator == 'max') {
                return value+"+";
            }
            return value;
        }

        return {
            px: valuePixel,
            axis: propertyAxis,
            isValid: function isValid() {
                return ( valuePixel > 0 && typeof( propertyAxis ) != 'undefined' );
            },
            getCriticalSizeShortLabel: function getCriticalSizeShortLabel(isSizeBeforeBreakpoint) {
                if (valueUnit == 'em') {
                    return getCriticalSizeEmLabel(isSizeBeforeBreakpoint);
                }
                return getCriticalSize(isSizeBeforeBreakpoint);
            },
            getCriticalSizeLabel: function getCriticalSizeLabel(isSizeBeforeBreakpoint) {
                if (valueUnit == 'em') {
                    var label = getCriticalSizeEmLabel(isSizeBeforeBreakpoint);
                    return label+" ("+getCriticalSize(isSizeBeforeBreakpoint)+"px)";
                }
                return getCriticalSize(isSizeBeforeBreakpoint)+"px";
            },
            getCriticalSize: getCriticalSize,
            getMediaQuery: function getMediaQuery() {
                return mediaQuery;
            },
            isSizeMatch: function isSizeMatch(size) {
                if (propertyOperator == 'min') {
                    return valuePixel<=size;
                }
                return valuePixel>size;
            }
        };
    };

    function getAxisBreakpoints() {

        var breakpointList = [ ];

        (function () {
            parseCssGetBreakpoints();
            var indexs = { width: [ ], height: [ ] };
            for (var i = 0; i < breakpointList.length; i++) {
                var breakpoint = breakpointList[i];
                if (breakpoint.isValid() && typeof indexs[ breakpoint.axis ][ breakpoint.px ] == 'undefined') {
                    axisList[ breakpoint.axis ].push(breakpoint);
                    indexs[ breakpoint.axis ][ breakpoint.px ] = axisList[ breakpoint.axis ].length - 1;
                }
            }
            axisList.width = axisList.width.sort(function (a, b) {
                return a.px - b.px;
            });
            axisList.height = axisList.height.sort(function (a, b) {
                return a.px - b.px;
            });
        })();

        function parseCssGetBreakpoints() {

            (function () {
                var mediaSelectorList = parseCssGetMediaSelectors();
                for (var i = 0; i < mediaSelectorList.length; i++) {
                    getBreakpointsFromMediaSelector(mediaSelectorList[ i ]);
                }
            })();

            function parseCssGetMediaSelectors() {

                return (function () {
                    var ruleList = parseCssGetRules();
                    var mediaSelectorList = [ ];
                    for (var i = 0; i < ruleList.length; i++) {
                        if (isMediaRule(ruleList[ i ])) {
                            mediaSelectorList.push(ruleList[ i ].media.mediaText);
                        }
                    }
                    return mediaSelectorList;
                })();

                function parseCssGetRules() {
                    var ruleList = [ ];
                    for (var i = 0; i < document.styleSheets.length; i++) {
                        try {
                            for (var j = 0; j < document.styleSheets[ i ].cssRules.length; j++) {
                                ruleList.push(document.styleSheets[ i ].cssRules[ j ]);
                            }
                        } catch (exception) {
                            // External stylesheet
                        }
                    }
                    return ruleList;
                }

                function isMediaRule(rule) {
                    return ( typeof( rule.media ) != 'undefined' );
                }
            }

            function getBreakpointsFromMediaSelector(mediaSelector) {

                (function () {
                    var mediaSelectorPartList = mediaSelector.split('(');
                    for (var i = 1; i < mediaSelectorPartList.length; i++) {
                        if (isMediaRulePartASizeSelector(mediaSelectorPartList[ i ])) {
                            breakpointList.push(Breakpoint(mediaSelectorPartList[ i ]));
                        }
                    }
                })();

                function isMediaRulePartASizeSelector(mediaSelectorPart) {
                    return ( mediaSelectorPart.indexOf(':') != -1 );
                }
            }
        }
    }

    function createActionPanel() {

        var fluidZoneList = { width: [ ], height: [ ] };

        (function () {
            getFluidZonesFromBreakpoints();
            displayFluidZonesActionPanel();
        })();

        function getFluidZonesFromBreakpoints() {

            (function () {
                formatFluidZonesByDirection('width');
                formatFluidZonesByDirection('height');
            })();

            function formatFluidZonesByDirection(direction) {
                if (axisList[ direction ].length != 0) {
                    var previousBreakpoint;
                    for (var i = 0; i < axisList[ direction ].length; i++) {
                        var breakpoint = axisList[ direction ][ i ];
                        var zone = [ ];
                        if (previousBreakpoint == null) {
                            zone.push(null);
                        } else if (previousBreakpoint.px + 1 != breakpoint.px) {
                            zone.push(previousBreakpoint);
                        }
                        zone.push(breakpoint);
                        fluidZoneList[ direction ].push(zone);
                        previousBreakpoint = breakpoint;
                    }
                    fluidZoneList[ direction ].push([ previousBreakpoint, '← ' + direction ]);
                }
            }
        }

        function displayFluidZonesActionPanel() {

            var resizedWindow;

            (function () {
                var panel = createPanelElement();
                if (axisList.width.length == 0 && axisList.height.length == 0) {
                    panel.addInformationToPanel('No breakpoint found');
                } else {
                    for (var j = 0; j < fluidZoneList.height.length; j++) {
                        panel.addFluidZoneToPanel('height', fluidZoneList.height[ j ], 'height');
                        panel.addBreakLineToPanel();
                    }
                    panel.addLinktoPanel('Breaq', 'http://tzi.fr/CSS/Responsive/Breaq-bookmarklet', 'See official project page');
                    for (var i = fluidZoneList.width.length-1; i>=0 ; i--) {
                        panel.addFluidZoneToPanel('width', fluidZoneList.width[ i ], 'width');
                    }
                    panel.addBreakLineToPanel();
                }
            })();

            function createPanelElement() {

                var boxStyle = 'float: right; margin: 0 3px 2px; border: 0; padding: 10px; background: rgba(0, 0, 0, 0.8);';
                var textResetStyle = 'color: white; font-family: Arial, sans-serif;font-weight: normal; font-size: 16px; text-decoration: none;';

                // internal
                var panel = document.getElementById('panelResize');
                if (panel == null) {
                    panel = document.createElement('div');
                    panel.setAttribute('id', 'panelResize');
                    panel.setAttribute('style', 'position: fixed; bottom:10px; right: 10px; z-index: 999999; text-align: right;');
                    document.body.appendChild(panel);
                }

                // private panel methods
                function addPanelElement(element) {
                    element.setAttribute('style', boxStyle+' min-width: 80px; box-sizing: content-box; -moz-box-sizing: content-box; text-align: center; '+textResetStyle);
                    panel.appendChild(element);
                }

                function addInformationToPanel(message) {
                    var information = document.createElement('span');
                    information.innerHTML = message;
                    addPanelElement(information);
                }

                function addLinktoPanel(label, href, title) {
                    link = document.createElement('a');
                    link.setAttribute('href', href);
                    link.setAttribute('target', '_blank');
                    link.setAttribute('title', title);
                    link.innerHTML = label;
                    addPanelElement(link);
                }

                function addBreakLineToPanel() {
                    var br = document.createElement('br');
                    br.setAttribute('style', 'clear: both');
                    panel.appendChild(br);
                }

                // public panel methods
                return {
                    addFluidZoneToPanel: function (direction, zoneBreakpointList, direction) {

                        (function () {
                            var zone = document.createElement('span');
                            zone.innerHTML = ' ';
                            var initialIndex = zoneBreakpointList.length-1;
                            for (var i=initialIndex; i>=0; i--) {
                                var element = createResizeElement(i);
                                if (element) {
                                    panel.appendChild(createResizeElement(i));
                                }
                            }
                        })();

                        function createResizeElement(i) {

                            var element;

                            return (function () {
                                var style = boxStyle+textResetStyle;
                                if (typeof( zoneBreakpointList[ i ] ) == 'object' && zoneBreakpointList[ i ] !== null) {
                                    var isSingleSize = (zoneBreakpointList.length==1);
                                    var isSizeBeforeBreakpoint = (i==1 || isSingleSize);
                                    createResizeButtonElement(zoneBreakpointList[i], isSizeBeforeBreakpoint);
                                    element.innerHTML = zoneBreakpointList[ i ].getCriticalSizeShortLabel(isSizeBeforeBreakpoint);
                                    style += 'border-radius: '+(isSingleSize?'10px':isSizeBeforeBreakpoint?'0 10px 10px 0':'10px 0 0 10px')+';';
                                    if (isSingleSize || isSizeBeforeBreakpoint) {
                                        style += 'margin-right: 0;';
                                    }
                                    if (isSingleSize || !isSizeBeforeBreakpoint) {
                                        style += 'margin-left: 0;';
                                    }
                                } else if (zoneBreakpointList[ i ]) {
                                    createResizeTextElement();
                                    element.innerHTML = zoneBreakpointList[ i ];
                                }
                                if (element) {
                                    element.setAttribute('style', style);
                                    return element;
                                }
                            })();

                            function createResizeTextElement() {
                                element = document.createElement('span');
                            }

                            function createResizeButtonElement(breakpoint, isSizeBeforeBreakpoint) {
                                var targetSize = breakpoint.getCriticalSize(isSizeBeforeBreakpoint);
                                element = document.createElement('a');
                                element.setAttribute('href', 'javascript:;');
                                element.setAttribute('title', 'Resize the '+breakpoint.axis+' to '+breakpoint.getCriticalSizeLabel(isSizeBeforeBreakpoint)+' '+(breakpoint.isSizeMatch(targetSize)?'':'not ')+'to match: '+breakpoint.getMediaQuery());
                                element.addEventListener('click', function () {
                                    var size = { };
                                    var alternate = direction == 'width' ? 'height' : 'width';
                                    var Direction = direction.charAt(0).toUpperCase() + direction.substr(1);
                                    var Alternate = alternate.charAt(0).toUpperCase() + alternate.substr(1);
                                    var existingPopup = ( resizedWindow != null && !resizedWindow.closed );
                                    size[ alternate ] = 600;
                                    if (existingPopup) {
                                        size[ alternate ] = resizedWindow[ 'outer' + Alternate ];
                                        resizedWindow.close();
                                    }
                                    resizedWindow = window.open(window.location + '#', 'resized', 'resizable,scrollbars=1,width=800,height=600');
                                    var resizePopup = function () {
                                        var innerSize;
                                        if (/AppleWebKit/.test(navigator.userAgent)) {
                                            innerSize = resizedWindow.document.documentElement[ 'client' + Direction ];
                                        } else {
                                            innerSize = resizedWindow[ 'inner' + Direction ];
                                        }
                                        size[ direction ] = targetSize + resizedWindow[ 'outer' + Direction ] - innerSize;
                                        resizedWindow.resizeTo(size.width, size.height);
                                        resizedWindow.focus();
                                    };
                                    var interval = setInterval(function () {
                                        if (resizedWindow.document.readyState == 'complete') {
                                            clearInterval(interval);
                                            resizePopup();
                                        }
                                    }, 100);
                                }, false);
                            }
                        }
                    },
                    addInformationToPanel: addInformationToPanel,
                    addLinktoPanel: addLinktoPanel,
                    addBreakLineToPanel: addBreakLineToPanel
                }
            }
        }
    }
})();

<commit_msg>Fix #2: Prevent multiple Breaq instance<commit_after>(function () {

    var axisList = { width: [ ], height: [ ] };

    (function () {
        getAxisBreakpoints();
        createActionPanel( );
    })();

    function Breakpoint(mediaSizeSelector) {

        var mediaQuery = initMediaQuery();
        var property = initProperty();
        var propertyAxis = initPropertyAxis();
        var propertyOperator = initPropertyOperator();
        var value = initValue();
        var valueUnit = initValueUnit();
        var valueNumber = initValueNumber();
        var valuePixel = initValuePixel();

        function initMediaQuery() {
            return mediaSizeSelector.split(')')[ 0 ].trim();
        }

        function initProperty() {
            return mediaQuery.split(':')[ 0 ].trim();
        }

        function initPropertyAxis() {
            if (property == 'max-width' || property == 'min-width') {
                return 'width';
            }
            if (property == 'max-height' || property == 'min-height') {
                return 'height';
            }
        }

        function initPropertyOperator() {
            if (property == 'max-height' || property == 'max-width') {
                return 'max';
            }
            if (property == 'min-height' || property == 'min-width') {
                return 'min';
            }
        }

        function initValue() {
            return mediaQuery.split(':')[ 1 ].trim();
        }

        function initValueUnit() {
            return value.replace(/[\d\.]/g, '');
        }

        function initValueNumber() {
            return Number(value.replace(/[^\d\.]/g, ''));
        }

        function initValuePixel() {
            var valuePixel;
            if (valueUnit == 'em') {
                valuePixel = valueNumber * getEmInPxRatio();
            } else if (valueUnit == 'px') {
                valuePixel =  valueNumber;
            }
            if (propertyOperator == 'max') {
                valuePixel++;
            }
            return roundPixel(valuePixel);

            function roundPixel(number) {
                return Math.ceil(number);
            }

            function getEmInPxRatio() {
                var html = document.documentElement;
                var style = html.getAttribute('style');
                html.setAttribute('style', style + ';font-size:1em !important');
                var baseline = parseFloat(getComputedStyle(html).fontSize);
                html.setAttribute('style', style);
                return baseline;
            }
        }

        function getCriticalSize(isSizeBeforeBreakpoint) {
            if (isSizeBeforeBreakpoint) {
                return valuePixel-1;
            }
            return valuePixel;
        }

        function getCriticalSizeEmLabel(isSizeBeforeBreakpoint) {
            if (isSizeBeforeBreakpoint && propertyOperator == 'min') {
                return value+"-";
            }
            if (!isSizeBeforeBreakpoint && propertyOperator == 'max') {
                return value+"+";
            }
            return value;
        }

        return {
            px: valuePixel,
            axis: propertyAxis,
            isValid: function isValid() {
                return ( valuePixel > 0 && typeof( propertyAxis ) != 'undefined' );
            },
            getCriticalSizeShortLabel: function getCriticalSizeShortLabel(isSizeBeforeBreakpoint) {
                if (valueUnit == 'em') {
                    return getCriticalSizeEmLabel(isSizeBeforeBreakpoint);
                }
                return getCriticalSize(isSizeBeforeBreakpoint);
            },
            getCriticalSizeLabel: function getCriticalSizeLabel(isSizeBeforeBreakpoint) {
                if (valueUnit == 'em') {
                    var label = getCriticalSizeEmLabel(isSizeBeforeBreakpoint);
                    return label+" ("+getCriticalSize(isSizeBeforeBreakpoint)+"px)";
                }
                return getCriticalSize(isSizeBeforeBreakpoint)+"px";
            },
            getCriticalSize: getCriticalSize,
            getMediaQuery: function getMediaQuery() {
                return mediaQuery;
            },
            isSizeMatch: function isSizeMatch(size) {
                if (propertyOperator == 'min') {
                    return valuePixel<=size;
                }
                return valuePixel>size;
            }
        };
    };

    function getAxisBreakpoints() {

        var breakpointList = [ ];

        (function () {
            parseCssGetBreakpoints();
            var indexs = { width: [ ], height: [ ] };
            for (var i = 0; i < breakpointList.length; i++) {
                var breakpoint = breakpointList[i];
                if (breakpoint.isValid() && typeof indexs[ breakpoint.axis ][ breakpoint.px ] == 'undefined') {
                    axisList[ breakpoint.axis ].push(breakpoint);
                    indexs[ breakpoint.axis ][ breakpoint.px ] = axisList[ breakpoint.axis ].length - 1;
                }
            }
            axisList.width = axisList.width.sort(function (a, b) {
                return a.px - b.px;
            });
            axisList.height = axisList.height.sort(function (a, b) {
                return a.px - b.px;
            });
        })();

        function parseCssGetBreakpoints() {

            (function () {
                var mediaSelectorList = parseCssGetMediaSelectors();
                for (var i = 0; i < mediaSelectorList.length; i++) {
                    getBreakpointsFromMediaSelector(mediaSelectorList[ i ]);
                }
            })();

            function parseCssGetMediaSelectors() {

                return (function () {
                    var ruleList = parseCssGetRules();
                    var mediaSelectorList = [ ];
                    for (var i = 0; i < ruleList.length; i++) {
                        if (isMediaRule(ruleList[ i ])) {
                            mediaSelectorList.push(ruleList[ i ].media.mediaText);
                        }
                    }
                    return mediaSelectorList;
                })();

                function parseCssGetRules() {
                    var ruleList = [ ];
                    for (var i = 0; i < document.styleSheets.length; i++) {
                        try {
                            for (var j = 0; j < document.styleSheets[ i ].cssRules.length; j++) {
                                ruleList.push(document.styleSheets[ i ].cssRules[ j ]);
                            }
                        } catch (exception) {
                            // External stylesheet
                        }
                    }
                    return ruleList;
                }

                function isMediaRule(rule) {
                    return ( typeof( rule.media ) != 'undefined' );
                }
            }

            function getBreakpointsFromMediaSelector(mediaSelector) {

                (function () {
                    var mediaSelectorPartList = mediaSelector.split('(');
                    for (var i = 1; i < mediaSelectorPartList.length; i++) {
                        if (isMediaRulePartASizeSelector(mediaSelectorPartList[ i ])) {
                            breakpointList.push(Breakpoint(mediaSelectorPartList[ i ]));
                        }
                    }
                })();

                function isMediaRulePartASizeSelector(mediaSelectorPart) {
                    return ( mediaSelectorPart.indexOf(':') != -1 );
                }
            }
        }
    }

    function createActionPanel() {

        var fluidZoneList = { width: [ ], height: [ ] };

        (function () {
            getFluidZonesFromBreakpoints();
            displayFluidZonesActionPanel();
        })();

        function getFluidZonesFromBreakpoints() {

            (function () {
                formatFluidZonesByDirection('width');
                formatFluidZonesByDirection('height');
            })();

            function formatFluidZonesByDirection(direction) {
                if (axisList[ direction ].length != 0) {
                    var previousBreakpoint;
                    for (var i = 0; i < axisList[ direction ].length; i++) {
                        var breakpoint = axisList[ direction ][ i ];
                        var zone = [ ];
                        if (previousBreakpoint == null) {
                            zone.push(null);
                        } else if (previousBreakpoint.px + 1 != breakpoint.px) {
                            zone.push(previousBreakpoint);
                        }
                        zone.push(breakpoint);
                        fluidZoneList[ direction ].push(zone);
                        previousBreakpoint = breakpoint;
                    }
                    fluidZoneList[ direction ].push([ previousBreakpoint, '← ' + direction ]);
                }
            }
        }

        function displayFluidZonesActionPanel() {

            var resizedWindow;

            (function () {
                var panel = createPanelElement();
                if (! panel) {
                    return;
                }
                if (axisList.width.length == 0 && axisList.height.length == 0) {
                    panel.addInformationToPanel('No breakpoint found');
                } else {
                    for (var j = 0; j < fluidZoneList.height.length; j++) {
                        panel.addFluidZoneToPanel('height', fluidZoneList.height[ j ], 'height');
                        panel.addBreakLineToPanel();
                    }
                    panel.addLinktoPanel('Breaq', 'http://tzi.fr/CSS/Responsive/Breaq-bookmarklet', 'See official project page');
                    for (var i = fluidZoneList.width.length-1; i>=0 ; i--) {
                        panel.addFluidZoneToPanel('width', fluidZoneList.width[ i ], 'width');
                    }
                    panel.addBreakLineToPanel();
                }
            })();

            function createPanelElement() {

                var panelElementId = 'BreaqBookmarkletPanel'
                var boxStyle = 'float: right; margin: 0 3px 2px; border: 0; padding: 10px; background: rgba(0, 0, 0, 0.8);';
                var textResetStyle = 'color: white; font-family: Arial, sans-serif;font-weight: normal; font-size: 16px; text-decoration: none;';

                // internal
                var panel = document.getElementById(panelElementId);
                if (panel !== null) {
                    return ;
                }
                panel = document.createElement('div');
                panel.setAttribute('id', panelElementId);
                panel.setAttribute('style', 'position: fixed; bottom:10px; right: 10px; z-index: 999999; text-align: right;');
                document.body.appendChild(panel);

                // private panel methods
                function addPanelElement(element) {
                    element.setAttribute('style', boxStyle+' min-width: 80px; box-sizing: content-box; -moz-box-sizing: content-box; text-align: center; '+textResetStyle);
                    panel.appendChild(element);
                }

                function addInformationToPanel(message) {
                    var information = document.createElement('span');
                    information.innerHTML = message;
                    addPanelElement(information);
                }

                function addLinktoPanel(label, href, title) {
                    link = document.createElement('a');
                    link.setAttribute('href', href);
                    link.setAttribute('target', '_blank');
                    link.setAttribute('title', title);
                    link.innerHTML = label;
                    addPanelElement(link);
                }

                function addBreakLineToPanel() {
                    var br = document.createElement('br');
                    br.setAttribute('style', 'clear: both');
                    panel.appendChild(br);
                }

                // public panel methods
                return {
                    addFluidZoneToPanel: function (direction, zoneBreakpointList, direction) {

                        (function () {
                            var zone = document.createElement('span');
                            zone.innerHTML = ' ';
                            var initialIndex = zoneBreakpointList.length-1;
                            for (var i=initialIndex; i>=0; i--) {
                                var element = createResizeElement(i);
                                if (element) {
                                    panel.appendChild(createResizeElement(i));
                                }
                            }
                        })();

                        function createResizeElement(i) {

                            var element;

                            return (function () {
                                var style = boxStyle+textResetStyle;
                                if (typeof( zoneBreakpointList[ i ] ) == 'object' && zoneBreakpointList[ i ] !== null) {
                                    var isSingleSize = (zoneBreakpointList.length==1);
                                    var isSizeBeforeBreakpoint = (i==1 || isSingleSize);
                                    createResizeButtonElement(zoneBreakpointList[i], isSizeBeforeBreakpoint);
                                    element.innerHTML = zoneBreakpointList[ i ].getCriticalSizeShortLabel(isSizeBeforeBreakpoint);
                                    style += 'border-radius: '+(isSingleSize?'10px':isSizeBeforeBreakpoint?'0 10px 10px 0':'10px 0 0 10px')+';';
                                    if (isSingleSize || isSizeBeforeBreakpoint) {
                                        style += 'margin-right: 0;';
                                    }
                                    if (isSingleSize || !isSizeBeforeBreakpoint) {
                                        style += 'margin-left: 0;';
                                    }
                                } else if (zoneBreakpointList[ i ]) {
                                    createResizeTextElement();
                                    element.innerHTML = zoneBreakpointList[ i ];
                                }
                                if (element) {
                                    element.setAttribute('style', style);
                                    return element;
                                }
                            })();

                            function createResizeTextElement() {
                                element = document.createElement('span');
                            }

                            function createResizeButtonElement(breakpoint, isSizeBeforeBreakpoint) {
                                var targetSize = breakpoint.getCriticalSize(isSizeBeforeBreakpoint);
                                element = document.createElement('a');
                                element.setAttribute('href', 'javascript:;');
                                element.setAttribute('title', 'Resize the '+breakpoint.axis+' to '+breakpoint.getCriticalSizeLabel(isSizeBeforeBreakpoint)+' '+(breakpoint.isSizeMatch(targetSize)?'':'not ')+'to match: '+breakpoint.getMediaQuery());
                                element.addEventListener('click', function () {
                                    var size = { };
                                    var alternate = direction == 'width' ? 'height' : 'width';
                                    var Direction = direction.charAt(0).toUpperCase() + direction.substr(1);
                                    var Alternate = alternate.charAt(0).toUpperCase() + alternate.substr(1);
                                    var existingPopup = ( resizedWindow != null && !resizedWindow.closed );
                                    size[ alternate ] = 600;
                                    if (existingPopup) {
                                        size[ alternate ] = resizedWindow[ 'outer' + Alternate ];
                                        resizedWindow.close();
                                    }
                                    resizedWindow = window.open(window.location + '#', 'resized', 'resizable,scrollbars=1,width=800,height=600');
                                    var resizePopup = function () {
                                        var innerSize;
                                        if (/AppleWebKit/.test(navigator.userAgent)) {
                                            innerSize = resizedWindow.document.documentElement[ 'client' + Direction ];
                                        } else {
                                            innerSize = resizedWindow[ 'inner' + Direction ];
                                        }
                                        size[ direction ] = targetSize + resizedWindow[ 'outer' + Direction ] - innerSize;
                                        resizedWindow.resizeTo(size.width, size.height);
                                        resizedWindow.focus();
                                    };
                                    var interval = setInterval(function () {
                                        if (resizedWindow.document.readyState == 'complete') {
                                            clearInterval(interval);
                                            resizePopup();
                                        }
                                    }, 100);
                                }, false);
                            }
                        }
                    },
                    addInformationToPanel: addInformationToPanel,
                    addLinktoPanel: addLinktoPanel,
                    addBreakLineToPanel: addBreakLineToPanel
                }
            }
        }
    }
})();

<|endoftext|>


<commit_before>/*
Copyright 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

'use strict';

import React from 'react';
import GeminiScrollbar from 'react-gemini-scrollbar';
import request from 'browser-request';
import { _t } from 'matrix-react-sdk/lib/languageHandler';
import sanitizeHtml from 'sanitize-html';

module.exports = React.createClass({
    displayName: 'HomePage',

    propTypes: {
        // URL base of the team server. Optional.
        teamServerUrl: React.PropTypes.string,
        // Team token. Optional. If set, used to get the static homepage of the team
        //      associated. If unset, homePageUrl will be used.
        teamToken: React.PropTypes.string,
        // URL to use as the iFrame src. Defaults to /home.html.
        homePageUrl: React.PropTypes.string,
    },

    getInitialState: function() {
        return {
            iframeSrc: '',
            page: '',
        };
    },

    translate: function(s) {
        s = sanitizeHtml(_t(s));
        // ugly fix for https://github.com/vector-im/riot-web/issues/4243
        s = s.replace(/Riot\.im/, 'Riot.im');
        s = s.replace(/\[matrix\]/, '');
        return s;
    },

    componentWillMount: function() {
        if (this.props.teamToken && this.props.teamServerUrl) {
            this.setState({
                iframeSrc: `${this.props.teamServerUrl}/static/${this.props.teamToken}/home.html`
            });
        }
        else {
            // we use request() to inline the homepage into the react component
            // so that it can inherit CSS and theming easily rather than mess around
            // with iframes and trying to synchronise document.stylesheets.

            let src = this.props.homePageUrl || 'home.html';

            request(
                { method: "GET", url: src },
                (err, response, body) => {
                    if (err || response.status < 200 || response.status >= 300) {
                        console.log(err);
                        this.setState({ page: "Couldn't load home page" });
                    }

                    body = body.replace(/_t\(['"]([\s\S]*?)['"]\)/mg, (match, g1)=>this.translate(g1));
                    this.setState({ page: body });
                }
            );
        }
    },

    render: function() {
        if (this.state.iframeSrc) {
            return (

            );
        }
        else {
            return (
                <GeminiScrollbar autoshow={true} className="mx_HomePage">

                </GeminiScrollbar>
            );
        }
    }
});
<commit_msg>Fix broken riot.im link on homepage<commit_after>/*
Copyright 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

'use strict';

import React from 'react';
import GeminiScrollbar from 'react-gemini-scrollbar';
import request from 'browser-request';
import { _t } from 'matrix-react-sdk/lib/languageHandler';
import sanitizeHtml from 'sanitize-html';

module.exports = React.createClass({
    displayName: 'HomePage',

    propTypes: {
        // URL base of the team server. Optional.
        teamServerUrl: React.PropTypes.string,
        // Team token. Optional. If set, used to get the static homepage of the team
        //      associated. If unset, homePageUrl will be used.
        teamToken: React.PropTypes.string,
        // URL to use as the iFrame src. Defaults to /home.html.
        homePageUrl: React.PropTypes.string,
    },

    getInitialState: function() {
        return {
            iframeSrc: '',
            page: '',
        };
    },

    translate: function(s) {
        s = sanitizeHtml(_t(s));
        // ugly fix for https://github.com/vector-im/riot-web/issues/4243
        s = s.replace(/Riot\.im/, 'Riot.im');
        s = s.replace(/\[matrix\]/, '');
        return s;
    },

    componentWillMount: function() {
        if (this.props.teamToken && this.props.teamServerUrl) {
            this.setState({
                iframeSrc: `${this.props.teamServerUrl}/static/${this.props.teamToken}/home.html`
            });
        }
        else {
            // we use request() to inline the homepage into the react component
            // so that it can inherit CSS and theming easily rather than mess around
            // with iframes and trying to synchronise document.stylesheets.

            let src = this.props.homePageUrl || 'home.html';

            request(
                { method: "GET", url: src },
                (err, response, body) => {
                    if (err || response.status < 200 || response.status >= 300) {
                        console.log(err);
                        this.setState({ page: "Couldn't load home page" });
                    }

                    body = body.replace(/_t\(['"]([\s\S]*?)['"]\)/mg, (match, g1)=>this.translate(g1));
                    this.setState({ page: body });
                }
            );
        }
    },

    render: function() {
        if (this.state.iframeSrc) {
            return (

            );
        }
        else {
            return (
                <GeminiScrollbar autoshow={true} className="mx_HomePage">

                </GeminiScrollbar>
            );
        }
    }
});
<|endoftext|>


<commit_before><commit_msg>auditLog fix<commit_after><|endoftext|>


<commit_before>/**
 *
 *    Copyright (c) 2020 Silicon Labs
 *
 *    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.
 *
 *
 * @jest-environment node
 */
const path = require('path')
const fs = require('fs')
const startup = require('../src-electron/main-process/startup.js')
const env = require('../src-electron/util/env.js')
const args = require('../src-electron/util/args.js')
const testUtil = require('./test-util.js')

test('startup: start generation', () => {
  let testGenDir = path.join(path.join(__dirname, '.zap/'), 'test-gen')
  if (!fs.existsSync(testGenDir)) fs.mkdirSync(testGenDir, { recursive: true })
  return startup.startGeneration(
    testGenDir,
    testUtil.testZigbeeGenerationTemplates,
    args.zclPropertiesFile,
    null,
    {
      quit: false,
      logger: (msg) => {},
    }
  )
}, 10000)

test('startup: self-check', () => {
  return startup.startSelfCheck({ logger: (msg) => {}, quit: false })
}, 5000)

test('startup: convert', () => {
  let files = []
  files.push(path.join(__dirname, 'resource/test-light.isc'))
  let output = '{basename}.conversion'
  let testOutputFile = path.join(__dirname, 'resource/test-light.conversion')
  return startup
    .startConvert(files, output, {
      quit: false,
      noZapFileLog: true,
      logger: (msg) => {},
    })
    .then(() => {
      expect(fs.existsSync(testOutputFile)).toBeTruthy()
      fs.unlinkSync(testOutputFile)
    })
}, 5000)

test('startup: analyze', () => {
  let files = []
  files.push(path.join(__dirname, 'resource/test-light.isc'))
  return startup.startAnalyze(files, {
    quit: false,
    cleanDb: true,
    logger: (msg) => {},
  })
}, 5000)
<commit_msg>Reuse database for the analyze unit test.<commit_after>/**
 *
 *    Copyright (c) 2020 Silicon Labs
 *
 *    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.
 *
 *
 * @jest-environment node
 */
const path = require('path')
const fs = require('fs')
const startup = require('../src-electron/main-process/startup.js')
const env = require('../src-electron/util/env.js')
const args = require('../src-electron/util/args.js')
const testUtil = require('./test-util.js')

test('startup: start generation', () => {
  let testGenDir = path.join(path.join(__dirname, '.zap/'), 'test-gen')
  if (!fs.existsSync(testGenDir)) fs.mkdirSync(testGenDir, { recursive: true })
  return startup.startGeneration(
    testGenDir,
    testUtil.testZigbeeGenerationTemplates,
    args.zclPropertiesFile,
    null,
    {
      quit: false,
      logger: (msg) => {},
    }
  )
}, 10000)

test('startup: self-check', () => {
  return startup.startSelfCheck({ logger: (msg) => {}, quit: false })
}, 5000)

test('startup: convert', () => {
  let files = []
  files.push(path.join(__dirname, 'resource/test-light.isc'))
  let output = '{basename}.conversion'
  let testOutputFile = path.join(__dirname, 'resource/test-light.conversion')
  return startup
    .startConvert(files, output, {
      quit: false,
      noZapFileLog: true,
      logger: (msg) => {},
    })
    .then(() => {
      expect(fs.existsSync(testOutputFile)).toBeTruthy()
      fs.unlinkSync(testOutputFile)
    })
}, 5000)

test('startup: analyze', () => {
  let files = []
  files.push(path.join(__dirname, 'resource/test-light.isc'))
  return startup.startAnalyze(files, {
    quit: false,
    cleanDb: false,
    logger: (msg) => {},
  })
}, 5000)
<|endoftext|>


<commit_before>/**   For testing asynchronous json downloading, here we have a tiny http server.
 *
 *    For every request (regardless f path) it responds with the json [0,1,2,3,4,5,6,7,8,9]
 *    but writing out each number one at a time.
 *
 *    You can start this server up and visit it in a browser to see the numbers stream in.
 */

require('color');

function startServer( grunt, port ) {

   function echoBackBody(req, res) {

      grunt.verbose.ok('will just echo the same back');

      req.on('readable', function () {
         var reqBody = req.read().toString();
         grunt.verbose.ok('echoing back ' + reqBody.blue);
         res.write(reqBody);
      });

      req.on('end', function () {
         grunt.verbose.ok('done echoing back');
         res.end(req.body);
      });
   }

   function replyWithTenSlowNumbers(_req, res) {
      sendJsonHeaders(res);

      var NUMBER_INTERVAL = 250;
      var MAX_NUMBER = 9;

      grunt.verbose.ok('slow number server: will write numbers 0 ..' + String(MAX_NUMBER).blue + ' out as a json array at a rate of one per', String(NUMBER_INTERVAL).blue + 'ms');

      res.write('[\n');

      var curNumber = 0;

      var inervalId = setInterval(function () {

         res.write(String(curNumber));

         if (curNumber == MAX_NUMBER) {

            res.end(']');
            clearInterval(inervalId);
            grunt.verbose.writeln('slow number server: finished writing out');
         } else {
            res.write(',\n');
         }

         curNumber++;

      }, NUMBER_INTERVAL);
   }

   function replyWithStaticJson(req, res) {
      sendJsonHeaders(res);

      var filename = req.url.replace('/static', 'test');

      grunt.verbose.ok('will respond with contents of file ' + filename.blue);

      require('fs').readFile(filename, 'utf8', function (err,data) {
         if (err) {
            grunt.log.error('could not read static file ' + filename.red);
            return;
         }

         res.end(data);

         grunt.verbose.ok('read file ' + filename.blue);
      });
   }

   function sendJsonHeaders(res) {
      var JSON_MIME_TYPE = "application/octet-stream";
      res.setHeader("Content-Type", JSON_MIME_TYPE);
      res.writeHead(200);
   }

   function answerRequest(req, res) {

      grunt.verbose.ok('got ' + req.method.blue + ' request for url ' + req.url.blue +
                           (req.body? ' with body ' + req.body : '')
      );

      var urlMappings = {
         '/stream/echoback': echoBackBody
      ,  '/static/json': replyWithStaticJson
      ,  '/stream/tenSlowNumbers': replyWithTenSlowNumbers
      };

      var responder;

      for( var i in urlMappings ) {
         if( req.url.indexOf(i) == 0 ) {
            responder = urlMappings[i];
            grunt.verbose.ok( 'url starts with ' + i.blue + ' so will reply using ' + responder.name.blue);
            break;
         }
      }

      if( !responder ) {
         grunt.log.error("no mapping for url " + req.url.red);
         return;
      }

      responder(req, res);

   }

   require('http').createServer().on('request', answerRequest).listen(port);
   grunt.log.writeln('streaming server started on port'.green, String(port).blue);
}

module.exports.startServer = startServer;

<commit_msg>make streamsource slighlty neater<commit_after>/**   For testing asynchronous json downloading, here we have a tiny http server.
 *
 *    For every request (regardless f path) it responds with the json [0,1,2,3,4,5,6,7,8,9]
 *    but writing out each number one at a time.
 *
 *    You can start this server up and visit it in a browser to see the numbers stream in.
 */

require('color');

function startServer( grunt, port ) {

   function echoBackBody(req, res) {

      grunt.verbose.ok('will just echo the same back');

      req.on('readable', function () {
         var reqBody = req.read().toString();
         grunt.verbose.ok('echoing back ' + reqBody.blue);
         res.write(reqBody);
      });

      req.on('end', function () {
         grunt.verbose.ok('done echoing back');
         res.end(req.body);
      });
   }

   function replyWithTenSlowNumbers(_req, res) {
      sendJsonHeaders(res);

      var NUMBER_INTERVAL = 250;
      var MAX_NUMBER = 9;

      grunt.verbose.ok('slow number server: will write numbers 0 ..' + String(MAX_NUMBER).blue + ' out as a json array at a rate of one per', String(NUMBER_INTERVAL).blue + 'ms');

      res.write('[\n');

      var curNumber = 0;

      var inervalId = setInterval(function () {

         res.write(String(curNumber));

         if (curNumber == MAX_NUMBER) {

            res.end(']');
            clearInterval(inervalId);
            grunt.verbose.writeln('slow number server: finished writing out');
         } else {
            res.write(',\n');
         }

         curNumber++;

      }, NUMBER_INTERVAL);
   }

   function replyWithStaticJson(req, res) {
      sendJsonHeaders(res);

      var filename = req.url.replace('/static', 'test');

      grunt.verbose.ok('will respond with contents of file ' + filename.blue);

      require('fs').readFile(filename, 'utf8', function (err,data) {
         if (err) {
            grunt.log.error('could not read static file ' + filename.red);
            return;
         }

         res.end(data);

         grunt.verbose.ok('read file ' + filename.blue);
      });
   }

   function sendJsonHeaders(res) {
      var JSON_MIME_TYPE = "application/octet-stream";
      res.setHeader("Content-Type", JSON_MIME_TYPE);
      res.writeHead(200);
   }

   function answerRequest(req, res) {

      grunt.verbose.ok(
         'got ' + req.method.blue + ' request for url ' + req.url.blue +
            (req.body? ' with body ' + req.body : '')
      );

      var urlMappings = {
         '/stream/echoback': echoBackBody
      ,  '/static/json': replyWithStaticJson
      ,  '/stream/tenSlowNumbers': replyWithTenSlowNumbers
      };

      var responder;

      for( var i in urlMappings ) {
         if( req.url.indexOf(i) == 0 ) {
            responder = urlMappings[i];
            grunt.verbose.ok( 'url starts with ' + i.blue + ' so will reply using ' + responder.name.blue);
            break;
         }
      }

      if( !responder ) {
         grunt.log.error("no mapping for url " + req.url.red);
         return;
      }

      responder(req, res);

   }

   require('http')
      .createServer(answerRequest)
      .listen(port);

   grunt.log.writeln('streaming server started on port'.green, String(port).blue);
}

module.exports.startServer = startServer;

<|endoftext|>


<commit_before><commit_msg>Add vendor.bundle<commit_after><|endoftext|>


<commit_before>'use strict'

var fs = require('fs')
var path = require('path')
var https = require('https')
var concat = require('concat-stream')
var yauzl = require('yauzl')
var dsv = require('d3-dsv')
var bail = require('bail')

var found = false

var scopes = {
  I: 'individual',
  M: 'macrolanguage',
  S: 'special'
}

var types = {
  A: 'ancient',
  C: 'constructed',
  E: 'extinct',
  H: 'historical',
  L: 'living',
  S: 'special'
}

// Note:
// You can find download links here:
// <https://iso639-3.sil.org/code_tables/download_tables>
// Just get the complete code tables in UTF-8.

https
  .request(
    'https://iso639-3.sil.org/sites/iso639-3/files/downloads/iso-639-3_Code_Tables_20190408.zip',
    onrequest
  )
  .end()

function onrequest(res) {
  res
    .pipe(fs.createWriteStream('archive.zip'))
    .on('close', onclose)
    .on('error', bail)
}

function onclose() {
  yauzl.open('archive.zip', {lazyEntries: true}, onopen)
}

function onopen(err, archive) {
  bail(err)

  read()

  archive.on('entry', onentry)
  archive.on('end', onend)

  function onentry(entry) {
    if (path.basename(entry.fileName) !== 'iso-639-3_20190408.tab') {
      return read()
    }

    found = true
    archive.openReadStream(entry, onreadstream)
  }

  function onreadstream(err, rs) {
    bail(err)
    rs.pipe(concat(onconcat)).on('error', bail)
    rs.on('end', read)
  }

  function read() {
    archive.readEntry()
  }
}

function onend() {
  if (!found) {
    throw new Error('File not found')
  }
}

function onconcat(body) {
  var data = dsv.tsvParse(String(body)).map(mapper)

  fs.writeFile('index.json', JSON.stringify(data, 0, 2) + '\n', bail)
}

function mapper(d) {
  return {
    name: d.Ref_Name || null,
    type: types[d.d_Type],
    scope: scopes[d.Scope],
    iso6393: d.Id,
    iso6392B: d.Part2B || null,
    iso6392T: d.Part2T || null,
    iso6391: d.Part1 || null
  }
}
<commit_msg>Fix missing type<commit_after>'use strict'

var fs = require('fs')
var path = require('path')
var https = require('https')
var concat = require('concat-stream')
var yauzl = require('yauzl')
var dsv = require('d3-dsv')
var bail = require('bail')

var found = false

var scopes = {
  I: 'individual',
  M: 'macrolanguage',
  S: 'special'
}

var types = {
  A: 'ancient',
  C: 'constructed',
  E: 'extinct',
  H: 'historical',
  L: 'living',
  S: 'special'
}

// Note:
// You can find download links here:
// <https://iso639-3.sil.org/code_tables/download_tables>
// Just get the complete code tables in UTF-8.

https
  .request(
    'https://iso639-3.sil.org/sites/iso639-3/files/downloads/iso-639-3_Code_Tables_20190408.zip',
    onrequest
  )
  .end()

function onrequest(res) {
  res
    .pipe(fs.createWriteStream('archive.zip'))
    .on('close', onclose)
    .on('error', bail)
}

function onclose() {
  yauzl.open('archive.zip', {lazyEntries: true}, onopen)
}

function onopen(err, archive) {
  bail(err)

  read()

  archive.on('entry', onentry)
  archive.on('end', onend)

  function onentry(entry) {
    if (path.basename(entry.fileName) !== 'iso-639-3_20190408.tab') {
      return read()
    }

    found = true
    archive.openReadStream(entry, onreadstream)
  }

  function onreadstream(err, rs) {
    bail(err)
    rs.pipe(concat(onconcat)).on('error', bail)
    rs.on('end', read)
  }

  function read() {
    archive.readEntry()
  }
}

function onend() {
  if (!found) {
    throw new Error('File not found')
  }
}

function onconcat(body) {
  var data = dsv.tsvParse(String(body)).map(mapper)

  fs.writeFile('index.json', JSON.stringify(data, 0, 2) + '\n', bail)
}

function mapper(d) {
  return {
    name: d.Ref_Name || null,
    type: types[d.Language_Type],
    scope: scopes[d.Scope],
    iso6393: d.Id,
    iso6392B: d.Part2B || null,
    iso6392T: d.Part2T || null,
    iso6391: d.Part1 || null
  }
}
<|endoftext|>