<commit_before>// Copyright (c) 2012 Johannes Zellner webmaster@nebulon.de - All Rights Reserved

"use strict";

/*
 **************************************************
 * Singleton engine
 **************************************************
 *
 * Handles mainly toplevel elements and detects bindings.
 * This should contain as less as possible!
 *
 */

if (!Quick) {
    var Quick = {};
}

 // animation frame shim
window.requestAnimFrame = (function () {
    return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function (callback) {
            window.setTimeout(callback, 1000 / 60);
        };
}());

// create main singleton object
if (!Quick.Engine) {
    Quick.Engine = (function () {
        var ret = {};
        var getterCalled = {};
        var dirtyElements = [];
        var updateTimer;

        ret.magicBindingState = false;
        ret.verbose = false;

        function log(msg, error) {
            if (ret.verbose || error) {
                console.log("[Quick.Engine] " + msg);
            }
        }

        // try to create a renderer backend, currently on DOM supported
        try {
            var renderer = new QuickRendererDOM();
            ret.createElement = renderer.createElement;
            ret.addElement = renderer.addElement;
            ret.addElements = renderer.addElements;
            ret.renderElement = renderer.renderElement;
        } catch (e) {
            log("Cannot create DOM renderer", true);
            ret.createElement = function () {};
            ret.addElements = function () {};
            ret.addElement = function () {};
            ret.renderElement = function () {};
        }

        // begin binding detection
        ret.enterMagicBindingState = function () {
            log("enterMagicBindingState");
            getterCalled = {};
            ret.magicBindingState = true;
        };

        // end binding detection
        ret.exitMagicBindingState = function () {
            log("exitMagicBindingState\n\n");
            ret.magicBindingState = false;
            return getterCalled;
        };

        ret.addCalledGetter = function (element, property) {
            getterCalled[element.id + "." + property] = { element: element, property: property };
        };

        // TODO should be part of the dom renderer?
        function advance() {
            window.requestAnimFrame(advance);
            var i;
            for (i = 0; i < dirtyElements.length; ++i) {
                dirtyElements[i].render();
            }
            dirtyElements = [];
        }

        advance();

        ret.dirty = function (element, property) {
            element.properties[property].dirty = true;
            if (dirtyElements.indexOf(element) === -1)
                dirtyElements[dirtyElements.length] = element;
        };

        return ret;
    }());
}

/*
 **************************************************
 * Basic Element
 **************************************************
 *
 * The main element, which handles its connections
 * and properties. It also calls into the renderer
 * by using render hooks.
 *
 */
function Element(id, parent) {
    this.id = id;
    this.element = Quick.Engine.createElement('item', this);
    this.parent = parent;

    this.properties = {};
    this.connections = {};
    this.children = [];
    this.bound = {};

    if (this.parent) {
        this.parent.addChild(this);
    }
}

Element.prototype.addChildren = function (children) {
    for (var j = 0; j < children.length; ++j) {
        var child = children[j];

        // adds child id to the namespace
        this[child.id] = child;

        // adds the parents id to the child
        child[this.id] = this;

        // add child to siblings scope and vice versa
        var i;
        for (i = 0; i < this.children.length; ++i) {
            this.children[i][child.id] = child;
            child[this.children[i].id] = this.children[i];
        }

        // add newly added child to internal children array
        this.children[this.children.length] = child;

        child.parent = this;
    }

    Quick.Engine.addElements(children, this);
}

Element.prototype.addChild = function (child) {
    // adds child id to the namespace
    this[child.id] = child;

    // adds the parents id to the child
    child[this.id] = this;

    // add child to siblings scope and vice versa
    var i;
    for (i = 0; i < this.children.length; ++i) {
        this.children[i][child.id] = child;
        child[this.children[i].id] = this.children[i];
    }

    // add newly added child to internal children array
    this.children[this.children.length] = child;

    child.parent = this;
    Quick.Engine.addElement(child, this);

    return child;
};

Element.prototype.render = function () {
    Quick.Engine.renderElement(this);
};

Element.prototype.addChanged = function (signal, callback) {
    if (!this.connections[signal]) {
        this.connections[signal] = [];
    }

    this.connections[signal][this.connections[signal].length] = callback;
    // console.log("connections for " + signal + " " + this.connections[signal].length);
};

Element.prototype.removeChanged = function (obj, signal) {
    var signalConnections = this.connections[signal];
    // check if there are any connections for this signal
    if (!signalConnections) {
        return;
    }

    for (var i = 0; i < signalConnections.length; ++i) {
        // TODO do implementation
    }
};

Element.prototype.addBinding = function (name, value) {
    // console.log("addBinding", name);

    var that = this;
    var hasBinding = false;

    // FIXME does not catch changing conditions in expression
    //  x: mouseArea.clicked ? a.y() : b:z();
    Quick.Engine.enterMagicBindingState();
    var val = value.apply(this);
    // console.log("addBinding result", name, val);
    var getters = Quick.Engine.exitMagicBindingState();

    // break all previous bindings
    for (var i = 0; i < this.bound[name]; this.bound[name].length) {
        console.log("!!! experimental untested: break binding for " + name);
        var boundObject = this.bound[name][i];
        boundObject.removeChanged(this, name);
    }
    this.bound[name] = [];

    // TODO test break bindings as well!!
    for (var getter in getters) {
        var tmp = getters[getter];
        // store bindings to this for breaking
        this.bound[name][this.bound[name].length] = { element: tmp.element, property: tmp.property };

        tmp.element.addChanged(tmp.property, function() {
            that[name] = value.apply(that);
        });
        hasBinding = true;
    }

    return { hasBindings: hasBinding, value: val };
};

Element.prototype.addEventHandler = function (event, handler) {
    var that = this;
    var signal = event;

    if (signal === "" || typeof handler !== 'function') {
        return;
    }

    if (signal.indexOf('on') === 0) {
        signal = signal.slice(2);
    }

    this.addChanged(signal, function () {
        handler.apply(that);
    });
}

Element.prototype.addProperty = function (name, value) {
    var that = this;
    var valueStore;

    // register property
    this.properties[name] = {value: value, dirty: false};

    if (this.hasOwnProperty(name)) {
        this.name = value;
    } else {
        Object.defineProperty(this, name, {
            get: function () {
                // console.log("getter: ", that.id, name);
                Quick.Engine.addCalledGetter(that, name);

                if (typeof valueStore === 'function')
                    return valueStore.apply(that);

                return valueStore;
            },
            set: function (val) {
                // console.log("setter: ", that.id, name, val);
                if (valueStore === val)
                    return;

                valueStore = val;

                // connections are called like the properties
                that.emit(name);
                Quick.Engine.dirty(that, name);
            }
        });
    }
};

// initial set of all properties and binding evaluation
// should only be called once
Element.prototype.initializeBindings = function () {
    var name, i;
    for (name in this.properties) {
        var value = this.properties[name].value;

        // console.log("Element.initializeBindings()", this.id, name, value);

        // initial set and binding discovery
        if (typeof value === 'function') {
            var ret = this.addBinding(name, value);
            if (ret.hasBindings) {
                this[name] = value;
            } else {
                this[name] = ret.value;
            }
        } else {
            this[name] = value;
        }
    }

    for (i = 0; i < this.children.length; ++i) {
        this.children[i].initializeBindings();
    }

    // this calls the onload slot, if defined
    this.emit("load");
};

Element.prototype.emit = function (signal) {
    // console.log("## emit signal " + signal);
    if (signal in this.connections) {
        // console.log("### signal has connections", signal);
        for (var slot in this.connections[signal]) {
            // console.log("#### execute slot", slot);
            this.connections[signal][slot]();
        }
    }
};
<commit_msg>for now only track getters when we are in the magicbindingstate<commit_after>// Copyright (c) 2012 Johannes Zellner webmaster@nebulon.de - All Rights Reserved

"use strict";

/*
 **************************************************
 * Singleton engine
 **************************************************
 *
 * Handles mainly toplevel elements and detects bindings.
 * This should contain as less as possible!
 *
 */

if (!Quick) {
    var Quick = {};
}

 // animation frame shim
window.requestAnimFrame = (function () {
    return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function (callback) {
            window.setTimeout(callback, 1000 / 60);
        };
}());

// create main singleton object
if (!Quick.Engine) {
    Quick.Engine = (function () {
        var ret = {};
        var getterCalled = {};
        var dirtyElements = [];
        var updateTimer;

        ret.magicBindingState = false;
        ret.verbose = false;

        function log(msg, error) {
            if (ret.verbose || error) {
                console.log("[Quick.Engine] " + msg);
            }
        }

        // try to create a renderer backend, currently on DOM supported
        try {
            var renderer = new QuickRendererDOM();
            ret.createElement = renderer.createElement;
            ret.addElement = renderer.addElement;
            ret.addElements = renderer.addElements;
            ret.renderElement = renderer.renderElement;
        } catch (e) {
            log("Cannot create DOM renderer", true);
            ret.createElement = function () {};
            ret.addElements = function () {};
            ret.addElement = function () {};
            ret.renderElement = function () {};
        }

        // begin binding detection
        ret.enterMagicBindingState = function () {
            log("enterMagicBindingState");
            getterCalled = {};
            ret.magicBindingState = true;
        };

        // end binding detection
        ret.exitMagicBindingState = function () {
            log("exitMagicBindingState\n\n");
            ret.magicBindingState = false;
            return getterCalled;
        };

        ret.addCalledGetter = function (element, property) {
            getterCalled[element.id + "." + property] = { element: element, property: property };
        };

        // TODO should be part of the dom renderer?
        function advance() {
            window.requestAnimFrame(advance);
            var i;
            for (i = 0; i < dirtyElements.length; ++i) {
                dirtyElements[i].render();
            }
            dirtyElements = [];
        }

        advance();

        ret.dirty = function (element, property) {
            element.properties[property].dirty = true;
            if (dirtyElements.indexOf(element) === -1)
                dirtyElements[dirtyElements.length] = element;
        };

        return ret;
    }());
}

/*
 **************************************************
 * Basic Element
 **************************************************
 *
 * The main element, which handles its connections
 * and properties. It also calls into the renderer
 * by using render hooks.
 *
 */
function Element(id, parent) {
    this.id = id;
    this.element = Quick.Engine.createElement('item', this);
    this.parent = parent;

    this.properties = {};
    this.connections = {};
    this.children = [];
    this.bound = {};

    if (this.parent) {
        this.parent.addChild(this);
    }
}

