<commit_before>(function () {
var Url = require('fire-url');
var Fs = require('fire-fs');
var Path = require('fire-path');

function _escape(html) {
  return String(html)
    .replace(/&/g, '&')
    .replace(/"/g, '"')
    .replace(/</g, '<')
    .replace(/>/g, '>');
}

function _clean(str) {
  str = str
    .replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, '')
    .replace(/^function *\(.*\)\s*{|\(.*\) *=> *{?/, '')
    .replace(/\s+\}$/, '');

  var spaces = str.match(/^\n?( *)/)[1].length,
      tabs = str.match(/^\n?(\t*)/)[1].length,
      re = new RegExp('^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');

  str = str.replace(re, '');

  // trim
  return str.replace(/^\s+|\s+$/g, '');
}

function _fragment(html) {
    var args = arguments,
        div = document.createElement('div'),
        i = 1;

    div.innerHTML = html.replace(/%([se])/g, function(_, type){
        switch (type) {
            case 's': return String(args[i++]);
            case 'e': return _escape(args[i++]);
        }
    });

    return div.firstChild;
}

function _makeUrl(s) {
    var search = window.location.search;

    // Remove previous grep query parameter if present
    if (search) {
        search = search.replace(/[?&]grep=[^&\s]*/g, '').replace(/^&/, '?');
    }

    return window.location.pathname + (search ? search + '&' : '?' ) + 'grep=' + encodeURIComponent(s);
}

function _createPassEL ( test ) {
    return _fragment('

%e%ems

',
                     test.speed, test.title, test.duration);
}

function _createPendingEL ( test ) {
    return _fragment('

%e

', test.title);
}

function _createFailEL ( test, err ) {
    var el = _fragment('

%e

', test.title, _makeUrl(test.fullTitle));
    var errText = err.stack;

    // FF / Opera do not add the message
    if ( !~errText.indexOf(err.message) ) {
        errText = err.message + '\n' + errText;
    }

    // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
    // check for the result of the stringifying.
    if ('[object Error]' === errText) errText = err.message;

    Polymer.dom(el).appendChild(_fragment('
%e
', errText));
    return el;
}

//
Editor.registerPanel( 'tester.panel', {
    is: 'editor-tester',

    properties: {
    },

    ready: function () {
        this.reset();
    },

    'panel:open': function ( argv ) {
        if ( !argv || !argv.name ) {
            this._tests = ['packages://tester/env/empty.html'];
            this.reset();
            this.next();
            return;
        }

        this.runTests(argv.name);
    },

    'tester:run-tests': function ( pkgName ) {
        Editor.Panel.focus('tester.panel');
        this.runTests(pkgName);
    },

    reset: function () {
        this.passes = 0;
        this.failures = 0;
        this.duration = 0;
        this.progress = 0;

        this.lastPasses = 0;
        this.lastFailures = 0;
        this.lastDuration = 0;
        this.lastProgress = 0;

        this.curTestIdx = -1;

        var mochaReportEL = this.$['mocha-report'];
        while ( mochaReportEL.children.length ) {
            mochaReportEL.firstChild.remove();
        }
        this.stack = [mochaReportEL];

        if ( !this._tests || this._tests.length === 0 ) {
            this._tests = ['packages://tester/env/empty.html'];
        }
    },

    next: function () {
        this.lastPasses = this.passes;
        this.lastFailures = this.failures;
        this.lastDuration = this.duration;
        this.lastProgress = this.progress;

        this.curTestIdx += 1;
        if ( this.curTestIdx < this._tests.length ) {
            this._run(this._tests[this.curTestIdx]);
        }
        else {
            this._end();
        }
    },

    resetRunner: function () {
        // NOTE: The reason I don't use this.$.runner.src directly is because it will not stop
        //       the current running tests, even if I call runner.stop(). So destroy the webview is
        //       and recreate it is better than give him a source.
        if ( this.$.runner ) {
            Polymer.dom(this.$.webviewWrapper).removeChild(this.$.runner);
            this.$.runner = null;
        }

        var webview = document.createElement('webview');
        webview.setAttribute( 'id', 'runner' );
        // webview.setAttribute( 'src', Editor.url(url) );
        webview.setAttribute( 'nodeintegration', '' );
        webview.setAttribute( 'disablewebsecurity', '' );
        webview.setAttribute( 'autosize', 'on' );
        webview.setAttribute( 'maxheight', '200' );
        webview.addEventListener( 'console-message', this._onRunnerConsole.bind(this) );
        webview.addEventListener( 'ipc-message', this._onRunnerIpc.bind(this) );
        webview.addEventListener( 'crashed', function ( event ) {
            console.error( 'webview crashed!' );
        });
        webview.addEventListener( 'gpu-crashed', function ( event ) {
            console.error( 'webview gpu-crashed!' );
        });
        webview.addEventListener( 'plugin-crashed', function ( event ) {
            console.error( 'webview plugin-crashed!' );
        });
        this.$.runner = webview;

        Polymer.dom(this.$.webviewWrapper).appendChild(this.$.runner);
    },

    runTests: function ( pkgName ) {
        //
        Editor.Package.queryInfo( pkgName, function ( result ) {
            var pkgInfo = result.info;
            var tests = pkgInfo.tests || [];
            this._tests = tests.map( function ( path ) {
                if ( pkgInfo.build )
                    return Url.join( 'packages://', pkgInfo.name, 'bin', 'dev', path );

                return Url.join( 'packages://', pkgInfo.name, path );
            });
            this.reset();
            this.next();

        }.bind(this));
    },

    reload: function () {
        this.reset();
        this.next();
    },

    _run: function ( url ) {
        this.resetRunner();
        if ( this.$.runner ) {
            var src = Editor.url(url);
            if ( Fs.existsSync(src) ) {
                var extname = Path.extname(src);
                if ( extname === '.html' ) {
                    this.$.runner.src = src;
                }
                else if ( extname === '.js') {
                    this.$.runner.src = Editor.url('packages://tester/env/env-core.html');
                    Editor.sendToCore( 'tester:run-test', src );
                }
                this.$.runner.title = Path.basename(src);
            } else {
                this.$.runner.src = Editor.url('packages://tester/env/empty.html');
                this.$.runner.title = Path.basename(this.$.runner.src);
            }
        }
    },

    _end: function () {
        this.resetRunner();
        if ( this.$.runner ) {
            this.$.runner.src = Editor.url('packages://tester/env/empty.html');
        }
    },

    _proxyIpc: function () {
        var args = [].slice.call(arguments, 0);
        this.$.runner.send.apply(this.$.runner,args);
    },

    _onReload: function ( event ) {
        this.reload();
    },

    _onRunnerConsole: function ( event ) {
        switch ( event.level ) {
        case 0:
            console.log('[runner-console]: ', event.message);
            break;

        case 1:
            console.warn('[runner-console]: ', event.message);
            break;

        case 2:
            console.error('[runner-console]: ', event.message);
            break;
        }
    },

    _onRunnerIpc: function ( event ) {
        var stats, suite, test, err, errText, el, url;

        switch ( event.channel ) {
        case 'tester:send':
            // NOTE: this will prevent us send back ipc message
            //       in ipc callstack which will make ipc event in reverse order
            setImmediate( function () {
                this._proxyIpc.apply(this,event.args);
            }.bind(this));

            break;

        case 'runner:start': this._onRunnerStart(); break;
        case 'runner:end': this._onRunnerEnd(); break;
        case 'runner:suite': this._onRunnerSuite( event.args[0] ); break;
        case 'runner:suite-end': this._onRunnerSuiteEnd( event.args[0] ); break;
        case 'runner:test': break;
        case 'runner:test-end': this._onRunnerTestEnd( event.args[0],  event.args[1] ); break;
        case 'runner:pending': break;
        case 'runner:pass': break;
        case 'runner:fail': this._onRunnerFail( event.args[0],  event.args[1] ); break;
        }
    },

    _onRunnerStart: function () {
        // runner
        var el = _fragment('

%s

', this.$.runner.title);

        // container
        Polymer.dom(this.stack[0]).appendChild(el);
        this.stack.unshift(document.createElement('ul'));
        Polymer.dom(el).appendChild(this.stack[0]);
        this._scrollToEnd();
    },

    _onRunnerEnd: function () {
        // console.log('%s runner finish', Url.basename(this.$.runner.src));
        this.stack.shift();
        this.next();
    },

    _onRunnerSuite: function ( suite ) {
        if ( suite.root )
            return;

        // suite
        var el = _fragment('

%s

', _escape(suite.title));

        // container
        Polymer.dom(this.stack[0]).appendChild(el);
        this.stack.unshift(document.createElement('ul'));
        Polymer.dom(el).appendChild(this.stack[0]);
        this._scrollToEnd();
    },

    _onRunnerSuiteEnd: function ( suite ) {
        if ( suite.root )
            return;

        this.stack.shift();
    },

    _onRunnerTestEnd: function ( stats, test ) {
        this.passes = this.lastPasses + stats.passes;
        this.failures = this.lastFailures + stats.failures;
        this.duration = this.lastDuration + stats.duration / 1000;
        this.progress = this.lastProgress + stats.progress/this._tests.length;

        // test
        var el;
        if ( test.state === 'passed' ) {
            el = _createPassEL(test);
        } else if (test.pending) {
            el = _createPendingEL(test);
        } else {
            el = _createFailEL(test, test.err);
        }

        // toggle code
        // TODO: defer
        if (!test.pending) {
            var h2 = el.getElementsByTagName('h2')[0];

            h2.addEventListener( 'click', function () {
                pre.style.display = 'none' == pre.style.display ? 'block' : 'none';
            });

            var pre = _fragment('
%e
', _clean(test.fn));
            Polymer.dom(el).appendChild(pre);
            pre.style.display = 'none';
        }

        // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
        if (this.stack[0]) {
            Polymer.dom(this.stack[0]).appendChild(el);
            this._scrollToEnd();
        }
    },

    _onRunnerFail: function ( test, err ) {
        if ( test.type === 'hook' ) {
            var el = _createFailEL(test, err);

            // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
            if (this.stack[0]) {
                Polymer.dom(this.stack[0]).appendChild(el);
                this._scrollToEnd();
            }
        }
    },

    _toFixed: function ( number, p ) {
        return number.toFixed(p);
    },

    _scrollToEnd: function () {
        if ( this._scrollTaskID )
            return;

        // to make sure after layout and before render
        this._scrollTaskID = window.requestAnimationFrame ( function () {
            this._scrollTaskID = null;
            var scrollView = this.$['mocha-report-view'];
            scrollView.scrollTop = scrollView.scrollHeight;
        }.bind(this) );
    },

    // ipc
    'editor:dragstart': function () {
        this.$.dragMask.hidden = false;
    },

    'editor:dragend': function () {
        this.$.dragMask.hidden = true;
    },

    'tester:runner-start': function () {
        this._onRunnerStart.apply( this, arguments );
    },

    'tester:runner-end': function () {
        this._onRunnerEnd.apply( this, arguments );
    },

    'tester:runner-suite': function () {
        this._onRunnerSuite.apply( this, arguments );
    },

    'tester:runner-suite-end': function () {
        this._onRunnerSuiteEnd.apply( this, arguments );
    },

    'tester:runner-test': function () {
    },

    'tester:runner-pending': function () {
    },

    'tester:runner-pass': function () {
    },

    'tester:runner-fail': function () {
        this._onRunnerFail.apply( this, arguments );
    },

    'tester:runner-test-end': function () {
        this._onRunnerTestEnd.apply( this, arguments );
    },
});

})();
<commit_msg>queue ipc messages from panel to webview<commit_after>(function () {
var Url = require('fire-url');
var Fs = require('fire-fs');
var Path = require('fire-path');

function _escape(html) {
  return String(html)
    .replace(/&/g, '&')
    .replace(/"/g, '"')
    .replace(/</g, '<')
    .replace(/>/g, '>');
}

function _clean(str) {
  str = str
    .replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, '')
    .replace(/^function *\(.*\)\s*{|\(.*\) *=> *{?/, '')
    .replace(/\s+\}$/, '');

  var spaces = str.match(/^\n?( *)/)[1].length,
      tabs = str.match(/^\n?(\t*)/)[1].length,
      re = new RegExp('^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');

  str = str.replace(re, '');

  // trim
  return str.replace(/^\s+|\s+$/g, '');
}

function _fragment(html) {
    var args = arguments,
        div = document.createElement('div'),
        i = 1;

    div.innerHTML = html.replace(/%([se])/g, function(_, type){
        switch (type) {
            case 's': return String(args[i++]);
            case 'e': return _escape(args[i++]);
        }
    });

    return div.firstChild;
}

function _makeUrl(s) {
    var search = window.location.search;

    // Remove previous grep query parameter if present
    if (search) {
        search = search.replace(/[?&]grep=[^&\s]*/g, '').replace(/^&/, '?');
    }

    return window.location.pathname + (search ? search + '&' : '?' ) + 'grep=' + encodeURIComponent(s);
}

function _createPassEL ( test ) {
    return _fragment('

%e%ems

',
                     test.speed, test.title, test.duration);
}

function _createPendingEL ( test ) {
    return _fragment('

%e

', test.title);
}

function _createFailEL ( test, err ) {
    var el = _fragment('

%e

', test.title, _makeUrl(test.fullTitle));
    var errText = err.stack;

    // FF / Opera do not add the message
    if ( !~errText.indexOf(err.message) ) {
        errText = err.message + '\n' + errText;
    }

    // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
    // check for the result of the stringifying.
    if ('[object Error]' === errText) errText = err.message;

    Polymer.dom(el).appendChild(_fragment('
%e
', errText));
    return el;
}

//
Editor.registerPanel( 'tester.panel', {
    is: 'editor-tester',

    properties: {
    },

    ready: function () {
        this._ipcList = [];

        this.reset();
    },

    'panel:open': function ( argv ) {
        if ( !argv || !argv.name ) {
            this._tests = ['packages://tester/env/empty.html'];
            this.reset();
            this.next();
            return;
        }

        this.runTests(argv.name);
    },

    'tester:run-tests': function ( pkgName ) {
        Editor.Panel.focus('tester.panel');
        this.runTests(pkgName);
    },

    reset: function () {
        this.passes = 0;
        this.failures = 0;
        this.duration = 0;
        this.progress = 0;

        this.lastPasses = 0;
        this.lastFailures = 0;
        this.lastDuration = 0;
        this.lastProgress = 0;

        this.curTestIdx = -1;

        var mochaReportEL = this.$['mocha-report'];
        while ( mochaReportEL.children.length ) {
            mochaReportEL.firstChild.remove();
        }
        this.stack = [mochaReportEL];

        if ( !this._tests || this._tests.length === 0 ) {
            this._tests = ['packages://tester/env/empty.html'];
        }
    },

    next: function () {
        this.lastPasses = this.passes;
        this.lastFailures = this.failures;
        this.lastDuration = this.duration;
        this.lastProgress = this.progress;

        this.curTestIdx += 1;
        if ( this.curTestIdx < this._tests.length ) {
            this._run(this._tests[this.curTestIdx]);
        }
        else {
            this._end();
        }
    },

    resetRunner: function () {
        // NOTE: The reason I don't use this.$.runner.src directly is because it will not stop
        //       the current running tests, even if I call runner.stop(). So destroy the webview is
        //       and recreate it is better than give him a source.
        if ( this.$.runner ) {
            Polymer.dom(this.$.webviewWrapper).removeChild(this.$.runner);
            this.$.runner = null;
        }

        var webview = document.createElement('webview');
        webview.setAttribute( 'id', 'runner' );
        // webview.setAttribute( 'src', Editor.url(url) );
        webview.setAttribute( 'nodeintegration', '' );
        webview.setAttribute( 'disablewebsecurity', '' );
        webview.setAttribute( 'autosize', 'on' );
        webview.setAttribute( 'maxheight', '200' );
        webview.addEventListener( 'console-message', this._onRunnerConsole.bind(this) );
        webview.addEventListener( 'ipc-message', this._onRunnerIpc.bind(this) );
        webview.addEventListener( 'crashed', function ( event ) {
            console.error( 'webview crashed!' );
        });
        webview.addEventListener( 'gpu-crashed', function ( event ) {
            console.error( 'webview gpu-crashed!' );
        });
        webview.addEventListener( 'plugin-crashed', function ( event ) {
            console.error( 'webview plugin-crashed!' );
        });
        this.$.runner = webview;

        Polymer.dom(this.$.webviewWrapper).appendChild(this.$.runner);
    },

    runTests: function ( pkgName ) {
        //
        Editor.Package.queryInfo( pkgName, function ( result ) {
            var pkgInfo = result.info;
            var tests = pkgInfo.tests || [];
            this._tests = tests.map( function ( path ) {
                if ( pkgInfo.build )
                    return Url.join( 'packages://', pkgInfo.name, 'bin', 'dev', path );

                return Url.join( 'packages://', pkgInfo.name, path );
            });
            this.reset();
            this.next();

        }.bind(this));
    },

    reload: function () {
        this.reset();
        this.next();
    },

    _run: function ( url ) {
        this.resetRunner();
        if ( this.$.runner ) {
            var src = Editor.url(url);
            if ( Fs.existsSync(src) ) {
                var extname = Path.extname(src);
                if ( extname === '.html' ) {
                    this.$.runner.src = src;
                }
                else if ( extname === '.js') {
                    this.$.runner.src = Editor.url('packages://tester/env/env-core.html');
                    Editor.sendToCore( 'tester:run-test', src );
                }
                this.$.runner.title = Path.basename(src);
            } else {
                this.$.runner.src = Editor.url('packages://tester/env/empty.html');
                this.$.runner.title = Path.basename(this.$.runner.src);
            }
        }
    },

    _end: function () {
        this.resetRunner();
        if ( this.$.runner ) {
            this.$.runner.src = Editor.url('packages://tester/env/empty.html');
        }
    },

    _sendToView: function () {
        var args = [].slice.call(arguments, 0);
        this.$.runner.send.apply(this.$.runner,args);
    },

    _onReload: function ( event ) {
        this.reload();
    },

    _onRunnerConsole: function ( event ) {
        switch ( event.level ) {
        case 0:
            console.log('[runner-console]: ', event.message);
            break;

        case 1:
            console.warn('[runner-console]: ', event.message);
            break;

        case 2:
            console.error('[runner-console]: ', event.message);
            break;
        }
    },

    _onRunnerIpc: function ( event ) {
        var stats, suite, test, err, errText, el, url;

        switch ( event.channel ) {
        case 'tester:send':
            // NOTE: this will prevent us send back ipc message
            //       in ipc callstack which will make ipc event in reverse order
            if ( !this._timeoutID ) {
                this._timeoutID = setTimeout( function () {
                    for ( var i = 0; i < this._ipcList.length; ++i ) {
                        this._sendToView.apply( this, this._ipcList[i] );
                    }
                    this._ipcList = [];
                    this._timeoutID = null;
                }.bind(this),1);
            }
            this._ipcList.push( event.args );
            break;

        case 'runner:start': this._onRunnerStart(); break;
        case 'runner:end': this._onRunnerEnd(); break;
        case 'runner:suite': this._onRunnerSuite( event.args[0] ); break;
        case 'runner:suite-end': this._onRunnerSuiteEnd( event.args[0] ); break;
        case 'runner:test': break;
        case 'runner:test-end': this._onRunnerTestEnd( event.args[0],  event.args[1] ); break;
        case 'runner:pending': break;
        case 'runner:pass': break;
        case 'runner:fail': this._onRunnerFail( event.args[0],  event.args[1] ); break;
        }
    },

    _onRunnerStart: function () {
        // runner
        var el = _fragment('

%s

', this.$.runner.title);

        // container
        Polymer.dom(this.stack[0]).appendChild(el);
        this.stack.unshift(document.createElement('ul'));
        Polymer.dom(el).appendChild(this.stack[0]);
        this._scrollToEnd();
    },

    _onRunnerEnd: function () {
        // console.log('%s runner finish', Url.basename(this.$.runner.src));
        this.stack.shift();
        this.next();
    },

    _onRunnerSuite: function ( suite ) {
        if ( suite.root )
            return;

        // suite
        var el = _fragment('

%s

', _escape(suite.title));

        // container
        Polymer.dom(this.stack[0]).appendChild(el);
        this.stack.unshift(document.createElement('ul'));
        Polymer.dom(el).appendChild(this.stack[0]);
        this._scrollToEnd();
    },

    _onRunnerSuiteEnd: function ( suite ) {
        if ( suite.root )
            return;

        this.stack.shift();
    },

    _onRunnerTestEnd: function ( stats, test ) {
        this.passes = this.lastPasses + stats.passes;
        this.failures = this.lastFailures + stats.failures;
        this.duration = this.lastDuration + stats.duration / 1000;
        this.progress = this.lastProgress + stats.progress/this._tests.length;

        // test
        var el;
        if ( test.state === 'passed' ) {
            el = _createPassEL(test);
        } else if (test.pending) {
            el = _createPendingEL(test);
        } else {
            el = _createFailEL(test, test.err);
        }

        // toggle code
        // TODO: defer
        if (!test.pending) {
            var h2 = el.getElementsByTagName('h2')[0];

            h2.addEventListener( 'click', function () {
                pre.style.display = 'none' == pre.style.display ? 'block' : 'none';
            });

            var pre = _fragment('
%e
', _clean(test.fn));
            Polymer.dom(el).appendChild(pre);
            pre.style.display = 'none';
        }

        // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
        if (this.stack[0]) {
            Polymer.dom(this.stack[0]).appendChild(el);
            this._scrollToEnd();
        }
    },

    _onRunnerFail: function ( test, err ) {
        if ( test.type === 'hook' ) {
            var el = _createFailEL(test, err);

            // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
            if (this.stack[0]) {
                Polymer.dom(this.stack[0]).appendChild(el);
                this._scrollToEnd();
            }
        }
    },

    _toFixed: function ( number, p ) {
        return number.toFixed(p);
    },

    _scrollToEnd: function () {
        if ( this._scrollTaskID )
            return;

        // to make sure after layout and before render
        this._scrollTaskID = window.requestAnimationFrame ( function () {
            this._scrollTaskID = null;
            var scrollView = this.$['mocha-report-view'];
            scrollView.scrollTop = scrollView.scrollHeight;
        }.bind(this) );
    },

    // ipc
    'editor:dragstart': function () {
        this.$.dragMask.hidden = false;
    },

    'editor:dragend': function () {
        this.$.dragMask.hidden = true;
    },

    'tester:runner-start': function () {
        this._onRunnerStart.apply( this, arguments );
    },

    'tester:runner-end': function () {
        this._onRunnerEnd.apply( this, arguments );
    },

    'tester:runner-suite': function () {
        this._onRunnerSuite.apply( this, arguments );
    },

    'tester:runner-suite-end': function () {
        this._onRunnerSuiteEnd.apply( this, arguments );
    },

    'tester:runner-test': function () {
    },

    'tester:runner-pending': function () {
    },

    'tester:runner-pass': function () {
    },

    'tester:runner-fail': function () {
        this._onRunnerFail.apply( this, arguments );
    },

    'tester:runner-test-end': function () {
        this._onRunnerTestEnd.apply( this, arguments );
    },
});

})();
<|endoftext|>


<commit_before>/**
 * The main background script, containing listeners for communication, aggregating
 * the data and storing it.
 *
 * @author Bram Gotink (@bgotink)
 * @license MIT
 */

'use strict';

window.iidentity = window.iidentity || {};

(function (module, $, window) {
    var storage = chrome.storage.sync,
        data = null,
        storageCache = {},

        isOptionsPage = function (url) {
            return url.match(new RegExp('chrome-extension:\\/\\/' + chrome.runtime.id + '/options.html.*'));
        },

    // storage functions

        getStoredData = function (key, defaultValue, callback) {
            var request = {};
            request[key] = defaultValue;

            if (key in storageCache && storageCache[key].expires > (+new Date)) {
                module.log.log('Got storage { key: %s, value: %s } from storage cache', key, '' + storageCache[key].result);
                callback(storageCache[key].result);
            } else {
                storage.get(request, function (result) {
                    module.log.log('Got storage { key: %s, value: %s } from storage', key, '' + result[key]);

                    storageCache[key] = {
                        result: result[key],
                        expires: (+new Date()) + 60 * 1000
                    };

                    callback(result[key]);
                });
            }
        },

        setStoredData = function (key, value, callback) {
            var request = {};
            request[key] = value;

            module.log.log('Setting storage key %s to %s', key, '' + value);
            storage.set(request, callback);

            if (key in storageCache) {
                delete storageCache[key];
            }
        },

        getManifestKeys = function (callback) {
            module.log.log('Fetching manifest keys...');
            storage.get({ manifest_keys: [] }, function (result) {
                callback(result.manifest_keys);
            });
        },

        setManifestKeys = function (keys, callback) {
            module.log.log('Setting manifest keys...');
            storage.set({ manifest_keys: keys }, callback);
        },

        addManifestKey = function (key, callback) {
            getManifestKeys(function (keys) {
                if (keys.indexOf(key) !== -1) {
                    module.log.log('manifest key %s already loaded', key);
                    callback(false);
                    return;
                }

                module.log.log('adding manifest key %s', key);
                keys.push(key);

                setManifestKeys(keys, function () {
                    callback(true);
                });
            });
        },

        removeManifestKey = function (key, callback) {
            getManifestKeys(function (keys) {
                if (keys.indexOf(key) === -1) {
                    callback(false);
                    return;
                }

                keys.splice(
                    keys.indexOf(key),
                    1
                );

                setManifestKeys(keys, function () {
                    callback(true);
                });
            });
        },

    // data functions

        reloadData = function (callback) {
            getManifestKeys(function (storedData) {
                module.data.loadManifests(storedData, function (err, newData) {
                    if (newData !== null) {
                        data = newData;

                        updateTabs();
                        callback(err, true);
                    } else {
                        callback(err, false);
                    }
                });
            });
        },

    // communication functions

        updateTabs = function () {
            chrome.permissions.contains(
                { permissions: ['tabs'] },
                function (hasPermission) {
                    if (!hasPermission) {
                        return;
                    }

                    chrome.tabs.query({}, function(tabs) {
                        var i,
                            length = tabs.length,
                            message = { type: 'update' };
                        module.log.log('Sending update message to %d tabs', length);

                        for (i = 0; i < length; i++) {
                            module.log.log('-- tab ', tabs[i]);
                            chrome.tabs.sendMessage(tabs[i].id, message);
                        }
                    });
                }
            );
        },

    // communication listeners

        messageListeners = {};

    messageListeners.getManifests = function (request, sender, sendResponse) {
        if (!isOptionsPage(sender.url)) {
            module.log.error('A \'getManifests\' message can only originate from the options page');
            // silently die by not sending a response
            return false;
        }

        getManifestKeys(function (keys) {
            var result = {},
                manifest,
                manifestData;

            module.log.log('Loaded manifests: ', keys);

            keys.forEach(function (key) {
                manifest = data.getSource(key);
                manifestData = [];

                if (manifest === null) {
                    module.log.error('Strangely this manifest cannot be found');
                    return;
                }

                manifest.getSources().forEach(function (source) {
                    manifestData.push({
                        key:     source.getKey(),
                        tag:     source.getTag(),
                        count:   source.getNbPlayers(),
                        version: source.getVersion(),
                        faction: source.getFaction(),
                    });
                });

                module.log.log('Manifest %s contains the following data:', key);
                module.log.log(manifestData);

                result[key] = manifestData;
            });

            module.log.log('Sending result to getManifests: ', result);
            sendResponse(result);
        });

        return true;
    };

    messageListeners.addManifest = function (request, sender, sendResponse) {
        if (!isOptionsPage(sender.url)) {
            module.log.error('An \'addManifest\' message can only originate from the options page');
            // silently die by not sending a response
            return false;
        }

        addManifestKey(request.key, function (added) {
            if (!added) {
                sendResponse({ status: 'duplicate' });
                return;
            }

            reloadData(function (err, status) {
                sendResponse({ status: status ? 'success' : 'failed', err: err });
            });
        });

        return true;
    };

    messageListeners.removeManifest = function (request, sender, sendResponse) {
        if (!isOptionsPage(sender.url)) {
            module.log.error('A \'removeManifest\' message can only originate from the options page');
            // silently die by not sending a response
            return false;
        }

        removeManifestKey(request.key, function (removed) {
            if (!removed) {
                sendResponse({ status: 'nonexistent' });
                return;
            }

            reloadData(function (err, status) {
                sendResponse({ status: status ? 'success' : 'failed', err: err });
            });
        });

        return true;
    };

    messageListeners.reloadData = function (request, sender, sendResponse) {
        if (!isOptionsPage(sender.url)) {
            module.log.error('A \'reloadData\' message can only originate from the options page');
            // silently die by not sending a response
            return;
        }

        reloadData(function (err, status) {
            sendResponse({ status: status ? 'success' : 'failed', err: err });
        });

        return true;
    };

    messageListeners.requestPermission = function (request, sender, sendResponse) {
        if (!isOptionsPage(sender.url)) {
            module.log.error('A \'requestPermission\' message can only originate from the options page');
            // silently die by not sending a response
            return;
        }

        var permissions = { permissions: [ request.permission ]};
        module.log.log('Requesting premission %s', request.permission);

        chrome.permissions.contains(
            permissions,
            function (alreadyGranted) {
                if (alreadyGranted) {
                    sendResponse({ granted: true});
                    return;
                }

                chrome.permissions.request(
                    permissions,
                    function (granted) {
                        sendResponse({ granted: granted });
                    }
                );
            }
        );

        return true;
    };

    messageListeners.hasPermission = function (request, sender, sendResponse) {
        chrome.permissions.contains(
            { permissions: [ request.permission ]},
            function (granted) {
                sendResponse({ hasPermission: granted });
            }
        );

        return true;
    };

    messageListeners.revokePermission = function (request, sender, sendResponse) {
        if (!isOptionsPage(sender.url)) {
            module.log.error('A \'revokePermission\' message can only originate from the options page');
            // silently die by not sending a response
            return false;
        }

        var permissions = { permissions: [ request.permission ]};
        module.log.log('Revoking premission %s', request.permission);

        chrome.permissions.contains(
            permissions,
            function (granted) {
                if (!granted) {
                    sendResponse({ revoked: true});
                    return;
                }

                chrome.permissions.remove(
                    permissions,
                    function (revoked) {
                        sendResponse({ revoked: revoked });
                    }
                );
            }
        );

        return true;
    };

    messageListeners.setOption = function (request, sender, sendResponse) {
        if (!isOptionsPage(sender.url)) {
            module.log.error('A \'setOption\' message can only originate from the options page');
            // silently die by not sending a response
            return false;
        }

        setStoredData('option-' + request.option, request.value, function () {
            data.invalidateCache();
            updateTabs();
            sendResponse({ result: request.value });
        });

        return true;
    };

    messageListeners.getOption = function (request, sender, sendResponse) {
        getStoredData('option-' + request.option, request.default, function (result) {
            sendResponse({ value: result });
        });

        return true;
    }

    messageListeners.hasPlayer = function (request, sender, sendResponse) {
        if (data === null) {
            sendResponse({ result: false });
        } else {
            sendResponse({ result: data.hasPlayer(request.oid) });
        }

        return false;
    };

    messageListeners.getPlayer = function (request, sender, sendResponse) {
        if (data === null) {
            sendResponse({ status: 'not-found' });
        } else {
            var doGetPlayer = function () {
                var player = data.getPlayer(request.oid);

                if (player === null) {
                    sendResponse({ status: 'not-found' });

                    return false;
                }

                if ('anomaly' in player.extra) {
                    getStoredData('option-show-anomalies', true, function (showAnomalies) {
                        if (!showAnomalies) {
                            delete player.extra.anomaly;
                        }

                        sendResponse({ status: 'success', player: player });
                    });

                    return true;
                }

                sendResponse({ status: 'success', player: player });
            };

            if (!('extra' in request) || !('match' in request.extra)) {
                return doGetPlayer();
            }

            getStoredData(
                'option-match-' + request.extra.match,
                true,
                function (doMatch) {
                    if (!doMatch) {
                        sendResponse({ status: 'not-found' });
                        return;
                    }

                    doGetPlayer();
                }
            );

            return true;
        }

        return false;
    };

    chrome.runtime.onMessage.addListener(
        function (request, sender, sendResponse) {
            if (sender.tab) {
                module.log.log('Got request from tab %s, url: %s', sender.tab.id, sender.url);
            } else {
                module.log.error('Got request from this backgroundpage?');
                // silently ignore
                return;
            }

            var reply = null;

            if (request.lastUpdate) {
                reply = { shouldUpdate: data === null ? false : data.shouldUpdateRemote(request.lastUpdate) };

                request = request.request;
            }

            if (request.type in messageListeners) {
                return messageListeners[request.type](request, sender, function (response) {
                    if (reply !== null) {
                        reply.reply = response;
                    } else {
                        reply = response;
                    }

                    sendResponse(reply);
                });
            } else {
                module.log.error('Unknown message type: %s', request.type);
                module.log.error('Request: ', request);
                module.log.error('Sender: ', sender);

                return false;
            }
        }
    );

    $(function () {
        google.load("visualization", "1", { callback: function () {
            reloadData(function(err, success) {
                if (success) {
                    module.log.log('Successfully loaded existing configuration');
                    if (err) {
                        err.forEach(function (e) { module.log.warn(e); });
                    }
                } else {
                    module.log.error('Something went wrong while loading existing configuration');
                    err.forEach(function (e) { module.log.error(e); });
                }
            });

            window.setInterval(function () {
                if (data === null)
                    return;

                module.log.log('Performing hourly update...');
                data.update(function (updated) {
                    if (updated) {
                        data.invalidateCache();
                        updateTabs();
                    }
                })
            }, 60 * 60 * 1000);
        }});
    });
})(window.iidentity, window.jQuery, window);
<commit_msg>[backend] listen to chrome updating storage<commit_after>/**
 * The main background script, containing listeners for communication, aggregating
 * the data and storing it.
 *
 * @author Bram Gotink (@bgotink)
 * @license MIT
 */

'use strict';

window.iidentity = window.iidentity || {};

(function (module, $, window) {
    var storage = chrome.storage.sync,
        data = null,
        storageCache = {},

        isOptionsPage = function (url) {
            return url.match(new RegExp('chrome-extension:\\/\\/' + chrome.runtime.id + '/options.html.*'));
        },

    // storage functions

        disableUpdateListener = false,
        onDataUpdated = function (changes, areaName) {
            var update = false,
                reload = false,
                key;

            if (disableUpdateListener) {
                module.log.log('Chrome storage update listener disabled, re-enabling');
                disableUpdateListener = false;
                return;
            }

            module.log.log('Settings updated:');
            for (key in changes) {
                if (key in storageCache) {
                    delete storageCache[key];
                }

                module.log.log('- %s', key);

                if (key === 'manifest_keys') {
                    reload = true;
                } else {
                    update = true;
                }
            }

            if (reload) {
                module.log.log('Reloading manifests');
                reloadData(function (err, reloaded) {
                    if (reloaded) {
                        module.log.log('Manifests reloaded');

                        if (err) {
                            err.forEach(module.log.warn);
                        }
                    } else {
                        module.log.error('Error when reloading manifest:');
                        err.forEach(module.log.error);
                    }
                });
            } else if (update) {
                module.log.log('Updating tabs');
                updateTabs();
            }
        },

        getStoredData = function (key, defaultValue, callback) {
            var request = {};
            request[key] = defaultValue;

            if (key in storageCache && storageCache[key].expires > (+new Date)) {
                module.log.log('Got storage { key: %s, value: %s } from storage cache', key, '' + storageCache[key].result);
                callback(storageCache[key].result);
            } else {
                storage.get(request, function (result) {
                    module.log.log('Got storage { key: %s, value: %s } from storage', key, '' + result[key]);

                    storageCache[key] = {
                        result: result[key],
                        expires: (+new Date()) + 60 * 1000
                    };

                    callback(result[key]);
                });
            }
        },

        setStoredData = function (key, value, callback) {
            var request = {};
            request[key] = value;

            module.log.log('Setting storage key %s to %s', key, '' + value);
            storage.set(request, callback);
        },

        getManifestKeys = function (callback) {
            module.log.log('Fetching manifest keys...');
            storage.get({ manifest_keys: [] }, function (result) {
                callback(result.manifest_keys);
            });
        },

        setManifestKeys = function (keys, callback) {
            module.log.log('Setting manifest keys...');
            storage.set({ manifest_keys: keys }, callback);
        },

        addManifestKey = function (key, callback) {
            getManifestKeys(function (keys) {
                if (keys.indexOf(key) !== -1) {
                    module.log.log('manifest key %s already loaded', key);
                    callback(false);
                    return;
                }

                module.log.log('adding manifest key %s', key);
                keys.push(key);

                setManifestKeys(keys, function () {
                    callback(true);
                });
            });
        },

        removeManifestKey = function (key, callback) {
            getManifestKeys(function (keys) {
                if (keys.indexOf(key) === -1) {
                    callback(false);
                    return;
                }

                keys.splice(
                    keys.indexOf(key),
                    1
                );

                setManifestKeys(keys, function () {
                    callback(true);
                });
            });
        },

    // data functions

        reloadData = function (callback) {
            getManifestKeys(function (storedData) {
                module.data.loadManifests(storedData, function (err, newData) {
                    if (newData !== null) {
                        data = newData;

                        updateTabs();
                        callback(err, true);
                    } else {
                        callback(err, false);
                    }
                });
            });
        },

    // communication functions

        updateTabs = function () {
            chrome.permissions.contains(
                { permissions: ['tabs'] },
                function (hasPermission) {
                    if (!hasPermission) {
                        return;
                    }

                    chrome.tabs.query({}, function(tabs) {
                        var i,
                            length = tabs.length,
                            message = { type: 'update' };
                        module.log.log('Sending update message to %d tabs', length);

                        for (i = 0; i < length; i++) {
                            module.log.log('-- tab ', tabs[i]);
                            chrome.tabs.sendMessage(tabs[i].id, message);
                        }
                    });
                }
            );
        },

    // communication listeners

        messageListeners = {};

    messageListeners.getManifests = function (request, sender, sendResponse) {
        if (!isOptionsPage(sender.url)) {
            module.log.error('A \'getManifests\' message can only originate from the options page');
            // silently die by not sending a response
            return false;
        }

        getManifestKeys(function (keys) {
            var result = {},
                manifest,
                manifestData;

            module.log.log('Loaded manifests: ', keys);

            keys.forEach(function (key) {
                manifest = data.getSource(key);
                manifestData = [];

                if (manifest === null) {
                    module.log.error('Strangely this manifest cannot be found');
                    return;
                }

                manifest.getSources().forEach(function (source) {
                    manifestData.push({
                        key:     source.getKey(),
                        tag:     source.getTag(),
                        count:   source.getNbPlayers(),
                        version: source.getVersion(),
                        faction: source.getFaction(),
                    });
                });

                module.log.log('Manifest %s contains the following data:', key);
                module.log.log(manifestData);

                result[key] = manifestData;
            });

            module.log.log('Sending result to getManifests: ', result);
            sendResponse(result);
        });

        return true;
    };

    messageListeners.addManifest = function (request, sender, sendResponse) {
        if (!isOptionsPage(sender.url)) {
            module.log.error('An \'addManifest\' message can only originate from the options page');
            // silently die by not sending a response
            return false;
        }

        disableUpdateListener = true;
        addManifestKey(request.key, function (added) {
            if (!added) {
                disableUpdateListener = false;
                sendResponse({ status: 'duplicate' });
                return;
            }

            reloadData(function (err, status) {
                disableUpdateListener = false;
                sendResponse({ status: status ? 'success' : 'failed', err: err });
            });
        });

        return true;
    };

    messageListeners.removeManifest = function (request, sender, sendResponse) {
        if (!isOptionsPage(sender.url)) {
            module.log.error('A \'removeManifest\' message can only originate from the options page');
            // silently die by not sending a response
            return false;
        }

        disableUpdateListener = true;
        removeManifestKey(request.key, function (removed) {
            if (!removed) {
                disableUpdateListener = false;
                sendResponse({ status: 'nonexistent' });
                return;
            }

            reloadData(function (err, status) {
                disableUpdateListener = false;
                sendResponse({ status: status ? 'success' : 'failed', err: err });
            });
        });

        return true;
    };

    messageListeners.reloadData = function (request, sender, sendResponse) {
        if (!isOptionsPage(sender.url)) {
            module.log.error('A \'reloadData\' message can only originate from the options page');
            // silently die by not sending a response
            return;
        }

        reloadData(function (err, status) {
            sendResponse({ status: status ? 'success' : 'failed', err: err });
        });

        return true;
    };

    messageListeners.requestPermission = function (request, sender, sendResponse) {
        if (!isOptionsPage(sender.url)) {
            module.log.error('A \'requestPermission\' message can only originate from the options page');
            // silently die by not sending a response
            return;
        }

        var permissions = { permissions: [ request.permission ]};
        module.log.log('Requesting premission %s', request.permission);

        chrome.permissions.contains(
            permissions,
            function (alreadyGranted) {
                if (alreadyGranted) {
                    sendResponse({ granted: true});
                    return;
                }

                chrome.permissions.request(
                    permissions,
                    function (granted) {
                        sendResponse({ granted: granted });
                    }
                );
            }
        );

        return true;
    };

    messageListeners.hasPermission = function (request, sender, sendResponse) {
        chrome.permissions.contains(
            { permissions: [ request.permission ]},
            function (granted) {
                sendResponse({ hasPermission: granted });
            }
        );

        return true;
    };

    messageListeners.revokePermission = function (request, sender, sendResponse) {
        if (!isOptionsPage(sender.url)) {
            module.log.error('A \'revokePermission\' message can only originate from the options page');
            // silently die by not sending a response
            return false;
        }

        var permissions = { permissions: [ request.permission ]};
        module.log.log('Revoking premission %s', request.permission);

        chrome.permissions.contains(
            permissions,
            function (granted) {
                if (!granted) {
                    sendResponse({ revoked: true});
                    return;
                }

                chrome.permissions.remove(
                    permissions,
                    function (revoked) {
                        sendResponse({ revoked: revoked });
                    }
                );
            }
        );

        return true;
    };

    messageListeners.setOption = function (request, sender, sendResponse) {
        if (!isOptionsPage(sender.url)) {
            module.log.error('A \'setOption\' message can only originate from the options page');
            // silently die by not sending a response
            return false;
        }

        setStoredData('option-' + request.option, request.value, function () {
            data.invalidateCache();
            updateTabs();
            sendResponse({ result: request.value });
        });

        return true;
    };

    messageListeners.getOption = function (request, sender, sendResponse) {
        getStoredData('option-' + request.option, request.default, function (result) {
            sendResponse({ value: result });
        });

        return true;
    }

    messageListeners.hasPlayer = function (request, sender, sendResponse) {
        if (data === null) {
            sendResponse({ result: false });
        } else {
            sendResponse({ result: data.hasPlayer(request.oid) });
        }

        return false;
    };

    messageListeners.getPlayer = function (request, sender, sendResponse) {
        if (data === null) {
            sendResponse({ status: 'not-found' });
        } else {
            var doGetPlayer = function () {
                var player = data.getPlayer(request.oid);

                if (player === null) {
                    sendResponse({ status: 'not-found' });

                    return false;
                }

                if ('anomaly' in player.extra) {
                    getStoredData('option-show-anomalies', true, function (showAnomalies) {
                        if (!showAnomalies) {
                            delete player.extra.anomaly;
                        }

                        sendResponse({ status: 'success', player: player });
                    });

                    return true;
                }

                sendResponse({ status: 'success', player: player });
            };

            if (!('extra' in request) || !('match' in request.extra)) {
                return doGetPlayer();
            }

            getStoredData(
                'option-match-' + request.extra.match,
                true,
                function (doMatch) {
                    if (!doMatch) {
                        sendResponse({ status: 'not-found' });
                        return;
                    }

                    doGetPlayer();
                }
            );

            return true;
        }

        return false;
    };

    chrome.runtime.onMessage.addListener(
        function (request, sender, sendResponse) {
            if (sender.tab) {
                module.log.log('Got request from tab %s, url: %s', sender.tab.id, sender.url);
            } else {
                module.log.error('Got request from this backgroundpage?');
                // silently ignore
                return;
            }

            var reply = null;

            if (request.lastUpdate) {
                reply = { shouldUpdate: data === null ? false : data.shouldUpdateRemote(request.lastUpdate) };

                request = request.request;
            }

            if (request.type in messageListeners) {
                return messageListeners[request.type](request, sender, function (response) {
                    if (reply !== null) {
                        reply.reply = response;
                    } else {
                        reply = response;
                    }

                    sendResponse(reply);
                });
            } else {
                module.log.error('Unknown message type: %s', request.type);
                module.log.error('Request: ', request);
                module.log.error('Sender: ', sender);

                return false;
            }
        }
    );

    $(function () {
        google.load("visualization", "1", { callback: function () {
            reloadData(function(err, success) {
                if (success) {
                    module.log.log('Successfully loaded existing configuration');
                    if (err) {
                        err.forEach(function (e) { module.log.warn(e); });
                    }
                } else {
                    module.log.error('Something went wrong while loading existing configuration');
                    err.forEach(function (e) { module.log.error(e); });
                }
            });

            window.setInterval(function () {
                if (data === null)
                    return;

                module.log.log('Performing hourly update...');
                data.update(function (updated) {
                    if (updated) {
                        data.invalidateCache();
                        updateTabs();
                    }
                })
            }, 60 * 60 * 1000);
        }});

        chrome.storage.onChanged.addListener(onDataUpdated);
    });
})(window.iidentity, window.jQuery, window);
<|endoftext|>


<commit_before>var assert = require("assert");
var Engine2D = require("../src/engine2d");
var Engine2DM = require("../prod/engine2d.min");

describe("Engine2D", function() {
    describe("#GameScene()", function() {
        it("should be object", function() {
            assert.equal(typeof new Engine2D.GameScene(), "object");
        });
        it("should have an array of objects named `objects`", function() {
            assert.equal(typeof new Engine2D.GameScene().objects, "object");
        });
        it("should not have a public function named `isValidID`", function() {
            assert.equal(typeof new Engine2D.GameScene().isValidID, "undefined");
        });
    });
    describe("#Vector2()", function() {
        it("should have accessible coordinates", function() {
            assert.equal(new Engine2D.Vector2(10, 20).getX(), 10);
            assert.equal(new Engine2D.Vector2(10, 20).getY(), 20);
        });
        it("should have settable coordinates", function() {
            var pos = new Engine2D.Vector2(0, 0);
            pos.setPos(new Engine2D.Vector2(5, 10));
            assert.equal(pos.getX(), 5);
            assert.equal(pos.getY(), 10);
            pos.setX(3);
            pos.setY(4);
            assert.equal(pos.getX(), 3);
            assert.equal(pos.getY(), 4);
        });
    });
    describe("#Rect()", function() {
        it("should be object", function() {
            assert.equal(typeof new Engine2D.Rect(), "object");
        });
    });
    describe("#Circle()", function() {
        it("should be object", function() {
            assert.equal(typeof new Engine2D.Circle(), "object");
        });
    });
    describe("#nextAvailableTypeAddress()", function() {
        var size = 0;
        for (var i in Engine2D.TYPE) {
            if (Engine2D.TYPE.hasOwnProperty(i)) {
                size++;
            }
        }
        it("should be one greater than length of type object (" + size + ")", function() {
            assert.equal(Engine2D.nextAvailableTypeAddress(), size + 1);
        });
    });
    describe("#registerExtension", function() {
        it("should exist", function() {
            assert.equal(typeof Engine2D.registerExtension, "function");
        });
        it("should add a new extension", function() {
            var ext = Engine2D.registerExtension({
                extensionName: "Example Extension",
                version: "0.0.0",
                exec: function() {}
            });
            assert.equal(typeof Engine2D.EXTENSIONS[ext], "object");
        });
    });
});
describe("Engine2D minified", function() {
    describe("#GameScene()", function() {
        it("should be object", function() {
            assert.equal(typeof new Engine2DM.GameScene(), "object");
        });
        it("should have an array of objects named `objects`", function() {
            assert.equal(typeof new Engine2DM.GameScene().objects, "object");
        });
        it("should not have a public function named `isValidID`", function() {
            assert.equal(typeof new Engine2DM.GameScene().isValidID, "undefined");
        });
    });
    describe("#Vector2()", function() {
        it("should have accessible coordinates", function() {
            assert.equal(new Engine2DM.Vector2(10, 20).getX(), 10);
            assert.equal(new Engine2DM.Vector2(10, 20).getY(), 20);
        });
        it("should have settable coordinates", function() {
            var pos = new Engine2DM.Vector2(0, 0);
            pos.setPos(new Engine2DM.Vector2(5, 10));
            assert.equal(pos.getX(), 5);
            assert.equal(pos.getY(), 10);
            pos.setX(3);
            pos.setY(4);
            assert.equal(pos.getX(), 3);
            assert.equal(pos.getY(), 4);
        });
    });
    describe("#Rect()", function() {
        it("should be object", function() {
            assert.equal(typeof new Engine2DM.Rect(), "object");
        });
    });
    describe("#Circle()", function() {
        it("should be object", function() {
            assert.equal(typeof new Engine2DM.Circle(), "object");
        });
    });
    describe("#nextAvailableTypeAddress()", function() {
        var size = 0;
        for (var i in Engine2DM.TYPE) {
            if (Engine2DM.TYPE.hasOwnProperty(i)) {
                size++;
            }
        }
        it("should be one greater than length of type object (" + size + ")", function() {
            assert.equal(Engine2DM.nextAvailableTypeAddress(), size + 1);
        });
    });
    describe("#registerExtension", function() {
        it("should exist", function() {
            assert.equal(typeof Engine2DM.registerExtension, "function");
        });
        it("should add a new extension", function() {
            var ext = Engine2DM.registerExtension({
                extensionName: "Example Extension",
                version: "0.0.0",
                exec: function() {}
            });
            assert.equal(typeof Engine2DM.EXTENSIONS[ext], "object");
        });
    });
});<commit_msg>Update tests<commit_after>var assert = require("assert");
var Engine2D = require("../src/engine2d");
var Engine2DM = require("../prod/engine2d.min");

describe("Engine2D", function() {
    describe("#GameScene()", function() {
        it("should be object", function() {
            assert.equal(typeof new Engine2D.GameScene(), "object");
        });
        it("should have an array of objects named `objects`", function() {
            assert.equal(typeof new Engine2D.GameScene().objects, "object");
        });
        it("should not have a public function named `isValidID`", function() {
            assert.equal(typeof new Engine2D.GameScene().isValidID, "undefined");
        });
    });
    describe("#Vector2()", function() {
        it("should have accessible coordinates", function() {
            assert.equal(new Engine2D.Vector2(10, 20).getX(), 10);
            assert.equal(new Engine2D.Vector2(10, 20).getY(), 20);
        });
        it("should have settable coordinates", function() {
            var pos = new Engine2D.Vector2(0, 0);
            pos.setPosition(new Engine2D.Vector2(5, 10));
            assert.equal(pos.getX(), 5);
            assert.equal(pos.getY(), 10);
            pos.setX(3);
            pos.setY(4);
            assert.equal(pos.getX(), 3);
            assert.equal(pos.getY(), 4);
        });
    });
    describe("#Rect()", function() {
        it("should be object", function() {
            assert.equal(typeof new Engine2D.Rect(), "object");
        });
    });
    describe("#Circle()", function() {
        it("should be object", function() {
            assert.equal(typeof new Engine2D.Circle(), "object");
        });
    });
    describe("#nextAvailableTypeAddress()", function() {
        var size = 0;
        for (var i in Engine2D.TYPE) {
            if (Engine2D.TYPE.hasOwnProperty(i)) {
                size++;
            }
        }
        it("should be one greater than length of type object (" + size + ")", function() {
            assert.equal(Engine2D.nextAvailableTypeAddress(), size + 1);
        });
    });
    describe("#registerExtension", function() {
        it("should exist", function() {
            assert.equal(typeof Engine2D.registerExtension, "function");
        });
        it("should add a new extension", function() {
            var ext = Engine2D.registerExtension({
                extensionName: "Example Extension",
                version: "0.0.0",
                exec: function() {}
            });
            assert.equal(typeof Engine2D.EXTENSIONS[ext], "object");
        });
    });
});
describe("Engine2D minified", function() {
    describe("#GameScene()", function() {
        it("should be object", function() {
            assert.equal(typeof new Engine2DM.GameScene(), "object");
        });
        it("should have an array of objects named `objects`", function() {
            assert.equal(typeof new Engine2DM.GameScene().objects, "object");
        });
        it("should not have a public function named `isValidID`", function() {
            assert.equal(typeof new Engine2DM.GameScene().isValidID, "undefined");
        });
    });
    describe("#Vector2()", function() {
        it("should have accessible coordinates", function() {
            assert.equal(new Engine2DM.Vector2(10, 20).getX(), 10);
            assert.equal(new Engine2DM.Vector2(10, 20).getY(), 20);
        });
        it("should have settable coordinates", function() {
            var pos = new Engine2DM.Vector2(0, 0);
            pos.setPosition(new Engine2DM.Vector2(5, 10));
            assert.equal(pos.getX(), 5);
            assert.equal(pos.getY(), 10);
            pos.setX(3);
            pos.setY(4);
            assert.equal(pos.getX(), 3);
            assert.equal(pos.getY(), 4);
        });
    });
    describe("#Rect()", function() {
        it("should be object", function() {
            assert.equal(typeof new Engine2DM.Rect(), "object");
        });
    });
    describe("#Circle()", function() {
        it("should be object", function() {
            assert.equal(typeof new Engine2DM.Circle(), "object");
        });
    });
    describe("#nextAvailableTypeAddress()", function() {
        var size = 0;
        for (var i in Engine2DM.TYPE) {
            if (Engine2DM.TYPE.hasOwnProperty(i)) {
                size++;
            }
        }
        it("should be one greater than length of type object (" + size + ")", function() {
            assert.equal(Engine2DM.nextAvailableTypeAddress(), size + 1);
        });
    });
    describe("#registerExtension", function() {
        it("should exist", function() {
            assert.equal(typeof Engine2DM.registerExtension, "function");
        });
        it("should add a new extension", function() {
            var ext = Engine2DM.registerExtension({
                extensionName: "Example Extension",
                version: "0.0.0",
                exec: function() {}
            });
            assert.equal(typeof Engine2DM.EXTENSIONS[ext], "object");
        });
    });
});<|endoftext|>


<commit_before>/*!
 * Module dependencies.
 */

var archiver = require('archiver'),
    fs = require('fs'),
    path = require('path')
    findit = require('findit'),
    mkpath = require('mkpath'),
    ncp = require('ncp').ncp;

/**
 * Generates the zips of each of the Cordova versions and platforms
 *
 *
 * Arguments:
 *
 *
 * Return:
 *
 *
 * Example:
 *
 *
 */

module.exports = function(options, files){
    var cordovaPath = path.join(__dirname, '../res/middleware/cordova', version, platform);
    var zipPath = path.join(__dirname, '/../tmp', id);
    var wwwPath = path.join(zipPath, 'www');
    var resPath = path.join(__dirname, '../res/middleware');

    var autoreloadScript = path.join(__dirname, '../res/middleware/autoreload.js'),
        consoleScript = path.join(__dirname, '../res/middleware/consoler.js'),
        homepageScript = path.join(__dirname, '../res/middleware/homepage.js'),
        refreshScript = path.join(__dirname, '../res/middleware/refresh.js');

    var injectScript = function(){
        return fs.readFileSync(autoreloadScript) + fs.readFileSync(consoleScript) + fs.readFileSync(homepageScript) + fs.readFileSync(refreshScript)
    }

    // make our www
    if(!fs.existsSync(wwwPath)){
        mkpath.sync(wwwPath, '0700');
    }

}<commit_msg>[#86] Remove unused lib/autoreloadZip.js<commit_after><|endoftext|>


<commit_before>
/*
 * application JS library, UI independent code
 *
 */

/* these can be "overwritten" by the UI */
var busyImage = '';
var menuArrowImage = 'ui/dressprow/images/menuarrow.png';
var menuArrowActiveImagesrc = 'ui/dressprow/images/menuarrow_active.png';

function urlParameter( name, link) {
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( link );
  if( results == null )
    return "";
  else
    return results[1];
}

var updateMessages = new Array();
var updateLock = false;
function messagesStatusUpdate() {
  if (updateLock) return;
  updateLock = true;
  for (var i = 0; i < updateMessages.length; i++) {
    messageStatusUpdate(updateMessages[i]);
  }
  updateLock = false;
}

function messageStatusUpdate(msgid) {
   if (msgid) {
      $('#messagestatus'+msgid).load('./?page=pageaction&ajaxed=true&action=msgstatus&id='+msgid,"",function() {});
   }
}

function getServerTime() {
   $('#servertime').load('./?page=pageaction&ajaxed=true&action=getservertime',"",function() {
   });
   setTimeout("getServerTime()",60100); // just over a minute
}

function refreshCriteriaList() {
  var id = urlParameter('id',document.location);
  $("#existingCriteria").html(busyImage);
  $("#existingCriteria").load('./?page=pageaction&ajaxed=true&action=listcriteria&id='+id);
}

function refreshExport() {
 // alert('Refresh '+document.location);
  document.location = document.location;
}

function openHelpDialog(url) {
  $("#dialog").dialog({
    minHeight: 400,
    width: 600,
    modal: true
  });
  $("#dialog").html('
'+busyImage+'
');
  var destpage = urlParameter('page',url);
  url = url.replace(/page=/,'origpage=');
  $("#dialog").load(url+'&ajaxed=true&page=pageaction&action='+destpage);
  $(".ui-widget-overlay").click(function() {
    $("#dialog").dialog('close');
  });
}

function initialiseTranslation(text) {
  $("#dialog").dialog({
    minHeight: 400,
    width: 600,
    modal: true
  });
  $("#dialog").html('
'+text+'
'+busyImage+'
');
  $("#dialog").load('./?ajaxed=true&page=pageaction&action=initlanguage');
}

function totalSentUpdate(msgid) {
   $('#totalsent'+msgid).load('./?page=pageaction&ajaxed=true&action=msgsent&id='+msgid,"",function() {
   });
   setTimeout("totalSentUpdate("+msgid+")",5000);
}

$(document).ready(function() {
  $(".note .hide").click(function() {
    $(this).parents('.note').hide();
  });

  $(".configurelink").click(function() {
   // alert(this.href);
    $("#configurecontent").load('./?page=ajaxcall&action=test');
    $("#configurecontent").show();
    return false;
  });

  $("a.ajaxable").click(function() {
    var url = this.href;
    var thispage = urlParameter('page',window.location.href);
    var action = urlParameter('action',url);
    if (action == "") {
      url += '&action='+thispage;
    }
    parent = $(this).parent();
    parent.html(busyImage);
    url = url.replace(/page=/,'origpage=');
  //  alert(url+'&ajaxed=true&page=pageaction');
    parent.load(url+'&ajaxed=true&page=pageaction');
    return false;
  });

  $("input:checkbox.checkallcheckboxes").click(function() {
    if (this.checked) {
      $("input[type=checkbox]:not(:checked)").each(function(){
        this.checked = true;
      });
    } else {
      $("input[type=checkbox]:checked").each(function(){
        this.checked = false;
      });
    }
  });

  var stop = false;

  if ($.fn.accordion) {
    $(".accordion").accordion({
        autoHeight: false,
        navigation: true,
        collapsible: true
      });
  }

  $(".opendialog").click(function() {
    openHelpDialog(this.href);
    return false;
  });
  $(".helpdialog").click(function() {
    openHelpDialog(this.href);
    return false;
  });
  $(".closedialog").click(function() {
    $("#dialog").dialog('close');
  });

  //dropbuttons
  $("div.dropButton img.arrow").click(function(){
      submenu = $(this).parent().parent().find("div.submenu");
      if(submenu.css('display')=="block"){
        submenu.hide();
        $(this).attr('src',menuArrowImagesrc);
      } else {
        submenu.fadeIn();
        $(this).attr('src',menuArrowActiveImagesrc);
      }
      return false;
  });

  /* hmm, doesn't work yet, but would be nice at some point
  $("#emailsearch").autocomplete({
    source: "?page=pageaction&ajaxed=true&action=searchemail",
    minLength: 2,
    select: function(event, ui) {
    log(ui.item ? ("Selected: " + ui.item.value + " aka " + ui.item.id) : "Nothing selected, input was " + this.value);
    }
  });
  */

  if ($.fn.tabs) {
    $(".tabbed").tabs({
      //http://jqueryui.com/upgrade-guide/1.9/#deprecated-ajaxoptions-and-cache-options-added-beforeload-event
        ajaxOptions: {
        error: function(xhr, status, index, anchor) {
          $(anchor.hash).html("Error fetching page");
        }
      }
    });
    $(".tabbed1").tabs();
  }

  $("#remoteurlinput").focus(function() {
    if (this.value == 'e.g. http://www.phplist.com/testcampaign.html') {
      this.value = "";
    }
  })

  $("#remoteurlinput").blur(function() {
    if (this.value == "") {
      this.value = "e.g. http://www.phplist.com/testcampaign.html";
      return;
    }
    $("#remoteurlstatus").html(busyImage);
    $("#remoteurlstatus").load("./?page=pageaction&action=checkurl&ajaxed=true&url="+this.value);
  });

  $("input:radio[name=sendmethod]").change(function() {
    if (this.value == "remoteurl") {
      $("#remoteurl").show();
      $("#messagecontent").hide();
    } else {
      $("#remoteurl").hide();
      $("#messagecontent").show();
    }
  });

  $("a.savechanges").click(function() {
    if (changed) {
      document.sendmessageform.followupto.value = this.href;
      document.location.hash=""
      document.sendmessageform.submit();
      return false;
    }
  });

  $("#criteriaSelect").change(function() {
    var val = $("#criteriaSelect").val();
    var operator = '';
    switch (aT[val]) {
      case 'checkbox':
        $("#criteriaAttributeOperator").html('<input type="hidden" name="criteria_operator" value="is" />');
        $("#criteriaAttributeValues").html('CHECKED <input type="radio" name="criteria_values" value="checked" /> UNCHECKED <input type="radio" name="criteria_values" value="unchecked" />');
        break;
      case 'checkboxgroup':
      case 'select':
      case 'radio':
        $("#criteriaAttributeOperator").html('IS <input type="radio" name="criteria_operator" value="is" checked="checked" /> IS NOT <input type="radio" name="criteria_operator" value="isnot" />');
        $("#criteriaAttributeValues").html(busyImage);
        $("#criteriaAttributeValues").load("./?page=pageaction&ajaxed=true&action=attributevalues&name=criteria_values&type=multiselect&attid="+val);
        break;
      case 'date':
        $("#criteriaAttributeOperator").html('IS <input type="radio" name="criteria_operator" value="is" checked="checked" /> IS NOT <input type="radio" name="criteria_operator" value="isnot" /> IS BEFORE <input type="radio" name="criteria_operator" value="isbefore" /> IS AFTER <input type="radio" name="criteria_operator" value="isafter" />');
        $("#criteriaAttributeValues").html('<input type="text" id="datepicker" name="criteria_values" size="30"/>');
        $("#datepicker").datepicker({dateFormat: 'yy-mm-dd' });
        break;
      default:
        $("#criteriaAttributeOperator").html('');
        $("#criteriaAttributeValues").html('');
        break;
    }
  });

  $("#initialadminpassword").keyup(function() {
    if (this.value.length >= 8) {
      $("#initialisecontinue").removeAttr('disabled');
    }
  });
  $("#initialiseform").submit(function() {
    $("#dialog").dialog({
      minHeight: 400,
      width: 600,
      modal: true
    });
    $("#dialog").html('
Initialising phpList, please wait.
'+busyImage+'
');
  });

  // export page
  $("input:radio[name=column]").change(function() {
    if (this.value == 'nodate') {
      $("#exportdates").hide();
    } else {
      $("#exportdates").show();
    }
  });

  $("#processexport").click(function() {
    // for export, refresh underlying page, to get a new security token
    setTimeout("refreshExport()",2000);
  })

  //fade out 'actionresult' user feedback
  $('.actionresult').delay(4000).fadeOut(4000);
  //fade out 'result' user feedback
  $('.result').delay(4000).fadeOut(4000);

//  $("#processqueueoutput").html('Processing queue, please wait');
  $("#spinner").html(busyImage);

  $("#stopqueue").click(function() {
    $("#processqueueoutput").html('Processing cancelled');
    $("#spinner").html(' ');
    $("#stopqueue").hide();
    $("#resumequeue").show();
  });

  var docurl = document.location.search;
  document.cookie="browsetrail="+escape(docurl);

/* future dev
  $("#listinvalid").load("./?page=pageaction&action=listinvalid&ajaxed=true",function() {
 //  alert("Loaded")
  });
  $("#refreshCriteria").click(refreshCriteriaList);

  $("#addcriterionbutton").click(function() {
    $("#addcriterionbutton").addClass('disabled');
    var request = document.location.search+'&'+$("#sendmessageform").serialize();
    var attr = urlParameter('criteria_attribute',request);
    if (attr == '') {
      alert('Select an attribute to add');
      return false;
    };
    var vals = urlParameter('criteria_values',request);
    var arrVals = urlParameter('criteria_values[]',request);
    if (vals == '' && arrVals) {
      alert('Select a value to add');
      return false;
    };

    request = request.replace(/\?/,'');
    request = request.replace(/page=/,'origpage=');
    request = './?page=pageaction&action=storemessage&'+request;
    alert(request);
    $("#existingCriteria").html(busyImage);
 //   $("#hiddendiv").load(request);
 //   $("#sendmessageform").submit();
 //   setTimeout("refreshCriteriaList()",5000);

//    refreshCriteriaList();
    return true;
  });
*/

});

function allDone(text) {
  if (!text) {
    text = 'All done';
  }
  $("#processqueueoutput").html(''+text+'');
  $("#spinner").html(' ');
  $("#stopqueue").hide();
  $("#resumequeue").show();
  $("#progressmeter").hide();
}

var overallTotal = 0;
var overallSent = 0;

/* this one keeps track of the total between multiple processqueue runs */
$.fn.updateSendProgress = function() {
  var args = arguments[0].split(',') || {};
  var total = parseInt(args[1]);
  var done = parseInt(args[0]);
  if (total > overallTotal) {    overallTotal = total;  } else {    total = overallTotal;  }
  if (done > 0) {
    overallSent += done;
  }
  $.fn.updateProgress(overallSent,overallTotal);
}

$.fn.updateProgress = function() {
  if ($.isNumeric(arguments[0])) {
    var total = parseInt(arguments[1]);
    var done = parseInt(arguments[0]);
  } else {
    var args = arguments[0].split(',') || {};
    var total = parseInt(args[1]);
    var done = parseInt(args[0]);
  }
  var perc;
  if (total == 0) {
    perc = 0;
  } else {
    perc = parseInt((done / total) * 100);
  }
  $("#progresscount").html(done + ' / '+ total);
  $("#progresscount").show();
  $("#progressbar" ).progressbar({max: 100, value: +perc});
};

/*
 * old library of stuff that needs to be ported to jQuery style JS
 */

function deleteRec(url) {
	if (confirm("Are you sure you want to delete this record?")) {
		document.location = url;
	}
}

// @@TODO rewrite opening in pop-over
function viewImage(url,w,h) {
   alert("needs rewriting");
}
<commit_msg>increase page refresh<commit_after>
/*
 * application JS library, UI independent code
 *
 */

/* these can be "overwritten" by the UI */
var busyImage = '';
var menuArrowImage = 'ui/dressprow/images/menuarrow.png';
var menuArrowActiveImagesrc = 'ui/dressprow/images/menuarrow_active.png';

function urlParameter( name, link) {
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( link );
  if( results == null )
    return "";
  else
    return results[1];
}

var updateMessages = new Array();
var updateLock = false;
function messagesStatusUpdate() {
  if (updateLock) return;
  updateLock = true;
  for (var i = 0; i < updateMessages.length; i++) {
    messageStatusUpdate(updateMessages[i]);
  }
  updateLock = false;
}

function messageStatusUpdate(msgid) {
   if (msgid) {
      $('#messagestatus'+msgid).load('./?page=pageaction&ajaxed=true&action=msgstatus&id='+msgid,"",function() {});
   }
}

function getServerTime() {
   $('#servertime').load('./?page=pageaction&ajaxed=true&action=getservertime',"",function() {
   });
   setTimeout("getServerTime()",60100); // just over a minute
}

function refreshCriteriaList() {
  var id = urlParameter('id',document.location);
  $("#existingCriteria").html(busyImage);
  $("#existingCriteria").load('./?page=pageaction&ajaxed=true&action=listcriteria&id='+id);
}

function refreshExport() {
 // alert('Refresh '+document.location);
  document.location = document.location;
}

function openHelpDialog(url) {
  $("#dialog").dialog({
    minHeight: 400,
    width: 600,
    modal: true
  });
  $("#dialog").html('
'+busyImage+'
');
  var destpage = urlParameter('page',url);
  url = url.replace(/page=/,'origpage=');
  $("#dialog").load(url+'&ajaxed=true&page=pageaction&action='+destpage);
  $(".ui-widget-overlay").click(function() {
    $("#dialog").dialog('close');
  });
}

function initialiseTranslation(text) {
  $("#dialog").dialog({
    minHeight: 400,
    width: 600,
    modal: true
  });
  $("#dialog").html('
'+text+'
'+busyImage+'
');
  $("#dialog").load('./?ajaxed=true&page=pageaction&action=initlanguage');
}

function totalSentUpdate(msgid) {
   $('#totalsent'+msgid).load('./?page=pageaction&ajaxed=true&action=msgsent&id='+msgid,"",function() {
   });
   setTimeout("totalSentUpdate("+msgid+")",5000);
}

$(document).ready(function() {
  $(".note .hide").click(function() {
    $(this).parents('.note').hide();
  });

  $(".configurelink").click(function() {
   // alert(this.href);
    $("#configurecontent").load('./?page=ajaxcall&action=test');
    $("#configurecontent").show();
    return false;
  });

  $("a.ajaxable").click(function() {
    var url = this.href;
    var thispage = urlParameter('page',window.location.href);
    var action = urlParameter('action',url);
    if (action == "") {
      url += '&action='+thispage;
    }
    parent = $(this).parent();
    parent.html(busyImage);
    url = url.replace(/page=/,'origpage=');
  //  alert(url+'&ajaxed=true&page=pageaction');
    parent.load(url+'&ajaxed=true&page=pageaction');
    return false;
  });

  $("input:checkbox.checkallcheckboxes").click(function() {
    if (this.checked) {
      $("input[type=checkbox]:not(:checked)").each(function(){
        this.checked = true;
      });
    } else {
      $("input[type=checkbox]:checked").each(function(){
        this.checked = false;
      });
    }
  });

  var stop = false;

  if ($.fn.accordion) {
    $(".accordion").accordion({
        autoHeight: false,
        navigation: true,
        collapsible: true
      });
  }

  $(".opendialog").click(function() {
    openHelpDialog(this.href);
    return false;
  });
  $(".helpdialog").click(function() {
    openHelpDialog(this.href);
    return false;
  });
  $(".closedialog").click(function() {
    $("#dialog").dialog('close');
  });

  //dropbuttons
  $("div.dropButton img.arrow").click(function(){
      submenu = $(this).parent().parent().find("div.submenu");
      if(submenu.css('display')=="block"){
        submenu.hide();
        $(this).attr('src',menuArrowImagesrc);
      } else {
        submenu.fadeIn();
        $(this).attr('src',menuArrowActiveImagesrc);
      }
      return false;
  });

  /* hmm, doesn't work yet, but would be nice at some point
  $("#emailsearch").autocomplete({
    source: "?page=pageaction&ajaxed=true&action=searchemail",
    minLength: 2,
    select: function(event, ui) {
    log(ui.item ? ("Selected: " + ui.item.value + " aka " + ui.item.id) : "Nothing selected, input was " + this.value);
    }
  });
  */

  if ($.fn.tabs) {
    $(".tabbed").tabs({
      //http://jqueryui.com/upgrade-guide/1.9/#deprecated-ajaxoptions-and-cache-options-added-beforeload-event
        ajaxOptions: {
        error: function(xhr, status, index, anchor) {
          $(anchor.hash).html("Error fetching page");
        }
      }
    });
    $(".tabbed1").tabs();
  }

  $("#remoteurlinput").focus(function() {
    if (this.value == 'e.g. http://www.phplist.com/testcampaign.html') {
      this.value = "";
    }
  })

  $("#remoteurlinput").blur(function() {
    if (this.value == "") {
      this.value = "e.g. http://www.phplist.com/testcampaign.html";
      return;
    }
    $("#remoteurlstatus").html(busyImage);
    $("#remoteurlstatus").load("./?page=pageaction&action=checkurl&ajaxed=true&url="+this.value);
  });

  $("input:radio[name=sendmethod]").change(function() {
    if (this.value == "remoteurl") {
      $("#remoteurl").show();
      $("#messagecontent").hide();
    } else {
      $("#remoteurl").hide();
      $("#messagecontent").show();
    }
  });

  $("a.savechanges").click(function() {
    if (changed) {
      document.sendmessageform.followupto.value = this.href;
      document.location.hash=""
      document.sendmessageform.submit();
      return false;
    }
  });

  $("#criteriaSelect").change(function() {
    var val = $("#criteriaSelect").val();
    var operator = '';
    switch (aT[val]) {
      case 'checkbox':
        $("#criteriaAttributeOperator").html('<input type="hidden" name="criteria_operator" value="is" />');
        $("#criteriaAttributeValues").html('CHECKED <input type="radio" name="criteria_values" value="checked" /> UNCHECKED <input type="radio" name="criteria_values" value="unchecked" />');
        break;
      case 'checkboxgroup':
      case 'select':
      case 'radio':
        $("#criteriaAttributeOperator").html('IS <input type="radio" name="criteria_operator" value="is" checked="checked" /> IS NOT <input type="radio" name="criteria_operator" value="isnot" />');
        $("#criteriaAttributeValues").html(busyImage);
        $("#criteriaAttributeValues").load("./?page=pageaction&ajaxed=true&action=attributevalues&name=criteria_values&type=multiselect&attid="+val);
        break;
      case 'date':
        $("#criteriaAttributeOperator").html('IS <input type="radio" name="criteria_operator" value="is" checked="checked" /> IS NOT <input type="radio" name="criteria_operator" value="isnot" /> IS BEFORE <input type="radio" name="criteria_operator" value="isbefore" /> IS AFTER <input type="radio" name="criteria_operator" value="isafter" />');
        $("#criteriaAttributeValues").html('<input type="text" id="datepicker" name="criteria_values" size="30"/>');
        $("#datepicker").datepicker({dateFormat: 'yy-mm-dd' });
        break;
      default:
        $("#criteriaAttributeOperator").html('');
        $("#criteriaAttributeValues").html('');
        break;
    }
  });

  $("#initialadminpassword").keyup(function() {
    if (this.value.length >= 8) {
      $("#initialisecontinue").removeAttr('disabled');
    }
  });
  $("#initialiseform").submit(function() {
    $("#dialog").dialog({
      minHeight: 400,
      width: 600,
      modal: true
    });
    $("#dialog").html('
Initialising phpList, please wait.
'+busyImage+'
');
  });

  // export page
  $("input:radio[name=column]").change(function() {
    if (this.value == 'nodate') {
      $("#exportdates").hide();
    } else {
      $("#exportdates").show();
    }
  });

  $("#processexport").click(function() {
    // for export, refresh underlying page, to get a new security token
    setTimeout("refreshExport()",10000);
  })

  //fade out 'actionresult' user feedback
  $('.actionresult').delay(4000).fadeOut(4000);
  //fade out 'result' user feedback
  $('.result').delay(4000).fadeOut(4000);

//  $("#processqueueoutput").html('Processing queue, please wait');
  $("#spinner").html(busyImage);

  $("#stopqueue").click(function() {
    $("#processqueueoutput").html('Processing cancelled');
    $("#spinner").html(' ');
    $("#stopqueue").hide();
    $("#resumequeue").show();
  });

  var docurl = document.location.search;
  document.cookie="browsetrail="+escape(docurl);

/* future dev
  $("#listinvalid").load("./?page=pageaction&action=listinvalid&ajaxed=true",function() {
 //  alert("Loaded")
  });
  $("#refreshCriteria").click(refreshCriteriaList);

  $("#addcriterionbutton").click(function() {
    $("#addcriterionbutton").addClass('disabled');
    var request = document.location.search+'&'+$("#sendmessageform").serialize();
    var attr = urlParameter('criteria_attribute',request);
    if (attr == '') {
      alert('Select an attribute to add');
      return false;
    };
    var vals = urlParameter('criteria_values',request);
    var arrVals = urlParameter('criteria_values[]',request);
    if (vals == '' && arrVals) {
      alert('Select a value to add');
      return false;
    };

    request = request.replace(/\?/,'');
    request = request.replace(/page=/,'origpage=');
    request = './?page=pageaction&action=storemessage&'+request;
    alert(request);
    $("#existingCriteria").html(busyImage);
 //   $("#hiddendiv").load(request);
 //   $("#sendmessageform").submit();
 //   setTimeout("refreshCriteriaList()",5000);

//    refreshCriteriaList();
    return true;
  });
*/

});

function allDone(text) {
  if (!text) {
    text = 'All done';
  }
  $("#processqueueoutput").html(''+text+'');
  $("#spinner").html(' ');
  $("#stopqueue").hide();
  $("#resumequeue").show();
  $("#progressmeter").hide();
}

var overallTotal = 0;
var overallSent = 0;

/* this one keeps track of the total between multiple processqueue runs */
$.fn.updateSendProgress = function() {
  var args = arguments[0].split(',') || {};
  var total = parseInt(args[1]);
  var done = parseInt(args[0]);
  if (total > overallTotal) {    overallTotal = total;  } else {    total = overallTotal;  }
  if (done > 0) {
    overallSent += done;
  }
  $.fn.updateProgress(overallSent,overallTotal);
}

$.fn.updateProgress = function() {
  if ($.isNumeric(arguments[0])) {
    var total = parseInt(arguments[1]);
    var done = parseInt(arguments[0]);
  } else {
    var args = arguments[0].split(',') || {};
    var total = parseInt(args[1]);
    var done = parseInt(args[0]);
  }
  var perc;
  if (total == 0) {
    perc = 0;
  } else {
    perc = parseInt((done / total) * 100);
  }
  $("#progresscount").html(done + ' / '+ total);
  $("#progresscount").show();
  $("#progressbar" ).progressbar({max: 100, value: +perc});
};

/*
 * old library of stuff that needs to be ported to jQuery style JS
 */

function deleteRec(url) {
	if (confirm("Are you sure you want to delete this record?")) {
		document.location = url;
	}
}

// @@TODO rewrite opening in pop-over
function viewImage(url,w,h) {
   alert("needs rewriting");
}
<|endoftext|>


<commit_before>var dateFormat = require('dateformat');

Entry.create = function(gEntry) {
    return new Entry(gEntry);
}

function Entry(gEntry) {
    this._id = gEntry.id;
    this._title = gEntry.title;
    this._url = gEntry.origin ? gEntry.origin.htmlUrl : "";
    this._tstamp = gEntry.updated;
    this._summary = gEntry.summary ? gEntry.summary.content : "";
    this._isFresh = getIsFresh(gEntry.categories);
}

function getIsFresh(categories) {
    if (categories === undefined) return false;
    for (var i = 0; i < categories.length; i++) {
        if (categories[i].match(/fresh$/)) { return true; }
    }
    return false;
}

Entry.get = function(id, cb) {
    return Entry.GReader().getEntry(id, cb);
}

Entry.GReader = function() {
    return require('../services/class.greader.js');
}

Entry.prototype.id = function(id) {
    if (id === undefined) {
        return this._id;
    }
    this._id = id;
}

Entry.prototype.title = function(title) {
    if (title === undefined) {
        return this._title;
    }
    this._title = title;
}

Entry.prototype.shortTitle = function() {
    return this._title && this._title.length > 34 ?
        this._title.substr(0, 31) + "..." : this._title;
};

Entry.prototype.url = function(url) {
    if (url === undefined) {
        return this._url;
    }
    this._url = url;
}

Entry.prototype.tstamp = function(tstamp) {
    if (tstamp === undefined) {
        return this._tstamp;
    }
    this._tstamp = tstamp;
}

Entry.prototype.summary = function(summary) {
    if (summary === undefined) {
        return this._summary;
    }
    this._summary = summary;
}

Entry.prototype.isFresh = function(isFresh) {
    if (isFresh === undefined) {
        return this._isFresh;
    }
    this._isFresh = isFresh;
}

Entry.prototype.date = function() {
    return dateFormat(this._tstamp * 1000, "dd mmm, yyyy");
};

module.exports = Entry;
<commit_msg>Fix bug retrieving external Url of entry<commit_after>var dateFormat = require('dateformat');

Entry.create = function(gEntry) {
    return new Entry(gEntry);
}

function Entry(gEntry) {
    this._id = gEntry.id;
    this._title = gEntry.title;
    this._url = getUrlFor(gEntry);
    this._tstamp = gEntry.updated;
    this._summary = gEntry.summary ? gEntry.summary.content : "";
    this._isFresh = getIsFresh(gEntry.categories);
}

function getUrlFor(gEntry) {
    if (gEntry.items && gEntry.items.length > 0) {
        var alternate = gEntry.items[0].alternate;
        if (alternate) return alternate[0].href;
    }
    return "";
}

function getIsFresh(categories) {
    if (categories === undefined) return false;
    for (var i = 0; i < categories.length; i++) {
        if (categories[i].match(/fresh$/)) { return true; }
    }
    return false;
}

Entry.get = function(id, cb) {
    return Entry.GReader().getEntry(id, cb);
}

Entry.GReader = function() {
    return require('../services/class.greader.js');
}

Entry.prototype.id = function(id) {
    if (id === undefined) {
        return this._id;
    }
    this._id = id;
}

Entry.prototype.title = function(title) {
    if (title === undefined) {
        return this._title;
    }
    this._title = title;
}

Entry.prototype.shortTitle = function() {
    return this._title && this._title.length > 34 ?
        this._title.substr(0, 31) + "..." : this._title;
};

Entry.prototype.url = function(url) {
    if (url === undefined) {
        return this._url;
    }
    this._url = url;
}

Entry.prototype.tstamp = function(tstamp) {
    if (tstamp === undefined) {
        return this._tstamp;
    }
    this._tstamp = tstamp;
}

Entry.prototype.summary = function(summary) {
    if (summary === undefined) {
        return this._summary;
    }
    this._summary = summary;
}

Entry.prototype.isFresh = function(isFresh) {
    if (isFresh === undefined) {
        return this._isFresh;
    }
    this._isFresh = isFresh;
}

Entry.prototype.date = function() {
    return dateFormat(this._tstamp * 1000, "dd mmm, yyyy");
};

module.exports = Entry;
<|endoftext|>