Element.prototype.addChildren = function (children) {
    for (var j = 0; j < children.length; ++j) {
        var child = children[j];

        // adds child id to the namespace
        this[child.id] = child;

        // adds the parents id to the child
        child[this.id] = this;

        // add child to siblings scope and vice versa
        var i;
        for (i = 0; i < this.children.length; ++i) {
            this.children[i][child.id] = child;
            child[this.children[i].id] = this.children[i];
        }

        // add newly added child to internal children array
        this.children[this.children.length] = child;

        child.parent = this;
    }

    Quick.Engine.addElements(children, this);
}

Element.prototype.addChild = function (child) {
    // adds child id to the namespace
    this[child.id] = child;

    // adds the parents id to the child
    child[this.id] = this;

    // add child to siblings scope and vice versa
    var i;
    for (i = 0; i < this.children.length; ++i) {
        this.children[i][child.id] = child;
        child[this.children[i].id] = this.children[i];
    }

    // add newly added child to internal children array
    this.children[this.children.length] = child;

    child.parent = this;
    Quick.Engine.addElement(child, this);

    return child;
};

Element.prototype.render = function () {
    Quick.Engine.renderElement(this);
};

Element.prototype.addChanged = function (signal, callback) {
    if (!this.connections[signal]) {
        this.connections[signal] = [];
    }

    this.connections[signal][this.connections[signal].length] = callback;
    // console.log("connections for " + signal + " " + this.connections[signal].length);
};

Element.prototype.removeChanged = function (obj, signal) {
    var signalConnections = this.connections[signal];
    // check if there are any connections for this signal
    if (!signalConnections) {
        return;
    }

    for (var i = 0; i < signalConnections.length; ++i) {
        // TODO do implementation
    }
};

Element.prototype.addBinding = function (name, value) {
    // console.log("addBinding", name);

    var that = this;
    var hasBinding = false;

    // FIXME does not catch changing conditions in expression
    //  x: mouseArea.clicked ? a.y() : b:z();
    Quick.Engine.enterMagicBindingState();
    var val = value.apply(this);
    // console.log("addBinding result", name, val);
    var getters = Quick.Engine.exitMagicBindingState();

    // break all previous bindings
    for (var i = 0; i < this.bound[name]; this.bound[name].length) {
        console.log("!!! experimental untested: break binding for " + name);
        var boundObject = this.bound[name][i];
        boundObject.removeChanged(this, name);
    }
    this.bound[name] = [];

    // TODO test break bindings as well!!
    for (var getter in getters) {
        var tmp = getters[getter];
        // store bindings to this for breaking
        this.bound[name][this.bound[name].length] = { element: tmp.element, property: tmp.property };

        tmp.element.addChanged(tmp.property, function() {
            that[name] = value.apply(that);
        });
        hasBinding = true;
    }

    return { hasBindings: hasBinding, value: val };
};

Element.prototype.addEventHandler = function (event, handler) {
    var that = this;
    var signal = event;

    if (signal === "" || typeof handler !== 'function') {
        return;
    }

    if (signal.indexOf('on') === 0) {
        signal = signal.slice(2);
    }

    this.addChanged(signal, function () {
        handler.apply(that);
    });
}

Element.prototype.addProperty = function (name, value) {
    var that = this;
    var valueStore;

    // register property
    this.properties[name] = {value: value, dirty: false};

    if (this.hasOwnProperty(name)) {
        this.name = value;
    } else {
        Object.defineProperty(this, name, {
            get: function () {
                // console.log("getter: ", that.id, name);
                if (Quick.Engine.magicBindingState)
                    Quick.Engine.addCalledGetter(that, name);

                if (typeof valueStore === 'function')
                    return valueStore.apply(that);

                return valueStore;
            },
            set: function (val) {
                // console.log("setter: ", that.id, name, val);
                if (valueStore === val)
                    return;

                valueStore = val;

                // connections are called like the properties
                that.emit(name);
                Quick.Engine.dirty(that, name);
            }
        });
    }
};

// initial set of all properties and binding evaluation
// should only be called once
Element.prototype.initializeBindings = function () {
    var name, i;
    for (name in this.properties) {
        var value = this.properties[name].value;

        // console.log("Element.initializeBindings()", this.id, name, value);

        // initial set and binding discovery
        if (typeof value === 'function') {
            var ret = this.addBinding(name, value);
            if (ret.hasBindings) {
                this[name] = value;
            } else {
                this[name] = ret.value;
            }
        } else {
            this[name] = value;
        }
    }

    for (i = 0; i < this.children.length; ++i) {
        this.children[i].initializeBindings();
    }

    // this calls the onload slot, if defined
    this.emit("load");
};

Element.prototype.emit = function (signal) {
    // console.log("## emit signal " + signal);
    if (signal in this.connections) {
        // console.log("### signal has connections", signal);
        for (var slot in this.connections[signal]) {
            // console.log("#### execute slot", slot);
            this.connections[signal][slot]();
        }
    }
};
<|endoftext|>


<commit_before>System.config({
	transpiler: 'typescript',
	typescriptOptions: {
		target: "es5",
		module: "commonjs",
		emitDecoratorMetadata: true,
        experimentalDecorators: true
	},
	map: {
		'app': './app',

		'@angular/common': '@angular/common/bundles/common.umd.min.js',
		'@angular/compiler': '@angular/compiler/bundles/compiler.umd.min.js',
		'@angular/core': '@angular/core/bundles/core.umd.min.js',
		'@angular/forms': '@angular/forms/bundles/forms.umd.min.js',
		'@angular/http': '@angular/http/bundles/http.umd.min.js',
		'@angular/platform-browser': '@angular/platform-browser/bundles/platform-browser.umd.min.js',
		'@angular/platform-browser-dynamic': '@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.min.js',
		'@angular/router': '@angular/router/bundles/router.umd.min.js',

		'rxjs': 'rxjs/bundles/Rx.min.js',
		'typescript': 'typescript/lib/typescript.js'
	},
	packages: {
		app: {
			main: './main.ts',
			defaultExtension: 'ts'
		},
		rxjs: {
			defaultExtension: 'js'
		}
	}
});

System.import('app').catch(console.error.bind(console));
<commit_msg>SystemJs fix<commit_after>System.config({
	transpiler: 'typescript',
	typescriptOptions: {
		target: "es5",
		module: "commonjs",
		emitDecoratorMetadata: true,
        experimentalDecorators: true,
		paths: {
			uitoolkit: '/uitoolkit'
		}
	},
	map: {
		'app': './app',

		'@angular/common': '@angular/common/bundles/common.umd.min.js',
		'@angular/compiler': '@angular/compiler/bundles/compiler.umd.min.js',
		'@angular/core': '@angular/core/bundles/core.umd.min.js',
		'@angular/forms': '@angular/forms/bundles/forms.umd.min.js',
		'@angular/http': '@angular/http/bundles/http.umd.min.js',
		'@angular/platform-browser': '@angular/platform-browser/bundles/platform-browser.umd.min.js',
		'@angular/platform-browser-dynamic': '@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.min.js',
		'@angular/router': '@angular/router/bundles/router.umd.min.js',

		'rxjs': 'rxjs/',
		'typescript': 'typescript/lib/typescript.js'
	},
	packages: {
		app: {
			main: './main.ts',
			defaultExtension: 'ts'
		},
		uitoolkit: {
			defaultExtension: 'js'
		},
		rxjs: {
			defaultExtension: 'js'
		}
	}
});

System.import('app').catch(console.error.bind(console));
<|endoftext|>


<commit_before>var Procession = require('procession')
var logger = require('prolific.logger').createLogger('happenstance/timer')

function Timer (scheduler) {
    this.events = new Procession
    this._timeout = null
    this._scheduler = scheduler
}

Timer.prototype.push = function (event) {
    switch (event.method) {
    case 'set':
        var now = Date.now()
        logger.info('set', { now: now, duration: event.body.when - now, $event: event })
        this._unset()
        this._timeout = setTimeout(this._check.bind(this), Math.max(event.body.when - now, 0))
        break
    case 'unset':
        logger.info('unset', { now: now, $event: event })
        this._unset()
        break
    default:
        this.events.push(event)
        break
    }
}

Timer.prototype.enqueue = function (event, callback) {
    this.push(event)
    callback()
}

Timer.prototype._check = function () {
    var now = Date.now()
    logger.info('unset', { now: now, $calendar: this._scheduler.calendar() })
    this._timeout = null
    this._scheduler.check(now)
}

Timer.prototype._unset = function () {
    if (this._timeout != null) {
        clearTimeout(this._timeout)
        this._timeout = null
    }
}

module.exports = Timer
<commit_msg>Timer now handles `null` events.<commit_after>var Procession = require('procession')
var logger = require('prolific.logger').createLogger('happenstance/timer')

function Timer (scheduler) {
    this.events = new Procession
    this._timeout = null
    this._scheduler = scheduler
}

Timer.prototype.push = function (event) {
    switch (event && event.method) {
    case 'set':
        var now = Date.now()
        logger.info('set', { now: now, duration: event.body.when - now, $event: event })
        this._unset()
        this._timeout = setTimeout(this._check.bind(this), Math.max(event.body.when - now, 0))
        break
    case 'unset':
        logger.info('unset', { now: now, $event: event })
        this._unset()
        break
    default:
        this.events.push(event)
        break
    }
}

Timer.prototype.enqueue = function (event, callback) {
    this.push(event)
    callback()
}

Timer.prototype._check = function () {
    var now = Date.now()
    logger.info('unset', { now: now, $calendar: this._scheduler.calendar() })
    this._timeout = null
    this._scheduler.check(now)
}

Timer.prototype._unset = function () {
    if (this._timeout != null) {
        clearTimeout(this._timeout)
        this._timeout = null
    }
}

module.exports = Timer
<|endoftext|>


<commit_before>
// switch to testing mode
process.env.NODE_ENV = 'testing';

var utils         = require('../../lib/utils'),
    PopIt         = require('../../lib/popit'),
    MigrationApp  = require('../../lib/apps/migration');

module.exports = {

    setUp: function(cb) {
        this.popit  = new PopIt();
        this.popit.set_instance('test');
        this.Migration = this.popit.model('Migration');

        utils.delete_all_testing_databases(cb);
    },

    tearDown: function(cb) {
        // close the connections so that the test script can exit
        this.popit.close_db_connections(cb);
    },

    "database model": function ( test ) {
        test.expect( 11 );

        var migration = new this.Migration();
        test.ok( migration, "got new migation" );

        // initial settings
        test.equal( migration.created, Date(), 'current date' );
        test.equal( migration.source.name, null, 'empty source name' );
        test.equal( migration.source.mime_type, null, 'empty source mime_type' );
        test.equal( migration.source.parsed.header.length, 0, 'empty parsed source header' );
        test.equal( migration.source.parsed.data, null, 'empty parsed source data' );

        migration.source.name ="FooBar";
        test.equal( migration.source.name, "FooBar", 'source name changed' );

        migration.source.mime_type ="text/csv";
        test.equal( migration.source.mime_type, "text/csv", 'source mime_type changed' );

        var array = [ 'alpha', 'beta' ]
        migration.source.parsed.header = array;
        test.equal( migration.source.parsed.header.length, array.length, 'parsed source header changed' );

        var obj = {"0" : ["foo", "bar", "baz"]};
        migration.source.parsed.data = obj;
        test.deepEqual( migration.source.parsed.data, obj, 'parsed source data changed' );
        test.notDeepEqual( migration.source.parsed.data, {"1": ["foo"]}, 'parsed source data changed' );

        test.done();
    },

    "parse csv": function ( test ) {
        test.expect( 5 );

        var migration = new MigrationApp();
        test.ok( migration, "got new migation app" );

        test.ok( migration.parseCsv, "migration tests" );

        var realParsedCsv = { '0': [ 'a', 'b', 'c' ],
                              '1': [ ' foo\t', ' bar' ],
                              '2': [ '%*', ' ä', ' ßßß', ' ' ] };
        migration.parseCsv(__dirname+"/sample_csv.txt", function(parsed, err) {
          test.ifError(err);
          test.ok( parsed, "migration tests" );
          test.deepEqual( parsed, realParsedCsv, "migration tests" );

          test.done();

        });
    },

     "array to inverted dictionary": function ( test ) {
        test.expect( 3 );

        var migration = new MigrationApp();
        test.ok( migration, "got new migation app" );

        test.ok( migration.zipIt, "migration tests" );

        var mappings =  [[ 'firstname', 'name', 'First name' ],
            [ 'middlename', 'name', 'Middle name' ],
            [ 'lastname', 'name', 'Last name' ],
            [ 'twitter', 'links', 'Twitter' ],
            [ 'facebook', 'links', 'Facebook' ]];
        var attributes = [ 'John',
            'Peter',
            'Doe',
            '@funkyjohn',
            'John Doe'];

        var expect = {
          'name': {
            'First name': 'John',
            'Middle name': 'Peter',
            'Last name': 'Doe'},
          'links': {
            'Twitter': '@funkyjohn',
            'Facebook': 'John Doe'
          }};

        var inverted = migration.zipIt(mappings, attributes);

        test.deepEqual(inverted, expect, 'correctly inverted');

        test.done();
    },

    "import of two people": function ( test ) {
        test.expect( 10 );

        var migration = new MigrationApp();
        test.ok( migration, "got new migation app" );

        test.ok( migration.doImport, "migration tests" );

        schema = 'person';
        mappings =
            [ [ 'title', 'name', 'Title' ],
              [ 'firstname', 'name', 'First name' ],
              [ 'middlename', 'name', 'Middle name' ],
              [ 'lastname', 'name', 'Last name' ],
              [ 'name_suffix', 'name', 'Name suffix' ],
              [ 'nickname', '', '' ],
              [ 'party', 'position', 'Party' ],
              [ 'state', '', '' ],
              [ 'district', '', '' ],
              [ 'in_office', '', '' ],
              [ 'gender', '', '' ],
              [ 'phone', 'contact', 'Phone' ],
              [ 'fax', 'contact', 'Fax' ],
              [ 'website', 'links', 'Website' ],
              [ 'webform', 'links', 'Webform' ],
              [ 'congress_office', '', '' ],
              [ 'bioguide_id', '', '' ],
              [ 'votesmart_id', '', '' ],
              [ 'fec_id', '', '' ],
              [ 'govtrack_id', '', '' ],
              [ 'crp_id', '', '' ],
              [ 'twitter_id', 'id', 'Twitter' ],
              [ 'congresspedia_url', 'links', 'congresspedia' ],
              [ 'youtube_url', 'links', 'Youtube' ],
              [ 'facebook_id', 'id', 'Facebook' ],
              [ 'official_rss', 'links', 'RSS' ],
              [ 'senate_class', '', '' ],
              [ 'birthdate', 'name', 'Birthdate' ] ];
        data = {'675':
          [ 'Sen',
            'John',
            'A.',
            'Doe',
            '',
            '',
            'R',
            'SD',
            'Junior Seat',
            '1',
            'M',
            '',
            '734-234-3545',
            'http://www.doe.senate.gov/',
            'http://www.doe.senate.gov/public/index.cfm/contact',
            'Office Building',
            '56456',
            '123',
            'S2SD00068',
            '400546',
            'N00044342',
            '@thedoe',
            'http://www.opencongress.org/wiki/John_Doe',
            'http://www.youtube.com/JohnDoe',
            '63002536261',
            '',
            'III',
            '02/04/1900' ],
        '676':
          [ 'Sen',
            'Peter',
            'L.',
            'Johnson',
            '',
            '',
            'D',
            'SD',
            'Junior Seat',
            '1',
            'M',
            '734-234-3547',
            '',
            'http://www.johnson.senate.gov/',
            'http://www.johnson.senate.gov/public/index.cfm/contact',
            'Office Building',
            '6564566',
            '3456',
            '34566634',
            '400546',
            'N2356546',
            '@mrsen',
            '',
            'http://www.youtube.com/PeterJohnsson',
            '63002536261',
            'http://www.test.co.uk/rssfeed',
            'II',
            '01/10/2010' ]};

        var that = this;

        migration.doImport(that.popit, schema, mappings, data, function(err, people) {
          test.ifError(err);
          test.equal(people.length, 2, 'two people in people set');

          var query = that.popit.model('Person').find();

          query.run(function(err, docs) {
            test.ifError(err);

            test.equal(docs.length, 2, 'two people in database');

            docs.forEach(function(doc) {
              test.equal(doc.links.length, 4, 'four links per person');
              test.equal(doc.contact_details.length, 1, 'one contact detail per person');
            })

            test.done();
          });
        });
    },

    "create organisation and position when importing a person": function ( test ) {
      test.expect( 5 );
      var migration = new MigrationApp();

      schema = 'person';
      mappings = [
        [ 'firstname', 'name', 'First name' ],
        [ 'lastname', 'name', 'Last name' ],
        [ 'party', 'position', 'Party' ] ];
      data = {'675':
        [ 'John',
          'Doe',
          'Aliens']};

      var that = this;

      migration.doImport(that.popit, schema, mappings, data, function(err, people, positions, organisations) {
        test.ifError(err);
        test.equal(organisations.length, 1, 'one organisation in organisations set');

        async.parallel([
          function(cb) {
            var query = that.popit.model('Position').find();
            query.run(function(err, docs) {
              test.equal(docs.length, 1, 'one position in database');
              cb(err);
            });
          },
          function(cb) {
            var query = that.popit.model('Organisation').find();
            query.run(function(err, docs) {
              test.equal(docs.length, 1, 'one organisation in database');
              cb(err);
            });
          }],
          function(err) {
            test.ifError(err);
            test.done();
          })
      });
    },

    "handling of duplicate slugs": function ( test ) {
      test.expect( 2 );

      var migration = new MigrationApp();

      schema = 'person';
      mappings =
        [ [ 'firstname', 'name', 'First name' ],
        [ 'lastname', 'name', 'Last name' ] ];
      data = {
        '675':
          [ 'John',
        'Doe' ],
        '676':
          [ 'John',
        'Doe'],
        '677':
          [ 'John',
        'Doe']};

      var that = this;

      migration.doImport(that.popit, schema, mappings, data, function(err, people){
        test.ifError(err, 'expect no error');
        test.equal(people.length, 3, 'three people in people set');

        var query = that.popit.model('Person').find().asc('name');

        test.done();
      });
    }
};
<commit_msg>changed test name<commit_after>
// switch to testing mode
process.env.NODE_ENV = 'testing';

var utils         = require('../../lib/utils'),
    PopIt         = require('../../lib/popit'),
    MigrationApp  = require('../../lib/apps/migration');

module.exports = {

    setUp: function(cb) {
        this.popit  = new PopIt();
        this.popit.set_instance('test');
        this.Migration = this.popit.model('Migration');

        utils.delete_all_testing_databases(cb);
    },

    tearDown: function(cb) {
        // close the connections so that the test script can exit
        this.popit.close_db_connections(cb);
    },

    "database model": function ( test ) {
        test.expect( 11 );

        var migration = new this.Migration();
        test.ok( migration, "got new migation" );

        // initial settings
        test.equal( migration.created, Date(), 'current date' );
        test.equal( migration.source.name, null, 'empty source name' );
        test.equal( migration.source.mime_type, null, 'empty source mime_type' );
        test.equal( migration.source.parsed.header.length, 0, 'empty parsed source header' );
        test.equal( migration.source.parsed.data, null, 'empty parsed source data' );

        migration.source.name ="FooBar";
        test.equal( migration.source.name, "FooBar", 'source name changed' );

        migration.source.mime_type ="text/csv";
        test.equal( migration.source.mime_type, "text/csv", 'source mime_type changed' );

        var array = [ 'alpha', 'beta' ]
        migration.source.parsed.header = array;
        test.equal( migration.source.parsed.header.length, array.length, 'parsed source header changed' );

        var obj = {"0" : ["foo", "bar", "baz"]};
        migration.source.parsed.data = obj;
        test.deepEqual( migration.source.parsed.data, obj, 'parsed source data changed' );
        test.notDeepEqual( migration.source.parsed.data, {"1": ["foo"]}, 'parsed source data changed' );

        test.done();
    },

    "parse csv": function ( test ) {
        test.expect( 5 );

        var migration = new MigrationApp();
        test.ok( migration, "got new migation app" );

        test.ok( migration.parseCsv, "migration tests" );

        var realParsedCsv = { '0': [ 'a', 'b', 'c' ],
                              '1': [ ' foo\t', ' bar' ],
                              '2': [ '%*', ' ä', ' ßßß', ' ' ] };
        migration.parseCsv(__dirname+"/sample_csv.txt", function(parsed, err) {
          test.ifError(err);
          test.ok( parsed, "migration tests" );
          test.deepEqual( parsed, realParsedCsv, "migration tests" );

          test.done();

        });
    },

     "array to inverted dictionary": function ( test ) {
        test.expect( 3 );

        var migration = new MigrationApp();
        test.ok( migration, "got new migation app" );

        test.ok( migration.zipIt, "migration tests" );

        var mappings =  [[ 'firstname', 'name', 'First name' ],
            [ 'middlename', 'name', 'Middle name' ],
            [ 'lastname', 'name', 'Last name' ],
            [ 'twitter', 'links', 'Twitter' ],
            [ 'facebook', 'links', 'Facebook' ]];
        var attributes = [ 'John',
            'Peter',
            'Doe',
            '@funkyjohn',
            'John Doe'];

        var expect = {
          'name': {
            'First name': 'John',
            'Middle name': 'Peter',
            'Last name': 'Doe'},
          'links': {
            'Twitter': '@funkyjohn',
            'Facebook': 'John Doe'
          }};

        var inverted = migration.zipIt(mappings, attributes);

        test.deepEqual(inverted, expect, 'correctly inverted');

        test.done();
    },

    "import two people": function ( test ) {
        test.expect( 10 );

        var migration = new MigrationApp();
        test.ok( migration, "got new migation app" );

        test.ok( migration.doImport, "migration tests" );

        schema = 'person';
        mappings =
            [ [ 'title', 'name', 'Title' ],
              [ 'firstname', 'name', 'First name' ],
              [ 'middlename', 'name', 'Middle name' ],
              [ 'lastname', 'name', 'Last name' ],
              [ 'name_suffix', 'name', 'Name suffix' ],
              [ 'nickname', '', '' ],
              [ 'party', 'position', 'Party' ],
              [ 'state', '', '' ],
              [ 'district', '', '' ],
              [ 'in_office', '', '' ],
              [ 'gender', '', '' ],
              [ 'phone', 'contact', 'Phone' ],
              [ 'fax', 'contact', 'Fax' ],
              [ 'website', 'links', 'Website' ],
              [ 'webform', 'links', 'Webform' ],
              [ 'congress_office', '', '' ],
              [ 'bioguide_id', '', '' ],
              [ 'votesmart_id', '', '' ],
              [ 'fec_id', '', '' ],
              [ 'govtrack_id', '', '' ],
              [ 'crp_id', '', '' ],
              [ 'twitter_id', 'id', 'Twitter' ],
              [ 'congresspedia_url', 'links', 'congresspedia' ],
              [ 'youtube_url', 'links', 'Youtube' ],
              [ 'facebook_id', 'id', 'Facebook' ],
              [ 'official_rss', 'links', 'RSS' ],
              [ 'senate_class', '', '' ],
              [ 'birthdate', 'name', 'Birthdate' ] ];
        data = {'675':
          [ 'Sen',
            'John',
            'A.',
            'Doe',
            '',
            '',
            'R',
            'SD',
            'Junior Seat',
            '1',
            'M',
            '',
            '734-234-3545',
            'http://www.doe.senate.gov/',
            'http://www.doe.senate.gov/public/index.cfm/contact',
            'Office Building',
            '56456',
            '123',
            'S2SD00068',
            '400546',
            'N00044342',
            '@thedoe',
            'http://www.opencongress.org/wiki/John_Doe',
            'http://www.youtube.com/JohnDoe',
            '63002536261',
            '',
            'III',
            '02/04/1900' ],
        '676':
          [ 'Sen',
            'Peter',
            'L.',
            'Johnson',
            '',
            '',
            'D',
            'SD',
            'Junior Seat',
            '1',
            'M',
            '734-234-3547',
            '',
            'http://www.johnson.senate.gov/',
            'http://www.johnson.senate.gov/public/index.cfm/contact',
            'Office Building',
            '6564566',
            '3456',
            '34566634',
            '400546',
            'N2356546',
            '@mrsen',
            '',
            'http://www.youtube.com/PeterJohnsson',
            '63002536261',
            'http://www.test.co.uk/rssfeed',
            'II',
            '01/10/2010' ]};

        var that = this;

        migration.doImport(that.popit, schema, mappings, data, function(err, people) {
          test.ifError(err);
          test.equal(people.length, 2, 'two people in people set');

          var query = that.popit.model('Person').find();

          query.run(function(err, docs) {
            test.ifError(err);

            test.equal(docs.length, 2, 'two people in database');

            docs.forEach(function(doc) {
              test.equal(doc.links.length, 4, 'four links per person');
              test.equal(doc.contact_details.length, 1, 'one contact detail per person');
            })

            test.done();
          });
        });
    },

    "create organisation and position when importing a person": function ( test ) {
      test.expect( 5 );
      var migration = new MigrationApp();

      schema = 'person';
      mappings = [
        [ 'firstname', 'name', 'First name' ],
        [ 'lastname', 'name', 'Last name' ],
        [ 'party', 'position', 'Party' ] ];
      data = {'675':
        [ 'John',
          'Doe',
          'Aliens']};

      var that = this;

      migration.doImport(that.popit, schema, mappings, data, function(err, people, positions, organisations) {
        test.ifError(err);
        test.equal(organisations.length, 1, 'one organisation in organisations set');

        async.parallel([
          function(cb) {
            var query = that.popit.model('Position').find();
            query.run(function(err, docs) {
              test.equal(docs.length, 1, 'one position in database');
              cb(err);
            });
          },
          function(cb) {
            var query = that.popit.model('Organisation').find();
            query.run(function(err, docs) {
              test.equal(docs.length, 1, 'one organisation in database');
              cb(err);
            });
          }],
          function(err) {
            test.ifError(err);
            test.done();
          })
      });
    },

    "handling of duplicate slugs": function ( test ) {
      test.expect( 2 );

      var migration = new MigrationApp();

      schema = 'person';
      mappings =
        [ [ 'firstname', 'name', 'First name' ],
        [ 'lastname', 'name', 'Last name' ] ];
      data = {
        '675':
          [ 'John',
        'Doe' ],
        '676':
          [ 'John',
        'Doe'],
        '677':
          [ 'John',
        'Doe']};

      var that = this;

      migration.doImport(that.popit, schema, mappings, data, function(err, people){
        test.ifError(err, 'expect no error');
        test.equal(people.length, 3, 'three people in people set');

        var query = that.popit.model('Person').find().asc('name');

        test.done();
      });
    }
};
<|endoftext|>


<commit_before>require([
    "jQuery",
    "utils/storage",
    "utils/analytic",
    "utils/sharing",

    "core/state",
    "core/keyboard",
    "core/exercise",
    "core/quiz",
    "core/progress",
    "core/sidebar",
    "core/search"
], function($, storage, analytic, sharing, state, keyboard, exercise, quiz, progress, sidebar, search){
    $(document).ready(function() {
        var $book, bodyInnerWidth, pageWrapperWidth;
        $book = state.$book;

        // Init sidebar
        sidebar.init();

        // Load search
        search.init();

        // Init keyboard
        keyboard.init();

        if (state.githubId) {
            // Initialize storage
            storage.setBaseKey(state.githubId);

            // Star and watch count
            $.getJSON("https://api.github.com/repos/"+state.githubId)
            .done(function(repo) {
                $book.find(".count-star span").text(repo.stargazers_count);
                $book.find(".count-watch span").text(repo.subscribers_count);
            });
        }

        // Bind exercises
        exercise.init();
        quiz.init();

        // Bind sharing button
        sharing.init();

        // Show progress
        progress.show();

        // Focus on content
        $(".book-body").focus();

        // Move, if needed, right navigation control to allow scrolling.
        bodyInnerWidth = parseInt($('.body-inner').css('width'), 10);
        pageWrapperWidth = parseInt($('.page-wrapper').css('width'), 10);
        $('.navigation-next').css('margin-right', (bodyInnerWidth - pageWrapperWidth) + 'px');
    });
});
<commit_msg>Allow scroll in computers that put the navigation over scroll control. When the document is ready it will check the difference between the body-inner and the page-wrapper width to move the layer only this width allowing the user to scroll.<commit_after>require([
    "jQuery",
    "utils/storage",
    "utils/analytic",
    "utils/sharing",

    "core/state",
    "core/keyboard",
    "core/exercise",
    "core/quiz",
    "core/progress",
    "core/sidebar",
    "core/search"
], function($, storage, analytic, sharing, state, keyboard, exercise, quiz, progress, sidebar, search){
    function changeNavigationPosition()
    {
        var bodyInnerWidth, pageWrapperWidth;
        bodyInnerWidth = parseInt($('.body-inner').css('width'), 10);
        pageWrapperWidth = parseInt($('.page-wrapper').css('width'), 10);
        $('.navigation-next').css('margin-right', (bodyInnerWidth - pageWrapperWidth) + 'px');
    }
    $(window).on('resize', changeNavigationPosition);
    $(document).ready(function() {
        var $book;
        $book = state.$book;

        // Init sidebar
        sidebar.init();

        // Load search
        search.init();

        // Init keyboard
        keyboard.init();

        if (state.githubId) {
            // Initialize storage
            storage.setBaseKey(state.githubId);

            // Star and watch count
            $.getJSON("https://api.github.com/repos/"+state.githubId)
            .done(function(repo) {
                $book.find(".count-star span").text(repo.stargazers_count);
                $book.find(".count-watch span").text(repo.subscribers_count);
            });
        }

        // Bind exercises
        exercise.init();
        quiz.init();

        // Bind sharing button
        sharing.init();

        // Show progress
        progress.show();

        // Focus on content
        $(".book-body").focus();

        // Move, if needed, right navigation control to allow scrolling.
        changeNavigationPosition();
    });
});
<|endoftext|>


<commit_before>// THREEx.KeyboardState.js keep the current state of the keyboard.
// It is possible to query it at any time. No need of an event.
// This is particularly convenient in loop driven case, like in
// 3D demos or games.
//
// # Usage
//
// **Step 1**: Create the object
//
// ```var keyboard	= new THREEx.KeyboardState();```
//
// **Step 2**: Query the keyboard state
//
// This will return true if shift and A are pressed, false otherwise
//
// ```keyboard.pressed("shift+A")```
//
// **Step 3**: Stop listening to the keyboard
//
// ```keyboard.destroy()```
//
// NOTE: this library may be nice as standaline. independant from three.js
// - rename it keyboardForGame
//
// # Code
//

/** @namespace */
var THREEx	= THREEx 		|| {};

/**
 * - NOTE: it would be quite easy to push event-driven too
 *   - microevent.js for events handling
 *   - in this._onkeyChange, generate a string from the DOM event
 *   - use this as event name
*/
THREEx.KeyboardState	= function(domElement)
{
	this.domElement= domElement	|| document;
	// to store the current state
	this.keyCodes	= {};
	this.modifiers	= {};

	// create callback to bind/unbind keyboard events
	var _this	= this;
	this._onKeyDown	= function(event){ _this._onKeyChange(event)	}
	this._onKeyUp	= function(event){ _this._onKeyChange(event)	}

	// bind keyEvents
	this.domElement.addEventListener("keydown", this._onKeyDown, false);
	this.domElement.addEventListener("keyup", this._onKeyUp, false);
}

/**
 * To stop listening of the keyboard events
*/
THREEx.KeyboardState.prototype.destroy	= function()
{
	// unbind keyEvents
	this.domElement.removeEventListener("keydown", this._onKeyDown, false);
	this.domElement.removeEventListener("keyup", this._onKeyUp, false);
}

THREEx.KeyboardState.MODIFIERS	= ['shift', 'ctrl', 'alt', 'meta'];
THREEx.KeyboardState.ALIAS	= {
	'left'		: 37,
	'up'		: 38,
	'right'		: 39,
	'down'		: 40,
	'space'		: 32,
	'pageup'	: 33,
	'pagedown'	: 34,
	'tab'		: 9,
	'escape'	: 27
};

/**
 * to process the keyboard dom event
*/
THREEx.KeyboardState.prototype._onKeyChange	= function(event)
{
	// log to debug
	//console.log("onKeyChange", event, event.keyCode, event.shiftKey, event.ctrlKey, event.altKey, event.metaKey)

	// update this.keyCodes
	var keyCode		= event.keyCode
	var pressed		= event.type === 'keydown' ? true : false
	this.keyCodes[keyCode]	= pressed
	// update this.modifiers
	this.modifiers['shift']	= event.shiftKey
	this.modifiers['ctrl']	= event.ctrlKey
	this.modifiers['alt']	= event.altKey
	this.modifiers['meta']	= event.metaKey
}

/**
 * query keyboard state to know if a key is pressed of not
 *
 * @param {String} keyDesc the description of the key. format : modifiers+key e.g shift+A
 * @returns {Boolean} true if the key is pressed, false otherwise
*/
THREEx.KeyboardState.prototype.pressed	= function(keyDesc){
	var keys	= keyDesc.split("+");
	for(var i = 0; i < keys.length; i++){
		var key		= keys[i]
		var pressed	= false
		if( THREEx.KeyboardState.MODIFIERS.indexOf( key ) !== -1 ){
			pressed	= this.modifiers[key];
		}else if( Object.keys(THREEx.KeyboardState.ALIAS).indexOf( key ) != -1 ){
			pressed	= this.keyCodes[ THREEx.KeyboardState.ALIAS[key] ];
		}else {
			pressed	= this.keyCodes[key.toUpperCase().charCodeAt(0)]
		}
		if( !pressed)	return false;
	};
	return true;
}

/**
 * return true if an event match a keyDesc
 * @param  {KeyboardEvent} event   keyboard event
 * @param  {String} keyDesc string description of the key
 * @return {Boolean}         true if the event match keyDesc, false otherwise
 */
THREEx.KeyboardState.prototype.eventMatches = function(event, keyDesc) {
	var aliases	= THREEx.KeyboardState.ALIAS
	var aliasKeys	= Object.keys(aliases)
	var keys	= keyDesc.split("+")
	// log to debug
	// console.log("eventMatches", event, event.keyCode, event.shiftKey, event.ctrlKey, event.altKey, event.metaKey)
	for(var i = 0; i < keys.length; i++){
		var key		= keys[i];
		var pressed	= false;
		if( key === 'shift' ){
			pressed	= (event.shiftKey	? true : false)
		}else if( key === 'ctrl' ){
			pressed	= (event.ctrlKey	? true : false)
		}else if( key === 'alt' ){
			pressed	= (event.altKey		? true : false)
		}else if( key === 'meta' ){
			pressed	= (event.metaKey	? true : false)
		}else if( aliasKeys.indexOf( key ) !== -1 ){
			pressed	= (event.keyCode === aliases[key] ? true : false);
		}else if( event.keyCode === key.toUpperCase().charCodeAt(0) ){
			pressed	= true;
		}
		if( !pressed )	return false;
	}
	return true;
}

<commit_msg>added window blur support<commit_after>// THREEx.KeyboardState.js keep the current state of the keyboard.
// It is possible to query it at any time. No need of an event.
// This is particularly convenient in loop driven case, like in
// 3D demos or games.
//
// # Usage
//
// **Step 1**: Create the object
//
// ```var keyboard	= new THREEx.KeyboardState();```
//
// **Step 2**: Query the keyboard state
//
// This will return true if shift and A are pressed, false otherwise
//
// ```keyboard.pressed("shift+A")```
//
// **Step 3**: Stop listening to the keyboard
//
// ```keyboard.destroy()```
//
// NOTE: this library may be nice as standaline. independant from three.js
// - rename it keyboardForGame
//
// # Code
//

/** @namespace */
var THREEx	= THREEx 		|| {};

/**
 * - NOTE: it would be quite easy to push event-driven too
 *   - microevent.js for events handling
 *   - in this._onkeyChange, generate a string from the DOM event
 *   - use this as event name
*/
THREEx.KeyboardState	= function(domElement)
{
	this.domElement= domElement	|| document;
	// to store the current state
	this.keyCodes	= {};
	this.modifiers	= {};

	// create callback to bind/unbind keyboard events
	var _this	= this;
	this._onKeyDown	= function(event){ _this._onKeyChange(event)	}
	this._onKeyUp	= function(event){ _this._onKeyChange(event)	}

	// bind keyEvents
	this.domElement.addEventListener("keydown", this._onKeyDown, false);
	this.domElement.addEventListener("keyup", this._onKeyUp, false);

	// create callback to bind/unbind window blur event
	this._onBlur = function(){
		for(var prop in self.keyCodes)  self.keyCodes[prop] = false;
		for(var prop in self.modifiers)  self.modifiers[prop] = false;
	}

	// bind window blur
	window.addEventListener("blur", this._onBlur, false);
}

/**
 * To stop listening of the keyboard events
*/
THREEx.KeyboardState.prototype.destroy	= function()
{
	// unbind keyEvents
	this.domElement.removeEventListener("keydown", this._onKeyDown, false);
	this.domElement.removeEventListener("keyup", this._onKeyUp, false);

	// unbind window blur event
	window.removeEventListener("blur", this._onBlur, false);
}

THREEx.KeyboardState.MODIFIERS	= ['shift', 'ctrl', 'alt', 'meta'];
THREEx.KeyboardState.ALIAS	= {
	'left'		: 37,
	'up'		: 38,
	'right'		: 39,
	'down'		: 40,
	'space'		: 32,
	'pageup'	: 33,
	'pagedown'	: 34,
	'tab'		: 9,
	'escape'	: 27
};

/**
 * to process the keyboard dom event
*/
THREEx.KeyboardState.prototype._onKeyChange	= function(event)
{
	// log to debug
	//console.log("onKeyChange", event, event.keyCode, event.shiftKey, event.ctrlKey, event.altKey, event.metaKey)

	// update this.keyCodes
	var keyCode		= event.keyCode
	var pressed		= event.type === 'keydown' ? true : false
	this.keyCodes[keyCode]	= pressed
	// update this.modifiers
	this.modifiers['shift']	= event.shiftKey
	this.modifiers['ctrl']	= event.ctrlKey
	this.modifiers['alt']	= event.altKey
	this.modifiers['meta']	= event.metaKey
}

/**
 * query keyboard state to know if a key is pressed of not
 *
 * @param {String} keyDesc the description of the key. format : modifiers+key e.g shift+A
 * @returns {Boolean} true if the key is pressed, false otherwise
*/
THREEx.KeyboardState.prototype.pressed	= function(keyDesc){
	var keys	= keyDesc.split("+");
	for(var i = 0; i < keys.length; i++){
		var key		= keys[i]
		var pressed	= false
		if( THREEx.KeyboardState.MODIFIERS.indexOf( key ) !== -1 ){
			pressed	= this.modifiers[key];
		}else if( Object.keys(THREEx.KeyboardState.ALIAS).indexOf( key ) != -1 ){
			pressed	= this.keyCodes[ THREEx.KeyboardState.ALIAS[key] ];
		}else {
			pressed	= this.keyCodes[key.toUpperCase().charCodeAt(0)]
		}
		if( !pressed)	return false;
	};
	return true;
}

/**
 * return true if an event match a keyDesc
 * @param  {KeyboardEvent} event   keyboard event
 * @param  {String} keyDesc string description of the key
 * @return {Boolean}         true if the event match keyDesc, false otherwise
 */
THREEx.KeyboardState.prototype.eventMatches = function(event, keyDesc) {
	var aliases	= THREEx.KeyboardState.ALIAS
	var aliasKeys	= Object.keys(aliases)
	var keys	= keyDesc.split("+")
	// log to debug
	// console.log("eventMatches", event, event.keyCode, event.shiftKey, event.ctrlKey, event.altKey, event.metaKey)
	for(var i = 0; i < keys.length; i++){
		var key		= keys[i];
		var pressed	= false;
		if( key === 'shift' ){
			pressed	= (event.shiftKey	? true : false)
		}else if( key === 'ctrl' ){
			pressed	= (event.ctrlKey	? true : false)
		}else if( key === 'alt' ){
			pressed	= (event.altKey		? true : false)
		}else if( key === 'meta' ){
			pressed	= (event.metaKey	? true : false)
		}else if( aliasKeys.indexOf( key ) !== -1 ){
			pressed	= (event.keyCode === aliases[key] ? true : false);
		}else if( event.keyCode === key.toUpperCase().charCodeAt(0) ){
			pressed	= true;
		}
		if( !pressed )	return false;
	}
	return true;
}

<|endoftext|>


<commit_before>define(["Ti/_/declare", "Ti/_/UI/FontWidget", "Ti/_/dom", "Ti/_/css", "Ti/_/style", "Ti/_/lang", "Ti/Locale", "Ti/UI"],
	function(declare, FontWidget, dom, css, style, lang, Locale, UI) {

	var serviceReply = {
		onsuccess: function(){},
		onfail:    function(){
			alert('Request failed');
		}
	};

	/**
	 * ReplaceAll by Fagner Brack (MIT Licensed)
	 * Replaces all occurrences of a substring in a string
	 */

	String.prototype.replaceAll = function(token, newToken, ignoreCase) {
	    var str, i = -1, _token;
	    if((str = this.toString()) && typeof token === "string") {
	        _token = ignoreCase === true? token.toLowerCase() : undefined;
	        while((i = (
	            _token !== undefined?
	                str.toLowerCase().indexOf(
	                            _token,
	                            i >= 0? i + newToken.length : 0
	                ) : str.indexOf(
	                            token,
	                            i >= 0? i + newToken.length : 0
	                )
	        )) !== -1 ) {
	            str = str.substring(0, i)
	                    .concat(newToken)
	                    .concat(str.substring(i + token.length));
	        }
	    }
	return str;
	};

	if(! window.autoLinkClick){
		window.autoLinkClick = function (e, linkType, link){

			switch (linkType) {
				case "url":
					var service1 = new tizen.ApplicationService('http://tizen.org/appcontrol/operation/default', link);
					tizen.application.launchService(
						service1,
					    'org.tizen.browser',
						function() {
							console.log("Launch service succeeded");
						},
						function(e) {
							console.log("Launch service failed. Reason : " + e.name);
						},
					    serviceReply
					);
					e.stopPropagation();
					break;
				case "email":
					var service1 = new tizen.ApplicationService('http://tizen.org/appcontrol/operation/default', 'mailto:test@example.com');
					tizen.application.launchService(
						service1,
					    'email-composer-efl',
						function() {
							alert("Launch service succeeded");
						},
						function(e) {
							alert("Launch service failed. Reason : " + e.name);
						},
					    serviceReply
					    );
					e.stopPropagation();
					break;
				case "number":
					var service1 = new tizen.ApplicationService('http://tizen.org/appcontrol/operation/call', 'tel:123-123-1234');
					tizen.application.launchService(
						service1,
					    'org.tizen.phone',
						function() {
							alert("Launch service succeeded");
						},
						function(e) {
							alert("Launch service failed. Reason : " + e.name);
						},
					    serviceReply
					    );
					e.stopPropagation();
					break;
				default:
					throw new Exception("undefined link type");
			}

	  	}
	}

	var setStyle = style.set,
		unitize = dom.unitize,
		tabStop = 2,

		arrayRemoveDuplicates = function(var_array){
			var_array.sort();
			var i = 0;
			var_array[0] = var_array[0].trim().replace(/<|>/, '');
			while(i < (var_array.length - 1)){
				var_array[i + 1] = var_array[i + 1].trim().replace(/<|>/, '');
				if(var_array[i] == var_array[i + 1]){
					var_array.splice(i + 1, 1);
				} else {
					i++;
				}
			}
		},

		linkifyFunctions = {
			linkifyUrls : function(text_arg){
				var reg = /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?/ig,
				matches = text_arg.match(reg);
				if(matches != null){
					arrayRemoveDuplicates(matches);
					for(var i = 0, l = matches.length; i < l; i++){
						var replace_text =  '' + matches[i] + '';
						text_arg = text_arg.replaceAll(matches[i], replace_text, false);
					}
				}
				return text_arg;
			},

			linkifyEmail : function(text_arg){
				var reg = /(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/g,
				matches = text_arg.match(reg);
				if(matches != null){
					arrayRemoveDuplicates(matches);
					for(var i = 0, l = matches.length; i < l; i++){
						var replace_text = '' + matches[i] + '';
						text_arg = text_arg.replaceAll(matches[i], replace_text, false);
					}
				}
				return text_arg;
			},

			linkifyPhoneNumber : function(text_arg){
				var reg_alone = /^((\(?\+?[0-9]*\)?)?(\(?[0-9\-]\)?([ ][0-9\-\(\)])?)+)$/g;

				if(reg_alone.test(text_arg)){
					text_arg = '' + text_arg + '';
				} else {
					var reg = /(^(\(?\+?[0-9]*\)?)?(\(?[0-9\-]\)?([ ][0-9\-\(\)])?)+([ ]|<))|(([ ]|>)(\(?\+?[0-9]*\)?)?(\(?[0-9\-]\)?([ ][0-9\-\(\)])?)+([ ]|<))|((([ ]|>)(\(?\+?[0-9]*\)?)?(\(?[0-9\-]\)?([ ][0-9\-\(\)])?)+)$)/g,
					matches = text_arg.match(reg);
					if(matches != null){
						arrayRemoveDuplicates(matches);
						for(var i = 0, l = matches.length; i < l; i++){
							var replace_text = '' + matches[i] + '';
							text_arg = text_arg.replaceAll(matches[i], replace_text, false);
						}
					}
				}
				return text_arg;
			}
		},

		textPost = {
			post: "_setText"
		};

	return declare("Ti.UI.Label", FontWidget, {

		constructor: function() {
			this._add(this._textContainer = UI.createView({
				width: UI.INHERIT,
				height: UI.SIZE,
				center: {y: "50%"}
			}));

			var self = this,
				textContainerDomNode = this._textContainerDomNode = this._textContainer.domNode;
			self._textContainer._getContentSize = function(width, height) {
				var text = self._textContainerDomNode.innerHTML,
					measuredSize = self._measureText(text, textContainerDomNode, self._hasSizeWidth() ? void 0 : width);
				return {
					width: measuredSize.width,
					height: measuredSize.height
				};
			};

			this._addStyleableDomNode(textContainerDomNode);
			this.wordWrap = true;
		},

		_defaultWidth: UI.SIZE,

		_defaultHeight: UI.SIZE,

		_linkifyText : function(textArg){

			var	functions = [];
			switch(this.autoLink){
				case UI.Tizen.LINKIFY_EMAIL_ADDRESSES:
					functions.push('linkifyEmail');
					break;
				case UI.Tizen.LINKIFY_WEB_URLS:
					functions.push('linkifyUrl');
					break;
				case UI.Tizen.LINKIFY_PHONE_NUMBERS:
					functions.push('linkifyPhoneNumber');
					break;
				case UI.Tizen.LINKIFY_ALL:
					functions.push('linkifyUrl');
					functions.push('linkifyEmail');
					functions.push('linkifyPhoneNumber');
					break;
				default:
					return textArg;
			}

			for(var i = 0, l = functions.length; i < l; i++){
				textArg = linkifyFunctions[functions[i]](textArg);
			}

			return textArg;
		},

		_getText: function() {
			var i,
				lineStartIndex = 0,
				currentIndex = 0,
				currentTabIndex,
				text = Locale._getString(this.textid, this.text);

			// Handle null, undefined, etc edge case
			if (text === void 0) {
				return "";
			}
			text += "";

			// Convert \t and \n to  's and
's
			while (currentIndex < text.length) {
				if (text[currentIndex] === '\t') {
					var tabSpaces = "",
						numSpacesToInsert = tabStop - (currentTabIndex) % tabStop;
					for (i = 0; i < numSpacesToInsert; i++) {
						tabSpaces += " ";
					}
					text = text.substring(0, currentIndex) + tabSpaces + text.substring(currentIndex + 1);
					currentIndex += tabSpaces.length;
					currentTabIndex += numSpacesToInsert;
				} else if (text[currentIndex] === '\n') {
					text = text.substring(0, currentIndex) + "
" + text.substring(currentIndex + 1);
					currentIndex += 5;
					lineStartIndex = currentIndex;
					currentTabIndex = 0;
				} else {
					currentIndex++;
					currentTabIndex++;
				}
			}

			text.match(/
$/) && (text += " ");
			return text;
		},

		_setText: function() {
			this._textContainerDomNode.innerHTML = this._linkifyText(this._getText());
			this._hasSizeDimensions() && this._triggerLayout();
		},

		_setTextShadow: function() {
			var shadowColor = this.shadowColor && this.shadowColor !== "" ? this.shadowColor : void 0;
			setStyle(
				this._textContainerDomNode,
				"textShadow",
				this.shadowOffset || shadowColor
					? (this.shadowOffset ? unitize(this.shadowOffset.x) + " " + unitize(this.shadowOffset.y) : "0px 0px") + " 0.1em " + lang.val(shadowColor,"black")
					: ""
			);
		},

		properties: {
			ellipsize: {
				set: function(value) {
					setStyle(this._textContainerDomNode,"textOverflow", !!value ? "ellipsis" : "clip");
					return value;
				},
				value: true
			},
			html: {
				set: function(value) {
					this._textContainerDomNode.innerHTML = value;
					this._hasSizeDimensions() && this._triggerLayout();
					return value;
				}
			},
			shadowColor: {
				post: function() {
					this._setTextShadow();
				}
			},
			shadowOffset: {
				post: function() {
					this._setTextShadow();
				}
			},
			text: textPost,
			textAlign: {
				set: function(value) {
					setStyle(this._textContainerDomNode, "textAlign", /(center|right)/.test(value) ? value : "left");
					return value;
				}
			},
			textid: textPost,
			wordWrap: {
				set: function(value) {
					setStyle(this._textContainerDomNode, "whiteSpace", !!value ? "normal" : "nowrap");
					return value;
				}
			},
			verticalAlign: {
				set: function(value) {
					var top,
						bottom,
						center = this.center || {},
						textContainer = this._textContainer;
					switch(value) {
						case UI.TEXT_VERTICAL_ALIGNMENT_TOP: top = 0; break;
						case UI.TEXT_VERTICAL_ALIGNMENT_CENTER: center.y = "50%"; break;
						case UI.TEXT_VERTICAL_ALIGNMENT_BOTTOM: bottom = 0; break;
					}
					textContainer.top = top;
					textContainer.center = center;
					textContainer.bottom = bottom;
					return value;
				},
				value: UI.TEXT_VERTICAL_ALIGNMENT_CENTER
			},

			autoLink: textPost
		}

	});

});<commit_msg>UI.Label fixed<commit_after>define(["Ti/_/declare", "Ti/_/UI/FontWidget", "Ti/_/dom", "Ti/_/css", "Ti/_/style", "Ti/_/lang", "Ti/Locale", "Ti/UI"],
	function(declare, FontWidget, dom, css, style, lang, Locale, UI) {

	var serviceReply = {
		onsuccess: function(){},
		onfail:    function(){
			alert('Request failed');
		}
	};

	/**
	 * ReplaceAll by Fagner Brack (MIT Licensed)
	 * Replaces all occurrences of a substring in a string
	 */

	String.prototype.replaceAll = function(token, newToken, ignoreCase) {
	    var str, i = -1, _token;
	    if((str = this.toString()) && typeof token === "string") {
	        _token = ignoreCase === true? token.toLowerCase() : undefined;
	        while((i = (
	            _token !== undefined?
	                str.toLowerCase().indexOf(
	                            _token,
	                            i >= 0? i + newToken.length : 0
	                ) : str.indexOf(
	                            token,
	                            i >= 0? i + newToken.length : 0
	                )
	        )) !== -1 ) {
	            str = str.substring(0, i)
	                    .concat(newToken)
	                    .concat(str.substring(i + token.length));
	        }
	    }
	return str;
	};

	if(! window.autoLinkClick){
		window.autoLinkClick = function (e, linkType, link){

			switch (linkType) {
				case "url":
					var service1 = new tizen.ApplicationService('http://tizen.org/appcontrol/operation/default', link);
					tizen.application.launchService(
						service1,
					    'org.tizen.browser',
						function() {
							console.log("Launch service succeeded");
						},
						function(e) {
							console.log("Launch service failed. Reason : " + e.name);
						},
					    serviceReply
					);
					e.stopPropagation();
					break;
				case "email":
					var service1 = new tizen.ApplicationService('http://tizen.org/appcontrol/operation/default', 'mailto:test@example.com');
					tizen.application.launchService(
						service1,
					    'email-composer-efl',
						function() {
							alert("Launch service succeeded");
						},
						function(e) {
							alert("Launch service failed. Reason : " + e.name);
						},
					    serviceReply
					    );
					e.stopPropagation();
					break;
				case "number":
					var service1 = new tizen.ApplicationService('http://tizen.org/appcontrol/operation/call', 'tel:123-123-1234');
					tizen.application.launchService(
						service1,
					    'org.tizen.phone',
						function() {
							alert("Launch service succeeded");
						},
						function(e) {
							alert("Launch service failed. Reason : " + e.name);
						},
					    serviceReply
					    );
					e.stopPropagation();
					break;
				default:
					throw new Exception("undefined link type");
			}

	  	}
	}

	var setStyle = style.set,
		unitize = dom.unitize,
		tabStop = 2,

		arrayRemoveDuplicates = function(var_array){
			var_array.sort();
			var i = 0;
			var_array[0] = var_array[0].trim().replace(/<|>/, '');
			while(i < (var_array.length - 1)){
				var_array[i + 1] = var_array[i + 1].trim().replace(/<|>/, '');
				if(var_array[i] == var_array[i + 1]){
					var_array.splice(i + 1, 1);
				} else {
					i++;
				}
			}
		},

		linkifyFunctions = {
			linkifyUrl : function(text_arg){
				var reg = /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?/ig,
				matches = text_arg.match(reg);
				if(matches != null){
					arrayRemoveDuplicates(matches);
					for(var i = 0, l = matches.length; i < l; i++){
						var replace_text =  '' + matches[i] + '';
						text_arg = text_arg.replaceAll(matches[i], replace_text, false);
					}
				}
				return text_arg;
			},

			linkifyEmail : function(text_arg){
				var reg = /(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/g,
				matches = text_arg.match(reg);
				if(matches != null){
					arrayRemoveDuplicates(matches);
					for(var i = 0, l = matches.length; i < l; i++){
						var replace_text = '' + matches[i] + '';
						text_arg = text_arg.replaceAll(matches[i], replace_text, false);
					}
				}
				return text_arg;
			},

			linkifyPhoneNumber : function(text_arg){
				var reg_alone = /^((\(?\+?[0-9]*\)?)?(\(?[0-9\-]\)?([ ][0-9\-\(\)])?)+)$/g;

				if(reg_alone.test(text_arg)){
					text_arg = '' + text_arg + '';
				} else {
					var reg = /(^(\(?\+?[0-9]*\)?)?(\(?[0-9\-]\)?([ ][0-9\-\(\)])?)+([ ]|<))|(([ ]|>)(\(?\+?[0-9]*\)?)?(\(?[0-9\-]\)?([ ][0-9\-\(\)])?)+([ ]|<))|((([ ]|>)(\(?\+?[0-9]*\)?)?(\(?[0-9\-]\)?([ ][0-9\-\(\)])?)+)$)/g,
					matches = text_arg.match(reg);
					if(matches != null){
						arrayRemoveDuplicates(matches);
						for(var i = 0, l = matches.length; i < l; i++){
							var replace_text = '' + matches[i] + '';
							text_arg = text_arg.replaceAll(matches[i], replace_text, false);
						}
					}
				}
				return text_arg;
			}
		},

		textPost = {
			post: "_setText"
		};

	return declare("Ti.UI.Label", FontWidget, {

		constructor: function() {
			this._add(this._textContainer = UI.createView({
				width: UI.INHERIT,
				height: UI.SIZE,
				center: {y: "50%"}
			}));

			var self = this,
				textContainerDomNode = this._textContainerDomNode = this._textContainer.domNode;
			self._textContainer._getContentSize = function(width, height) {
				var text = self._textContainerDomNode.innerHTML,
					measuredSize = self._measureText(text, textContainerDomNode, self._hasSizeWidth() ? void 0 : width);
				return {
					width: measuredSize.width,
					height: measuredSize.height
				};
			};

			this._addStyleableDomNode(textContainerDomNode);
			this.wordWrap = true;
		},

		_defaultWidth: UI.SIZE,

		_defaultHeight: UI.SIZE,

		_linkifyText : function(textArg){

			var	functions = [];
			switch(this.autoLink){
				case UI.Tizen.LINKIFY_EMAIL_ADDRESSES:
					functions.push('linkifyEmail');
					break;
				case UI.Tizen.LINKIFY_WEB_URLS:
					functions.push('linkifyUrl');
					break;
				case UI.Tizen.LINKIFY_PHONE_NUMBERS:
					functions.push('linkifyPhoneNumber');
					break;
				case UI.Tizen.LINKIFY_ALL:
					functions.push('linkifyUrl');
					functions.push('linkifyEmail');
					functions.push('linkifyPhoneNumber');
					break;
				default:
					return textArg;
			}

			for(var i = 0, l = functions.length; i < l; i++){
				textArg = linkifyFunctions[functions[i]](textArg);
			}

			return textArg;
		},

		_getText: function() {
			var i,
				lineStartIndex = 0,
				currentIndex = 0,
				currentTabIndex,
				text = Locale._getString(this.textid, this.text);

			// Handle null, undefined, etc edge case
			if (text === void 0) {
				return "";
			}
			text += "";

			// Convert \t and \n to  's and
's
			while (currentIndex < text.length) {
				if (text[currentIndex] === '\t') {
					var tabSpaces = "",
						numSpacesToInsert = tabStop - (currentTabIndex) % tabStop;
					for (i = 0; i < numSpacesToInsert; i++) {
						tabSpaces += " ";
					}
					text = text.substring(0, currentIndex) + tabSpaces + text.substring(currentIndex + 1);
					currentIndex += tabSpaces.length;
					currentTabIndex += numSpacesToInsert;
				} else if (text[currentIndex] === '\n') {
					text = text.substring(0, currentIndex) + "
" + text.substring(currentIndex + 1);
					currentIndex += 5;
					lineStartIndex = currentIndex;
					currentTabIndex = 0;
				} else {
					currentIndex++;
					currentTabIndex++;
				}
			}

			text.match(/
$/) && (text += " ");
			return text;
		},

		_setText: function() {
			this._textContainerDomNode.innerHTML = this._linkifyText(this._getText());
			this._hasSizeDimensions() && this._triggerLayout();
		},

		_setTextShadow: function() {
			var shadowColor = this.shadowColor && this.shadowColor !== "" ? this.shadowColor : void 0;
			setStyle(
				this._textContainerDomNode,
				"textShadow",
				this.shadowOffset || shadowColor
					? (this.shadowOffset ? unitize(this.shadowOffset.x) + " " + unitize(this.shadowOffset.y) : "0px 0px") + " 0.1em " + lang.val(shadowColor,"black")
					: ""
			);
		},

		properties: {
			ellipsize: {
				set: function(value) {
					setStyle(this._textContainerDomNode,"textOverflow", !!value ? "ellipsis" : "clip");
					return value;
				},
				value: true
			},
			html: {
				set: function(value) {
					this._textContainerDomNode.innerHTML = value;
					this._hasSizeDimensions() && this._triggerLayout();
					return value;
				}
			},
			shadowColor: {
				post: function() {
					this._setTextShadow();
				}
			},
			shadowOffset: {
				post: function() {
					this._setTextShadow();
				}
			},
			text: textPost,
			textAlign: {
				set: function(value) {
					setStyle(this._textContainerDomNode, "textAlign", /(center|right)/.test(value) ? value : "left");
					return value;
				}
			},
			textid: textPost,
			wordWrap: {
				set: function(value) {
					setStyle(this._textContainerDomNode, "whiteSpace", !!value ? "normal" : "nowrap");
					return value;
				}
			},
			verticalAlign: {
				set: function(value) {
					var top,
						bottom,
						center = this.center || {},
						textContainer = this._textContainer;
					switch(value) {
						case UI.TEXT_VERTICAL_ALIGNMENT_TOP: top = 0; break;
						case UI.TEXT_VERTICAL_ALIGNMENT_CENTER: center.y = "50%"; break;
						case UI.TEXT_VERTICAL_ALIGNMENT_BOTTOM: bottom = 0; break;
					}
					textContainer.top = top;
					textContainer.center = center;
					textContainer.bottom = bottom;
					return value;
				},
				value: UI.TEXT_VERTICAL_ALIGNMENT_CENTER
			},

			autoLink: textPost
		}

	});

});<|endoftext|>


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

/**
 * The "add a folder" dialog
 */
var FilterModal = Modal.extend({

    type: "filter",
    closeText: "Save",

    events: {
        //'submit form': 'save',
        'click .dialog_footer a' : 'call',
        'click .insert-member' : 'open_select_member_selector'
    },

    buttons: [
        { text: "OK", method: "save" },
        { text: "Cancel", method: "close" }
    ],

    message: "",

    expression_text: function() {
        var c = "<form class='form-group-inline' data-action='cad' id='custom_filter'>
";
        if (this.expressionType == "Order") {
            c += "
Sort Type: <select id='fun'><option>ASC</option><option>BASC</option><option>DESC</option><option>BDESC</option> </select>
";
        }
        c += "
" + this.expressionType + " MDX Expression:
" +
             "

" +
             "
" +
            "Insert Member</form>";
        return c;
    },

    expression: " ",
    expressonType: "",

    initialize: function(args) {
        var self = this;
        this.id = _.uniqueId('filter-modal-');
        this.workspace = args.workspace;
        this.axis = args.axis;
        this.query = args.query;
        this.success = args.success;
        this.expression = args.expression;
        this.expressionType = args.expressionType;
        _.bindAll(this, "save", "expression_text");

        _.extend(this.options, {
            title: "Custom " + this.expressionType + " for " + this.axis
        });

        this.message = this.expression_text(this.expressionType);

        this.bind( 'open', function( ) {
                    //$(this.el).find('textarea').val('').val(self.expression);
            this.editor = ace.edit(this.id);
            this.editor.setShowPrintMargin(false);
            this.editor.setFontSize(11);
        });

        // fix event listening in IE < 9
        if(isIE && isIE < 9) {
            $(this.el).find('form').on('submit', this.save);
        }

    },

    save: function( event ) {
        event.preventDefault( );
        var self = this;
        this.expression = $(this.el).find('textarea').val();

        var alert_msg = "";
        if (typeof this.expression == "undefined" || !this.expression || this.expression === "") {
            alert_msg += "You have to enter a MDX expression for the " + this.expressionType + " function! ";
            alert(alert_msg);
        } else {
            if (self.expressionType == "Order") {
                var sortOrder = $('#fun').val();
                self.success(sortOrder, this.expression);
            } else {
                self.success(this.expression);
            }
            this.close();
        }

        return false;
    },

    error: function() {
        $(this.el).find('dialog_body')
            .html("Could not add new folder");
    },

    /**
     * Open the select member dialog
     * @param event
     */
    open_select_member_selector: function(event){
        event.preventDefault();
        var dimension = {
            val: this.$el.find('#cms-dimension option:selected').val(),
            txt: this.$el.find('#cms-dimension option:selected').text(),
            dataDimension: this.$el.find('#cms-dimension option:selected').data('dimension'),
            dataType: this.$el.find('#cms-dimension option:selected').data('type')
        };
        var editor = ace.edit(this.id);
        var that = this;

         (new ParentMemberSelectorModal({
                dialog: this,
                workspace: this.workspace,
                cube: this.workspace.selected_cube,
                dimensions: Saiku.session.sessionworkspace.cube[this.workspace.selected_cube].get('data').dimensions,
                selectDimension: dimension.val,
                dimension: dimension.dataDimension,
                hierarchy: dimension.txt,
                uniqueName: this.pmUniqueName,
                lastLevel: this.pmLevel,
                breadcrumbs: this.pmBreadcrumbs,
                select_type: "select_member",
                selected_member: this.selected_member,
                close_callback: function(args){
                    var e = editor;
                    that.close_select_modal(e, args);
                }
            })).render().open();

            this.$el.parents('.ui-dialog').find('.ui-dialog-title').text('Custom Filter');

    },

    /**
     * Callback to update the editor with the selected member.
     * @param editor
     * @param n
     */
    close_select_modal: function(editor, n){
        editor.insert(n);
    }

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

/**
 * The "add a folder" dialog
 */
var FilterModal = Modal.extend({

    type: "filter",
    closeText: "Save",

    events: {
        //'submit form': 'save',
        'click .dialog_footer a' : 'call',
        'click .insert-member' : 'open_select_member_selector'
    },

    buttons: [
        { text: "OK", method: "save" },
        { text: "Cancel", method: "close" }
    ],

    message: "",

    expression_text: function() {
        var c = "<form class='form-group-inline' data-action='cad' id='custom_filter'>
";
        if (this.expressionType == "Order") {
            c += "
Sort Type: <select id='fun'><option>ASC</option><option>BASC</option><option>DESC</option><option>BDESC</option> </select>
";
        }
        c += "
" + this.expressionType + " MDX Expression:
" +
             "

" +
             "
" +
            "Insert Member</form>";
        return c;
    },

    expression: " ",
    expressonType: "",

    initialize: function(args) {
        var self = this;
        this.id = _.uniqueId('filter-modal-');
        this.workspace = args.workspace;
        this.axis = args.axis;
        this.query = args.query;
        this.success = args.success;
        this.expression = args.expression;
        this.expressionType = args.expressionType;
        _.bindAll(this, "save", "expression_text");

        _.extend(this.options, {
            title: "Custom " + this.expressionType + " for " + this.axis
        });

        this.message = this.expression_text(this.expressionType);

        this.bind( 'open', function( ) {
            this.editor = ace.edit(this.id);
            this.editor.setValue(self.expression);
            this.editor.setShowPrintMargin(false);
            this.editor.setFontSize(11);
        });

        // fix event listening in IE < 9
        if(isIE && isIE < 9) {
            $(this.el).find('form').on('submit', this.save);
        }

    },

    save: function( event ) {
        event.preventDefault( );
        var self = this;
        this.expression = $(this.el).find('textarea').val();

        var alert_msg = "";
        if (typeof this.expression == "undefined" || !this.expression || this.expression === "") {
            alert_msg += "You have to enter a MDX expression for the " + this.expressionType + " function! ";
            alert(alert_msg);
        } else {
            if (self.expressionType == "Order") {
                var sortOrder = $('#fun').val();
                self.success(sortOrder, this.expression);
            } else {
                self.success(this.expression);
            }
            this.close();
        }

        return false;
    },

    error: function() {
        $(this.el).find('dialog_body')
            .html("Could not add new folder");
    },

    /**
     * Open the select member dialog
     * @param event
     */
    open_select_member_selector: function(event){
        event.preventDefault();
        var dimension = {
            val: this.$el.find('#cms-dimension option:selected').val(),
            txt: this.$el.find('#cms-dimension option:selected').text(),
            dataDimension: this.$el.find('#cms-dimension option:selected').data('dimension'),
            dataType: this.$el.find('#cms-dimension option:selected').data('type')
        };
        var editor = ace.edit(this.id);
        var that = this;

         (new ParentMemberSelectorModal({
                dialog: this,
                workspace: this.workspace,
                cube: this.workspace.selected_cube,
                dimensions: Saiku.session.sessionworkspace.cube[this.workspace.selected_cube].get('data').dimensions,
                selectDimension: dimension.val,
                dimension: dimension.dataDimension,
                hierarchy: dimension.txt,
                uniqueName: this.pmUniqueName,
                lastLevel: this.pmLevel,
                breadcrumbs: this.pmBreadcrumbs,
                select_type: "select_member",
                selected_member: this.selected_member,
                close_callback: function(args){
                    var e = editor;
                    that.close_select_modal(e, args);
                }
            })).render().open();

            this.$el.parents('.ui-dialog').find('.ui-dialog-title').text('Custom Filter');

    },

    /**
     * Callback to update the editor with the selected member.
     * @param editor
     * @param n
     */
    close_select_modal: function(editor, n){
        editor.insert(n);
    }

});
<|endoftext|>


<commit_before>export function getActivityInfo(id, callback) {
    fetchFromServer('/api/activity/' + id).then(data => {
        callback(data[0].fields);
    });

}

export function getUpcomingActivities(callback) {
    fetchFromServer('/api/activities/').then(data => {
        const ids = data.map(activity => {
            return activity.pk;
        });
        callback(ids);
    });
}

export function getAllActivities() {
    return fetchFromServer('/api/activities/').then(response => {
        return response;
    });
}

export function getFacebookEventData(activities) {

    let eventIDs = activities.activities
        .filter(activity => {return activity.fields.facebookID})
        .map(activity => {return activity.fields.facebookID});

    return new Promise(function (resolve) {
        getAccessToken(resolve);
    }).then(token => {

        let batch = eventIDs.map(id => {
            return {method:"GET", relative_url: id + "?fields=admins,attending,photos{images},picture,roles,videos"};
        });
        let data = {
            access_token: token,
            batch: batch
        };
        return postToServer('https://graph.facebook.com/v2.8/', data).then(data => {
            console.log(data);
            return data;
        });
    });

}

export function getAllAttendingActivities() {
    const profileName = window.location.href.split("/")[4];
    return fetchFromServer('/api/attendingActivities/'+profileName);
}
export function getAllHostingActivities() {
    const profileName = window.location.href.split("/")[4];
    return fetchFromServer('/api/hostingActivities/'+profileName);
}

export function signupActivity(id) {
    let data = {
        id: id
    };
    postToServer('http://localhost:8000/signupActivity/', data);
}

//Use only this method when doing GET-requests to server for JSON-data, don't make your own
function fetchFromServer(query) {
    return fetch(query, {
        credentials: "same-origin"
    }).then(response => {
        if (response.status >= 400) {
            throw new Error("Bad response from server");
        }
        return response.json();
    }).then(function(result) {
        if (result.error || result.length == 0) {
            console.log("This query gave an empty result or threw an error:\n" + query);
            return Promise.reject(result.error);
        } else {
            return result;
        }
    });
}

function postToServer(query, data) {
    return fetch(query, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        credentials: "same-origin",
        body: JSON.stringify(data)
    }).then((response) => {
        return response.json();
    }).then(function (result) {
        return result;
    })
}
<commit_msg>Facebook event data is now loaded and showing in events<commit_after>export function getActivityInfo(id, callback) {
    fetchFromServer('/api/activity/' + id).then(data => {
        callback(data[0].fields);
    });

}

export function getUpcomingActivities(callback) {
    fetchFromServer('/api/activities/').then(data => {
        const ids = data.map(activity => {
            return activity.pk;
        });
        callback(ids);
    });
}

export function getAllActivities() {
    return fetchFromServer('/api/activities/').then(response => {
        return response;
    });
}

export function getFacebookEventData(activities) {

    let eventIDs = activities.activities
        .filter(activity => {return activity.fields.facebookID})
        .map(activity => {return activity.fields.facebookID});

    return new Promise(function (resolve) {
        getAccessToken(resolve);
    }).then(token => {

        let batch = eventIDs.map(id => {
            return {method:"GET", relative_url: id + "?fields=admins,attending,photos{images},picture,roles,videos"};
        });
        let data = {
            access_token: token,
            batch: batch
        };
        return postToServer('https://graph.facebook.com/v2.8/', data).then(data => {
            for (let i = 0; i < data.length; i++) {
                let jsonObject = JSON.parse(data[0].body);
                for (let j in activities.activities) {
                    if (activities.activities[j].fields.facebookID == jsonObject.id) {
                        activities.activities[j].fields.facebook = jsonObject;
                    }
                }
            }
            return activities.activities;
        });
    });

}

function mapActivityToId() {

}

export function getAllAttendingActivities() {
    const profileName = window.location.href.split("/")[4];
    return fetchFromServer('/api/attendingActivities/'+profileName);
}
export function getAllHostingActivities() {
    const profileName = window.location.href.split("/")[4];
    return fetchFromServer('/api/hostingActivities/'+profileName);
}

export function signupActivity(id) {
    let data = {
        id: id
    };
    postToServer('http://localhost:8000/signupActivity/', data);
}

//Use only this method when doing GET-requests to server for JSON-data, don't make your own
function fetchFromServer(query) {
    return fetch(query, {
        credentials: "same-origin"
    }).then(response => {
        if (response.status >= 400) {
            throw new Error("Bad response from server");
        }
        return response.json();
    }).then(function(result) {
        if (result.error || result.length == 0) {
            console.log("This query gave an empty result or threw an error:\n" + query);
            return Promise.reject(result.error);
        } else {
            return result;
        }
    });
}

function postToServer(query, data) {
    return fetch(query, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        credentials: "same-origin",
        body: JSON.stringify(data)
    }).then((response) => {
        return response.json();
    }).then(function (result) {
        return result;
    })
}
<|endoftext|>


<commit_before>    var disqus_shortname = 'twelvepurplepills'; // required: replace example with your forum shortname
    /* * *  var disqus_identifier = '{{post.id}}'; // make sure to use the post.id as an identifier, otherwise disqus will use the pages url per default, which might be problematic... * * */

    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
<commit_msg>Deleted comments<commit_after>
<|endoftext|>