<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 *
 * 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.
 */

foam.CLASS({
  package: 'foam.dao',
  name: 'ResetSink',
  extends: 'foam.dao.ProxySink',
  implements: [ 'foam.core.Serializable' ],
  methods: [
    {
      name: 'put',
      code: function(obj, sub) { this.reset(s); },
      javaCode: 'reset(sub);'
    },
    {
      name: 'remove',
      code: function(obj, sub) { this.reset(s); },
      javaCode: 'reset(sub);'
    }
  ]
});

foam.CLASS({
  package: 'foam.dao',
  name: 'MergedResetSink',
  extends: 'foam.dao.ResetSink',
  implements: [ 'foam.core.Serializable' ],
  methods: [
    {
      name: 'reset',
      code: function(sub) { this.doReset(sub); },
      javaCode: `doReset(sub);`
    }
  ],
  listeners: [
    {
      name: 'doReset',
      isMerged: true,
      mergeDelay: 200,
      code: function(sub) {
        this.delegate.reset(sub);
      },
      javaCode: `
try {
  getDelegate().reset((foam.core.Detachable)event);
} catch(Exception e) {
  ((foam.core.Detachable)event).detach();
}
`
    }
  ]
});

foam.CLASS({
  package: 'foam.dao',
  name: 'ClientDAO',
  extends: 'foam.dao.BaseClientDAO',

  requires: [
    'foam.core.Serializable',
    'foam.dao.ClientSink',
    'foam.box.SkeletonBox'
  ],

  methods: [
    function put_(x, obj) {
      return this.SUPER(null, obj);
    },

    function remove_(x, obj) {
      return this.SUPER(null, obj);
    },

    function find_(x, key) {
      return this.SUPER(null, key);
    },

    function select_(x, sink, skip, limit, order, predicate) {
      if ( predicate === foam.mlang.predicate.True.create() ) predicate = null;
      if ( ! skip ) skip = 0;
      if ( foam.Undefined.isInstance(limit) ) limit = Number.MAX_SAFE_INTEGER;

      if ( ! this.Serializable.isInstance(sink) ) {
        var self = this;

        return this.SUPER(null, null, skip, limit, order, predicate).then(function(result) {
          var items = result.array;

          if ( ! sink ) return result;

          var sub = foam.core.FObject.create();
          var detached = false;
          sub.onDetach(function() { detached = true; });

          for ( var i = 0 ; i < items.length ; i++ ) {
            if ( detached ) break;

            sink.put(items[i], sub);
          }

          sink.eof();

          return sink;
        });
      }

      return this.SUPER(null, sink, skip, limit, order, predicate);
    },

    function removeAll_(x, skip, limit, order, predicate) {
      if ( predicate === foam.mlang.predicate.True.create() ) predicate = null;
      if ( ! skip ) skip = 0;
      if ( foam.Undefined.isInstance(limit) ) limit = Number.MAX_SAFE_INTEGER;

      return this.SUPER(null, skip, limit, order, predicate);
    },

    function listen_(x, sink, predicate) {
      // TODO: This should probably just be handled automatically via a RemoteSink/Listener
      // TODO: Unsubscribe support.

      var skeleton = this.SkeletonBox.create({
        data: sink
      });

      var clientSink = this.ClientSink.create({
        delegate: this.__context__.registry.register(
          null,
          this.delegateReplyPolicy,
          skeleton
        )
      });

      clientSink = foam.dao.MergedResetSink.create({
        delegate: clientSink
      });

      this.SUPER(null, clientSink, predicate);
    }
  ]
});
<commit_msg>Add java code to ClientDAO methods that need it.<commit_after>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 *
 * 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.
 */

foam.CLASS({
  package: 'foam.dao',
  name: 'ResetSink',
  extends: 'foam.dao.ProxySink',
  implements: [ 'foam.core.Serializable' ],
  methods: [
    {
      name: 'put',
      code: function(obj, sub) { this.reset(s); },
      javaCode: 'reset(sub);'
    },
    {
      name: 'remove',
      code: function(obj, sub) { this.reset(s); },
      javaCode: 'reset(sub);'
    }
  ]
});

foam.CLASS({
  package: 'foam.dao',
  name: 'MergedResetSink',
  extends: 'foam.dao.ResetSink',
  implements: [ 'foam.core.Serializable' ],
  methods: [
    {
      name: 'reset',
      code: function(sub) { this.doReset(sub); },
      javaCode: `doReset(sub);`
    }
  ],
  listeners: [
    {
      name: 'doReset',
      isMerged: true,
      mergeDelay: 200,
      code: function(sub) {
        this.delegate.reset(sub);
      },
      javaCode: `
try {
  getDelegate().reset((foam.core.Detachable)event);
} catch(Exception e) {
  ((foam.core.Detachable)event).detach();
}
`
    }
  ]
});

foam.CLASS({
  package: 'foam.dao',
  name: 'ClientDAO',
  extends: 'foam.dao.BaseClientDAO',

  requires: [
    'foam.core.Serializable',
    'foam.dao.ClientSink',
    'foam.box.SkeletonBox'
  ],

  methods: [
    {
      name: 'put_',
      code:     function put_(x, obj) {
        return this.SUPER(null, obj);
      },
      javaCode: `
return super.put_(null, obj);
`
    },
    {
      name: 'remove_',
      code: function remove_(x, obj) {
        return this.SUPER(null, obj);
      },
      javaCode: `
return super.remove_(null, obj);
`
    },
    {
      name: 'find_',
      code:     function find_(x, key) {
        return this.SUPER(null, key);
      },
      javaCode: `
return super.find_(null, id);
`
    },
    {
      name: 'select_',
      code: function select_(x, sink, skip, limit, order, predicate) {
        if ( predicate === foam.mlang.predicate.True.create() ) predicate = null;
        if ( ! skip ) skip = 0;
        if ( foam.Undefined.isInstance(limit) ) limit = Number.MAX_SAFE_INTEGER;

        if ( ! this.Serializable.isInstance(sink) ) {
          var self = this;

          return this.SUPER(null, null, skip, limit, order, predicate).then(function(result) {
            var items = result.array;

            if ( ! sink ) return result;

            var sub = foam.core.FObject.create();
            var detached = false;
            sub.onDetach(function() { detached = true; });

            for ( var i = 0 ; i < items.length ; i++ ) {
              if ( detached ) break;

              sink.put(items[i], sub);
            }

            sink.eof();

            return sink;
          });
        }

        return this.SUPER(null, sink, skip, limit, order, predicate);
      },
      javaCode: `
return super.select_(null, sink, skip, limit, order, predicate);
`
    },

    {
      name: 'removeAll_',
      code: function removeAll_(x, skip, limit, order, predicate) {
        if ( predicate === foam.mlang.predicate.True.create() ) predicate = null;
        if ( ! skip ) skip = 0;
        if ( foam.Undefined.isInstance(limit) ) limit = Number.MAX_SAFE_INTEGER;

        return this.SUPER(null, skip, limit, order, predicate);
      },
      javaCode: `
super.removeAll_(null, skip, limit, order, predicate);
`
    },

    {
      name: 'listen_',
      code: function listen_(x, sink, predicate) {
        // TODO: This should probably just be handled automatically via a RemoteSink/Listener
        // TODO: Unsubscribe support.

        var skeleton = this.SkeletonBox.create({
          data: sink
        });

        var clientSink = this.ClientSink.create({
          delegate: this.__context__.registry.register(
            null,
            this.delegateReplyPolicy,
            skeleton
          )
        });

        clientSink = foam.dao.MergedResetSink.create({
          delegate: clientSink
        });

        this.SUPER(null, clientSink, predicate);
      },
    }
  ]
});
<|endoftext|>


<commit_before>//----------------------------------------------------------------------------------------------------------------------
// Qniform Gruntfile
//----------------------------------------------------------------------------------------------------------------------

module.exports = function(grunt)
{
    grunt.initConfig({
        browserify: {
            dist: {
                options: {
                    //alias: {
                    //    vue: './src/utils/vueShim.js'
                    //},
                    banner: "/* Vuestrap v" + require('./package').version + " */",
                    transform: [ "vueify", "babelify" ],
                    browserifyOptions: {
                        standalone: 'vueboot'
                    }
                },
                files: {
                    "./dist/vueboot.js": "./src/vueboot.js"
                }
            }
        },
        clean: ['dist'],
        watch: {
            build: {
                files: ["src/**/*.js", "src/**/*.vue", "src/**/*.scss"],
                tasks: ["browserify"]
            }
        }
    });

    //------------------------------------------------------------------------------------------------------------------

    grunt.loadNpmTasks("grunt-browserify");
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-watch');

    //------------------------------------------------------------------------------------------------------------------

    grunt.registerTask("build", ["clean", "browserify"]);
    grunt.registerTask("default", ["build", 'watch']);

    //------------------------------------------------------------------------------------------------------------------
};

//----------------------------------------------------------------------------------------------------------------------
<commit_msg>Fixed name in header.<commit_after>//----------------------------------------------------------------------------------------------------------------------
// Qniform Gruntfile
//----------------------------------------------------------------------------------------------------------------------

module.exports = function(grunt)
{
    grunt.initConfig({
        browserify: {
            dist: {
                options: {
                    banner: "/* VueBoot v" + require('./package').version + " */",
                    transform: [ "vueify", "babelify" ],
                    browserifyOptions: {
                        standalone: 'vueboot'
                    }
                },
                files: {
                    "./dist/vueboot.js": "./src/vueboot.js"
                }
            }
        },
        clean: ['dist'],
        watch: {
            build: {
                files: ["src/**/*.js", "src/**/*.vue", "src/**/*.scss"],
                tasks: ["browserify"]
            }
        }
    });

    //------------------------------------------------------------------------------------------------------------------

    grunt.loadNpmTasks("grunt-browserify");
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-watch');

    //------------------------------------------------------------------------------------------------------------------

    grunt.registerTask("build", ["clean", "browserify"]);
    grunt.registerTask("default", ["build", 'watch']);

    //------------------------------------------------------------------------------------------------------------------
};

//----------------------------------------------------------------------------------------------------------------------
<|endoftext|>


<commit_before>const ntpClient = require('ntp-client');
const delay = require('delay');

var gReq = 0;
var gReqInProgress = false;
/**
 * Creates a promise that resolves with an Date object after a successful NTP server query
 * @return {Promise} Promise that either resolves with successful Date object or an NTP server communication
 * error
 */
function ntpDatePromise() {
    // TIME-server query via ntp: https://github.com/moonpyk/node-ntp-client

    return new Promise((iResolveFunc, iRejectFunc) => {

        // See http://www.pool.ntp.org/en/ for usage information
        // http://www.ntp.org/ About NTP protocol
        // Or just google for "gps clock time server"
        console.log(`NTP Req ${gReq} start`);
        const startedReq = gReq;
        gReq += 1;
        var startTime = Date.now();
        if (gReqInProgress === true) {
            console.error("ERROR: Simultaneous requests running!");
        }
        gReqInProgress = true;
        ntpClient.getNetworkTime("pool.ntp.org", 123, (err, date) => {
            console.log(`NTP Req ${startedReq} end`);
            gReqInProgress = false;
            if (err) {
                iRejectFunc(err);
            }

            const latency = Date.now() - startTime;

            iResolveFunc({
                date,
                latency
            });

        });
    });
}

function ntpDatePromiseBurst() {
    // See http://stackoverflow.com/questions/28683071/how-do-you-synchronously-resolve-a-chain-of-es6-promises

    // ntpDatePromise().then(() => {
    //     return ntpDatePromise();
    // }).then(() => {
    //     return ntpDatePromise();
    // }).then(() => {
    //     return ntpDatePromise();
    // });

    // Prepare promise chain
    var p = Promise.resolve();
    for (let i = 0; i < 10; i += 1) {
        p = p
            .then(delay(1000))
            .then((iRes) => {
                console.log(JSON.stringify(iRes));
                return ntpDatePromise();
            });
    }
    p.then(() => {
        console.log("NTP CHAIN DONE");
    }).catch((err) => {
        console.log(`NTP CHAIN Broke with "${err}"`);
    });
}
/**
 * A class that requests NTP time every 10 seconds
 * Its deltaData is sent back on every '/doSynchronize.json'
 */
class Chronos {

    constructor() {

        this.fDeltaData = {
            fLastServerNTPDelta: 0.0,
            fAverageServerNTPDelta: 0.0,
            fSampleCount: 0.0,
            fServerTimeMS: null
        };

        this.fTotalDelta = 0.0;
        this.fLastNTPRequestStarted = null;

        // this.Synchronize();

        // this.TickInterval = setInterval(() => {
        //     this.Synchronize();
        // }, 1000);
    }

    Synchronize() {
        const ntpRequestStart = Date.now();
        if (this.fLastNTPRequestStarted !== null) {
            const elapsedSinceLastRequestStarted = ntpRequestStart - this.fLastNTPRequestStarted;

            console.log(
                `No NTP Request possible, since last one is still processing
                 (${elapsedSinceLastRequestStarted} ms elapsed)`
            );

            return;
        }

        this.fLastNTPRequestStarted = ntpRequestStart;

        ntpDatePromise().then((iNTPDate) => {
            const serverNow = new Date();
            const ntpTimeRaw = iNTPDate.date.getTime();

            if (ntpTimeRaw < 0) {
                console.error("ERROR: NEGATIVE TIME RECEIVED, BAD SAMPLE");
                return;
            }
            if (this.fLastNTPRequestStarted === null) {
                console.error(
                    "ERROR: Received the response but do not know when it started! SHOULDN'T HAPPEN!"
                );
                return;
            }
            const ntpRequestElapsed = serverNow.getTime() - this.fLastNTPRequestStarted;

            const ntpTimeAdjusted = ntpTimeRaw + ntpRequestElapsed / 2; // Adjust for latency

            const serverMilliseconds = serverNow.getTime();
            const serverNTPDelta = serverMilliseconds - ntpTimeAdjusted;
            this.fDeltaData.fLastServerNTPDelta = serverNTPDelta;

            this.fTotalDelta += serverNTPDelta;

            this.fDeltaData.fSampleCount += 1;

            this.fDeltaData.fAverageServerNTPDelta = this.fTotalDelta /
                this.fDeltaData.fSampleCount;

            this.fDeltaData.fServerTimeMS = serverNow.getTime();

            console.log("===>");
            console.log("NTPTime RAW : " + ntpTimeRaw + " ms");
            console.log("NTP Request started: " + this.fLastNTPRequestStarted + " ms");
            console.log("Latency  1: " + ntpRequestElapsed + " ms");
            console.log("Latency  2: " + iNTPDate.latency + " ms");
            console.log("NTPTime Adjusted) : " + ntpTimeAdjusted + " ms");
            console.log("Current (ServerTime) : " + serverMilliseconds + " ms");
            console.log("Current (ServerTime - NTP Time) : " + serverNTPDelta + " ms");
            this.fLastNTPRequestStarted = null;
        }).catch((err) => {
            console.error("NTP Error (Promise Rejected):" + err);
            const serverNow = new Date();
            const ntpRequestElapsed = serverNow.getTime() - this.fLastNTPRequestStarted;
            console.error(`NTP Request Failed after :${ntpRequestElapsed} ms`);
            this.fLastNTPRequestStarted = null;
        });

    } /* Synchronize */

}
ntpDatePromiseBurst();
const keeper = new Chronos();
/**
 * Express middleware to log requests
 * @param {Object} iReq: standard Express request
 * @param {Object} iResponse: standard Express response
 * @param {Function} next: standard Express next() handler
 */
function timeServerEndpointHandler(iReq, iResponse, next) {
    console.log("doSynchronize Request");

    var result = {
        fDeltaData: keeper.fDeltaData
    };

    iResponse.send(JSON.stringify(result));

    next();
}

module.exports = {
    timeServerEndpointHandler
};
<commit_msg>Comments<commit_after>const ntpClient = require('ntp-client');
const delay = require('delay');

var gReq = 0;
var gReqInProgress = false;
/**
 * Creates a promise that resolves with an Date object after a successful NTP server query
 * @return {Promise} Promise that either resolves with successful Date object or an NTP server communication
 * error
 */
function ntpDatePromise() {
    // TIME-server query via ntp: https://github.com/moonpyk/node-ntp-client

    return new Promise((iResolveFunc, iRejectFunc) => {

        // See http://www.pool.ntp.org/en/ for usage information
        // http://www.ntp.org/ About NTP protocol
        // Or just google for "gps clock time server"
        console.log(`NTP Req ${gReq} start`);
        const startedReq = gReq;
        gReq += 1;
        var startTime = Date.now();
        if (gReqInProgress === true) {
            console.error("ERROR: Simultaneous requests running!");
        }
        gReqInProgress = true;
        ntpClient.getNetworkTime("pool.ntp.org", 123, (err, date) => {
            console.log(`NTP Req ${startedReq} end`);
            gReqInProgress = false;
            if (err) {
                iRejectFunc(err);
            }

            const latency = Date.now() - startTime;

            iResolveFunc({
                date,
                latency
            });

        });
    });
}

/**
 * Creates a promise that resolves with an Date object after a successful burst of X NTP server queries
 * @return {Promise} Promise that either resolves with successful average Date object or an NTP server communication
 * error
 */
function ntpDatePromiseBurst() {
    // See http://stackoverflow.com/questions/28683071/how-do-you-synchronously-resolve-a-chain-of-es6-promises

    // ntpDatePromise().then(() => {
    //     return ntpDatePromise();
    // }).then(() => {
    //     return ntpDatePromise();
    // }).then(() => {
    //     return ntpDatePromise();
    // });

    // Prepare promise chain
    var p = Promise.resolve();
    for (let i = 0; i < 10; i += 1) {
        // Chain the promises interleaved with the 'delay' passthrough promise, that resolves after X ms
        // https://github.com/sindresorhus/delay
        p = p
            .then(delay(1000))
            .then((iRes) => {
                console.log(JSON.stringify(iRes));
                return ntpDatePromise();
            });
    }
    p.then(() => {
        console.log("NTP CHAIN DONE");
    }).catch((err) => {
        console.log(`NTP CHAIN Broke with "${err}"`);
    });

    return p;
}
/**
 * A class that requests NTP time every 10 seconds
 * Its deltaData is sent back on every '/doSynchronize.json'
 */
class Chronos {

    constructor() {

        this.fDeltaData = {
            fLastServerNTPDelta: 0.0,
            fAverageServerNTPDelta: 0.0,
            fSampleCount: 0.0,
            fServerTimeMS: null
        };

        this.fTotalDelta = 0.0;
        this.fLastNTPRequestStarted = null;

        // this.Synchronize();

        // this.TickInterval = setInterval(() => {
        //     this.Synchronize();
        // }, 1000);
    }

    Synchronize() {
        const ntpRequestStart = Date.now();
        if (this.fLastNTPRequestStarted !== null) {
            const elapsedSinceLastRequestStarted = ntpRequestStart - this.fLastNTPRequestStarted;

            console.log(
                `No NTP Request possible, since last one is still processing
                 (${elapsedSinceLastRequestStarted} ms elapsed)`
            );

            return;
        }

        this.fLastNTPRequestStarted = ntpRequestStart;

        ntpDatePromise().then((iNTPDate) => {
            const serverNow = new Date();
            const ntpTimeRaw = iNTPDate.date.getTime();

            if (ntpTimeRaw < 0) {
                console.error("ERROR: NEGATIVE TIME RECEIVED, BAD SAMPLE");
                return;
            }
            if (this.fLastNTPRequestStarted === null) {
                console.error(
                    "ERROR: Received the response but do not know when it started! SHOULDN'T HAPPEN!"
                );
                return;
            }
            const ntpRequestElapsed = serverNow.getTime() - this.fLastNTPRequestStarted;

            const ntpTimeAdjusted = ntpTimeRaw + ntpRequestElapsed / 2; // Adjust for latency

            const serverMilliseconds = serverNow.getTime();
            const serverNTPDelta = serverMilliseconds - ntpTimeAdjusted;
            this.fDeltaData.fLastServerNTPDelta = serverNTPDelta;

            this.fTotalDelta += serverNTPDelta;

            this.fDeltaData.fSampleCount += 1;

            this.fDeltaData.fAverageServerNTPDelta = this.fTotalDelta /
                this.fDeltaData.fSampleCount;

            this.fDeltaData.fServerTimeMS = serverNow.getTime();

            console.log("===>");
            console.log("NTPTime RAW : " + ntpTimeRaw + " ms");
            console.log("NTP Request started: " + this.fLastNTPRequestStarted + " ms");
            console.log("Latency  1: " + ntpRequestElapsed + " ms");
            console.log("Latency  2: " + iNTPDate.latency + " ms");
            console.log("NTPTime Adjusted) : " + ntpTimeAdjusted + " ms");
            console.log("Current (ServerTime) : " + serverMilliseconds + " ms");
            console.log("Current (ServerTime - NTP Time) : " + serverNTPDelta + " ms");
            this.fLastNTPRequestStarted = null;
        }).catch((err) => {
            console.error("NTP Error (Promise Rejected):" + err);
            const serverNow = new Date();
            const ntpRequestElapsed = serverNow.getTime() - this.fLastNTPRequestStarted;
            console.error(`NTP Request Failed after :${ntpRequestElapsed} ms`);
            this.fLastNTPRequestStarted = null;
        });

    } /* Synchronize */

}
ntpDatePromiseBurst();
const keeper = new Chronos();
/**
 * Express middleware to log requests
 * @param {Object} iReq: standard Express request
 * @param {Object} iResponse: standard Express response
 * @param {Function} next: standard Express next() handler
 */
function timeServerEndpointHandler(iReq, iResponse, next) {
    console.log("doSynchronize Request");

    var result = {
        fDeltaData: keeper.fDeltaData
    };

    iResponse.send(JSON.stringify(result));

    next();
}

module.exports = {
    timeServerEndpointHandler
};
<|endoftext|>


<commit_before>/*
 * Reads the settings from settings.json and supplies defaults for any
 * missing settings.
 * */

var fs = require("fs");
var os = require("os");
var jsonminify = require('jsonminify');

//defaults
exports.defaults = {
  //IP and port to bind to
  "ip": "0.0.0.0",
  "port" : 3000,
  //The Type of the database. You can choose between dirty, postgres, sqlite and mysql
  //You shouldn't use "dirty" for for anything else than testing or development
  "dbType" : "dirty",
  //the database specific settings
  "dbSettings" : {
                   "filename" : "var/dirty.db"
                 }
};

exports.loadSettings = function() {
	var settings_file = "settings.json";
	var user_settings = {};
	try {
		  user_settings = fs.readFileSync(settings_file).toString();
		  //minify to remove comments and whitepsace before parsing
		  user_settings = JSON.parse(JSON.minify(user_settings));
	}
	catch(e){
		console.error('There was an error processing your settings.json file: '+e.message);
		process.exit(1);
	}

    //copy over defaults
	for(var k in exports.defaults){exports[k] = exports.defaults[k]}
	//go through each key in the user supplied settings and replace the defaults
	//if a key is not in the defaults, warn the user and ignore it
	for(var k in user_settings) {
		if(k in exports.defaults){
            //overwrite it
            exports[k] = user_settings[k];
        }
        else
        {
            console.warn('Unknown settings parameter:'+k)
        }
	}

};

exports.loadSettings();<commit_msg>changed console output to more closely match etherpad<commit_after>/*
 * Reads the settings from settings.json and supplies defaults for any
 * missing settings.
 * */

var fs = require("fs");
var os = require("os");
var jsonminify = require('jsonminify');

//defaults
exports.defaults = {
  //IP and port to bind to
  "ip": "0.0.0.0",
  "port" : 3000,
  //The Type of the database. You can choose between dirty, postgres, sqlite and mysql
  //You shouldn't use "dirty" for for anything else than testing or development
  "dbType" : "dirty",
  //the database specific settings
  "dbSettings" : {
                   "filename" : "var/dirty.db"
                 }
};

exports.loadSettings = function() {
	var settings_file = "settings.json";
	var user_settings = {};
	try {
		  user_settings = fs.readFileSync(settings_file).toString();
		  //minify to remove comments and whitepsace before parsing
		  user_settings = JSON.parse(JSON.minify(user_settings));
	}
	catch(e){
		console.error('There was an error processing your settings.json file: '+e.message);
		process.exit(1);
	}

    //copy over defaults
	for(var k in exports.defaults){exports[k] = exports.defaults[k]}
	//go through each key in the user supplied settings and replace the defaults
	//if a key is not in the defaults, warn the user and ignore it
	for(var k in user_settings) {
		if(k in exports.defaults){
            //overwrite it
            exports[k] = user_settings[k];
        }
        else
        {
            console.warn("'Unknown Setting: '" + k + "'. This setting doesn't exist or it was removed");
        }
	}
    //settings specific warnings
    if(exports.dbType === "dirty"){
        console.warn("DirtyDB is used. This is fine for testing but not recommended for production.");
    }

};

exports.loadSettings();<|endoftext|>


<commit_before>/*global module:false*/
module.exports = function (grunt) {
  'use strict';

  // Project configuration.
  grunt.initConfig({
    // Metadata.
    pkg: grunt.file.readJSON('package.json'),
    banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
      '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
      '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
      '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
      ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
    // Task configuration.
    concat: {
      options: {
        banner: '<%= banner %>',
        stripBanners: true
      },
      dist: {
        src: ['dist/<%= pkg.name %>.js'],
        dest: 'dist/<%= pkg.name %>.js'
      }
    },
    uglify: {
      options: {
        banner: '<%= banner %>'
      },
      dist: {
        src: '<%= concat.dist.dest %>',
        dest: 'dist/<%= pkg.name %>.min.js'
      }
    },
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      gruntfile: {
        src: 'Gruntfile.js'
      },
      libtest: {
        src: ['lib/**/*.js', 'test/**/*.js']
      }
    },
    jscs: {
      libtest: {
        src: '<%= jshint.libtest.src %>'
      },
      gruntfile: {
        src: 'Gruntfile.js'
      }
    },
    lintspaces: {
      options: {
        editorconfig: '.editorconfig'
      },
      gruntfile: {
        src: ['Gruntfile.js']
      },
      libtest: {
        src: ['lib/**/*.js', 'tests/*.spec.js']
      }
    },
    simplemocha: {
      options: {
        globals: ['should'],
        timeout: 3000,
        ignoreLeaks: false,
        ui: 'bdd',
        reporter: 'tap'
      },

      all: {
        src: ['tests/*.spec.js']
      }
    },
    watch: {
      gruntfile: {
        files: '<%= jshint.gruntfile.src %>',
        tasks: ['jshint:gruntfile', 'jscs:gruntfile', 'lintspaces:gruntfile']
      },
      libtest: {
        files: '<%= jshint.libtest.src %>',
        tasks: ['jshint:libtest', 'jscs:libtest', 'lintspaces:libtest', 'build', 'test']
      }
    },
    'release-it': {
      options: {
        pkgFiles: ['package.json', 'bower.json'],
        commitMessage: 'bump release %s',
        tagName: '%s',
        tagAnnotation: 'Release %s',
        buildCommand: false,
        publish: true
      }
    },
    umd: {
      lib: {
        src: 'lib/<%= pkg.name %>.js',
        dest: '<%= concat.dist.dest %>',
        indent: '  ',
        objectToExport: 'mixit'
      }
    }
  });

  require('load-grunt-tasks')(grunt);

  // Default task.
  grunt.registerTask('default', ['lint', 'build', 'test']);

  grunt.registerTask('build', ['umd:lib', 'concat', 'uglify']);

  grunt.registerTask('test', ['simplemocha']);

  grunt.registerTask('lint', ['jshint', 'jscs', 'lintspaces']);
};
<commit_msg>chore(closure): distribute the closure for anti-umd<commit_after>/*global module:false*/
module.exports = function (grunt) {
  'use strict';

  // Project configuration.
  grunt.initConfig({
    // Metadata.
    pkg: grunt.file.readJSON('package.json'),
    banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
      '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
      '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
      '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
      ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
    // Task configuration.
    concat: {
      options: {
        banner: '<%= banner %>',
        stripBanners: true
      },
      dist: {
        src: ['dist/<%= pkg.name %>.js'],
        dest: 'dist/<%= pkg.name %>.js'
      },
      closure: {
        src: ['lib/<%= pkg.name %>.js'],
        dest: 'dist/<%= pkg.name %>.closure.js'
      }
    },
    uglify: {
      options: {
        banner: '<%= banner %>'
      },
      dist: {
        src: '<%= concat.dist.dest %>',
        dest: 'dist/<%= pkg.name %>.min.js'
      },
      closure: {
        src: '<%= concat.closure.dest %>',
        dest: 'dist/<%= pkg.name %>.closure.min.js'
      }
    },
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      gruntfile: {
        src: 'Gruntfile.js'
      },
      libtest: {
        src: ['lib/**/*.js', 'test/**/*.js']
      }
    },
    jscs: {
      libtest: {
        src: '<%= jshint.libtest.src %>'
      },
      gruntfile: {
        src: 'Gruntfile.js'
      }
    },
    lintspaces: {
      options: {
        editorconfig: '.editorconfig'
      },
      gruntfile: {
        src: ['Gruntfile.js']
      },
      libtest: {
        src: ['lib/**/*.js', 'tests/*.spec.js']
      }
    },
    simplemocha: {
      options: {
        globals: ['should'],
        timeout: 3000,
        ignoreLeaks: false,
        ui: 'bdd',
        reporter: 'tap'
      },

      all: {
        src: ['tests/*.spec.js']
      }
    },
    watch: {
      gruntfile: {
        files: '<%= jshint.gruntfile.src %>',
        tasks: ['jshint:gruntfile', 'jscs:gruntfile', 'lintspaces:gruntfile']
      },
      libtest: {
        files: '<%= jshint.libtest.src %>',
        tasks: ['jshint:libtest', 'jscs:libtest', 'lintspaces:libtest', 'build', 'test']
      }
    },
    'release-it': {
      options: {
        pkgFiles: ['package.json', 'bower.json'],
        commitMessage: 'bump release %s',
        tagName: '%s',
        tagAnnotation: 'Release %s',
        buildCommand: false,
        publish: true
      }
    },
    umd: {
      lib: {
        src: 'lib/<%= pkg.name %>.js',
        dest: '<%= concat.dist.dest %>',
        indent: '  ',
        objectToExport: 'mixit'
      }
    }
  });

  require('load-grunt-tasks')(grunt);

  // Default task.
  grunt.registerTask('default', ['lint', 'build', 'test']);

  grunt.registerTask('build', ['umd:lib', 'concat', 'uglify']);

  grunt.registerTask('test', ['simplemocha']);

  grunt.registerTask('lint', ['jshint', 'jscs', 'lintspaces']);
};
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2013-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import type {TopLevelTypes} from './BrowserEventConstants';

import {accumulateTwoPhaseDispatches} from 'events/EventPropagators';
import ExecutionEnvironment from 'fbjs/lib/ExecutionEnvironment';

import * as FallbackCompositionState from './FallbackCompositionState';
import SyntheticCompositionEvent from './SyntheticCompositionEvent';
import SyntheticInputEvent from './SyntheticInputEvent';

const END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
const START_KEYCODE = 229;

const canUseCompositionEvent =
  ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window;

let documentMode = null;
if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) {
  documentMode = document.documentMode;
}

// Webkit offers a very useful `textInput` event that can be used to
// directly represent `beforeInput`. The IE `textinput` event is not as
// useful, so we don't use it.
const canUseTextInputEvent =
  ExecutionEnvironment.canUseDOM &&
  'TextEvent' in window &&
  !documentMode &&
  !isPresto();

// In IE9+, we have access to composition events, but the data supplied
// by the native compositionend event may be incorrect. Japanese ideographic
// spaces, for instance (\u3000) are not recorded correctly.
const useFallbackCompositionData =
  ExecutionEnvironment.canUseDOM &&
  (!canUseCompositionEvent ||
    (documentMode && documentMode > 8 && documentMode <= 11));

/**
 * Opera <= 12 includes TextEvent in window, but does not fire
 * text input events. Rely on keypress instead.
 */
function isPresto() {
  const opera = window.opera;
  return (
    opera !== null &&
    typeof opera === 'object' &&
    typeof opera.version === 'function' &&
    parseInt(opera.version(), 10) <= 12
  );
}

const SPACEBAR_CODE = 32;
const SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);

// Events and their corresponding property names.
const eventTypes = {
  beforeInput: {
    phasedRegistrationNames: {
      bubbled: 'onBeforeInput',
      captured: 'onBeforeInputCapture',
    },
    dependencies: [
      'topCompositionEnd',
      'topKeyPress',
      'topTextInput',
      'topPaste',
    ],
  },
  compositionEnd: {
    phasedRegistrationNames: {
      bubbled: 'onCompositionEnd',
      captured: 'onCompositionEndCapture',
    },
    dependencies: [
      'topBlur',
      'topCompositionEnd',
      'topKeyDown',
      'topKeyPress',
      'topKeyUp',
      'topMouseDown',
    ],
  },
  compositionStart: {
    phasedRegistrationNames: {
      bubbled: 'onCompositionStart',
      captured: 'onCompositionStartCapture',
    },
    dependencies: [
      'topBlur',
      'topCompositionStart',
      'topKeyDown',
      'topKeyPress',
      'topKeyUp',
      'topMouseDown',
    ],
  },
  compositionUpdate: {
    phasedRegistrationNames: {
      bubbled: 'onCompositionUpdate',
      captured: 'onCompositionUpdateCapture',
    },
    dependencies: [
      'topBlur',
      'topCompositionUpdate',
      'topKeyDown',
      'topKeyPress',
      'topKeyUp',
      'topMouseDown',
    ],
  },
};

// Track whether we've ever handled a keypress on the space key.
let hasSpaceKeypress = false;

/**
 * Return whether a native keypress event is assumed to be a command.
 * This is required because Firefox fires `keypress` events for key commands
 * (cut, copy, select-all, etc.) even though no character is inserted.
 */
function isKeypressCommand(nativeEvent) {
  return (
    (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
    // ctrlKey && altKey is equivalent to AltGr, and is not a command.
    !(nativeEvent.ctrlKey && nativeEvent.altKey)
  );
}

/**
 * Translate native top level events into event types.
 *
 * @param {string} topLevelType
 * @return {object}
 */
function getCompositionEventType(topLevelType) {
  switch (topLevelType) {
    case 'topCompositionStart':
      return eventTypes.compositionStart;
    case 'topCompositionEnd':
      return eventTypes.compositionEnd;
    case 'topCompositionUpdate':
      return eventTypes.compositionUpdate;
  }
}

/**
 * Does our fallback best-guess model think this event signifies that
 * composition has begun?
 *
 * @param {string} topLevelType
 * @param {object} nativeEvent
 * @return {boolean}
 */
function isFallbackCompositionStart(topLevelType, nativeEvent) {
  return topLevelType === 'topKeyDown' && nativeEvent.keyCode === START_KEYCODE;
}

/**
 * Does our fallback mode think that this event is the end of composition?
 *
 * @param {string} topLevelType
 * @param {object} nativeEvent
 * @return {boolean}
 */
function isFallbackCompositionEnd(topLevelType, nativeEvent) {
  switch (topLevelType) {
    case 'topKeyUp':
      // Command keys insert or clear IME input.
      return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
    case 'topKeyDown':
      // Expect IME keyCode on each keydown. If we get any other
      // code we must have exited earlier.
      return nativeEvent.keyCode !== START_KEYCODE;
    case 'topKeyPress':
    case 'topMouseDown':
    case 'topBlur':
      // Events are not possible without cancelling IME.
      return true;
    default:
      return false;
  }
}

/**
 * Google Input Tools provides composition data via a CustomEvent,
 * with the `data` property populated in the `detail` object. If this
 * is available on the event object, use it. If not, this is a plain
 * composition event and we have nothing special to extract.
 *
 * @param {object} nativeEvent
 * @return {?string}
 */
function getDataFromCustomEvent(nativeEvent) {
  const detail = nativeEvent.detail;
  if (typeof detail === 'object' && 'data' in detail) {
    return detail.data;
  }
  return null;
}

// Track the current IME composition status, if any.
let isComposing = false;

/**
 * @return {?object} A SyntheticCompositionEvent.
 */
function extractCompositionEvent(
  topLevelType,
  targetInst,
  nativeEvent,
  nativeEventTarget,
) {
  let eventType;
  let fallbackData;

  if (canUseCompositionEvent) {
    eventType = getCompositionEventType(topLevelType);
  } else if (!isComposing) {
    if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
      eventType = eventTypes.compositionStart;
    }
  } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
    eventType = eventTypes.compositionEnd;
  }

  if (!eventType) {
    return null;
  }

  if (useFallbackCompositionData) {
    // The current composition is stored statically and must not be
    // overwritten while composition continues.
    if (!isComposing && eventType === eventTypes.compositionStart) {
      isComposing = FallbackCompositionState.initialize(nativeEventTarget);
    } else if (eventType === eventTypes.compositionEnd) {
      if (isComposing) {
        fallbackData = FallbackCompositionState.getData();
      }
    }
  }

  const event = SyntheticCompositionEvent.getPooled(
    eventType,
    targetInst,
    nativeEvent,
    nativeEventTarget,
  );

  if (fallbackData) {
    // Inject data generated from fallback path into the synthetic event.
    // This matches the property of native CompositionEventInterface.
    event.data = fallbackData;
  } else {
    const customData = getDataFromCustomEvent(nativeEvent);
    if (customData !== null) {
      event.data = customData;
    }
  }

  accumulateTwoPhaseDispatches(event);
  return event;
}

/**
 * @param {TopLevelTypes} topLevelType Record from `BrowserEventConstants`.
 * @param {object} nativeEvent Native browser event.
 * @return {?string} The string corresponding to this `beforeInput` event.
 */
function getNativeBeforeInputChars(topLevelType: TopLevelTypes, nativeEvent) {
  switch (topLevelType) {
    case 'topCompositionEnd':
      return getDataFromCustomEvent(nativeEvent);
    case 'topKeyPress':
      /**
       * If native `textInput` events are available, our goal is to make
       * use of them. However, there is a special case: the spacebar key.
       * In Webkit, preventing default on a spacebar `textInput` event
       * cancels character insertion, but it *also* causes the browser
       * to fall back to its default spacebar behavior of scrolling the
       * page.
       *
       * Tracking at:
       * https://code.google.com/p/chromium/issues/detail?id=355103
       *
       * To avoid this issue, use the keypress event as if no `textInput`
       * event is available.
       */
      const which = nativeEvent.which;
      if (which !== SPACEBAR_CODE) {
        return null;
      }

      hasSpaceKeypress = true;
      return SPACEBAR_CHAR;

    case 'topTextInput':
      // Record the characters to be added to the DOM.
      const chars = nativeEvent.data;

      // If it's a spacebar character, assume that we have already handled
      // it at the keypress level and bail immediately. Android Chrome
      // doesn't give us keycodes, so we need to blacklist it.
      if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
        return null;
      }

      return chars;

    default:
      // For other native event types, do nothing.
      return null;
  }
}

/**
 * For browsers that do not provide the `textInput` event, extract the
 * appropriate string to use for SyntheticInputEvent.
 *
 * @param {string} topLevelType Record from `BrowserEventConstants`.
 * @param {object} nativeEvent Native browser event.
 * @return {?string} The fallback string for this `beforeInput` event.
 */
function getFallbackBeforeInputChars(topLevelType: TopLevelTypes, nativeEvent) {
  // If we are currently composing (IME) and using a fallback to do so,
  // try to extract the composed characters from the fallback object.
  // If composition event is available, we extract a string only at
  // compositionevent, otherwise extract it at fallback events.
  if (isComposing) {
    if (
      topLevelType === 'topCompositionEnd' ||
      (!canUseCompositionEvent &&
        isFallbackCompositionEnd(topLevelType, nativeEvent))
    ) {
      const chars = FallbackCompositionState.getData();
      FallbackCompositionState.reset();
      isComposing = false;
      return chars;
    }
    return null;
  }

  switch (topLevelType) {
    case 'topPaste':
      // If a paste event occurs after a keypress, throw out the input
      // chars. Paste events should not lead to BeforeInput events.
      return null;
    case 'topKeyPress':
      /**
       * As of v27, Firefox may fire keypress events even when no character
       * will be inserted. A few possibilities:
       *
       * - `which` is `0`. Arrow keys, Esc key, etc.
       *
       * - `which` is the pressed key code, but no char is available.
       *   Ex: 'AltGr + d` in Polish. There is no modified character for
       *   this key combination and no character is inserted into the
       *   document, but FF fires the keypress for char code `100` anyway.
       *   No `input` event will occur.
       *
       * - `which` is the pressed key code, but a command combination is
       *   being used. Ex: `Cmd+C`. No character is inserted, and no
       *   `input` event will occur.
       */
      if (!isKeypressCommand(nativeEvent)) {
        // IE fires the `keypress` event when a user types an emoji via
        // Touch keyboard of Windows.  In such a case, the `char` property
        // holds an emoji character like `\uD83D\uDE0A`.  Because its length
        // is 2, the property `which` does not represent an emoji correctly.
        // In such a case, we directly return the `char` property instead of
        // using `which`.
        if (nativeEvent.char && nativeEvent.char.length > 1) {
          return nativeEvent.char;
        } else if (nativeEvent.which) {
          return String.fromCharCode(nativeEvent.which);
        }
      }
      return null;
    case 'topCompositionEnd':
      return useFallbackCompositionData ? null : nativeEvent.data;
    default:
      return null;
  }
}

/**
 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
 * `textInput` or fallback behavior.
 *
 * @return {?object} A SyntheticInputEvent.
 */
function extractBeforeInputEvent(
  topLevelType,
  targetInst,
  nativeEvent,
  nativeEventTarget,
) {
  let chars;

  if (canUseTextInputEvent) {
    chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
  } else {
    chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
  }

  // If no characters are being inserted, no BeforeInput event should
  // be fired.
  if (!chars) {
    return null;
  }

  const event = SyntheticInputEvent.getPooled(
    eventTypes.beforeInput,
    targetInst,
    nativeEvent,
    nativeEventTarget,
  );

  event.data = chars;
  accumulateTwoPhaseDispatches(event);
  return event;
}

/**
 * Create an `onBeforeInput` event to match
 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
 *
 * This event plugin is based on the native `textInput` event
 * available in Chrome, Safari, Opera, and IE. This event fires after
 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
 *
 * `beforeInput` is spec'd but not implemented in any browsers, and
 * the `input` event does not provide any useful information about what has
 * actually been added, contrary to the spec. Thus, `textInput` is the best
 * available event to identify the characters that have actually been inserted
 * into the target node.
 *
 * This plugin is also responsible for emitting `composition` events, thus
 * allowing us to share composition fallback code for both `beforeInput` and
 * `composition` event types.
 */
const BeforeInputEventPlugin = {
  eventTypes: eventTypes,

  extractEvents: function(
    topLevelType,
    targetInst,
    nativeEvent,
    nativeEventTarget,
  ) {
    const composition = extractCompositionEvent(
      topLevelType,
      targetInst,
      nativeEvent,
      nativeEventTarget,
    );

    const beforeInput = extractBeforeInputEvent(
      topLevelType,
      targetInst,
      nativeEvent,
      nativeEventTarget,
    );

    if (composition === null) {
      return beforeInput;
    }

    if (beforeInput === null) {
      return composition;
    }

    return [composition, beforeInput];
  },
};

export default BeforeInputEventPlugin;
<commit_msg>Removed Presto check (#11921)<commit_after>/**
 * Copyright (c) 2013-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import type {TopLevelTypes} from './BrowserEventConstants';

import {accumulateTwoPhaseDispatches} from 'events/EventPropagators';
import ExecutionEnvironment from 'fbjs/lib/ExecutionEnvironment';

import * as FallbackCompositionState from './FallbackCompositionState';
import SyntheticCompositionEvent from './SyntheticCompositionEvent';
import SyntheticInputEvent from './SyntheticInputEvent';

const END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
const START_KEYCODE = 229;

const canUseCompositionEvent =
  ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window;

let documentMode = null;
if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) {
  documentMode = document.documentMode;
}

// Webkit offers a very useful `textInput` event that can be used to
// directly represent `beforeInput`. The IE `textinput` event is not as
// useful, so we don't use it.
const canUseTextInputEvent =
  ExecutionEnvironment.canUseDOM && 'TextEvent' in window && !documentMode;

// In IE9+, we have access to composition events, but the data supplied
// by the native compositionend event may be incorrect. Japanese ideographic
// spaces, for instance (\u3000) are not recorded correctly.
const useFallbackCompositionData =
  ExecutionEnvironment.canUseDOM &&
  (!canUseCompositionEvent ||
    (documentMode && documentMode > 8 && documentMode <= 11));

const SPACEBAR_CODE = 32;
const SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);

// Events and their corresponding property names.
const eventTypes = {
  beforeInput: {
    phasedRegistrationNames: {
      bubbled: 'onBeforeInput',
      captured: 'onBeforeInputCapture',
    },
    dependencies: [
      'topCompositionEnd',
      'topKeyPress',
      'topTextInput',
      'topPaste',
    ],
  },
  compositionEnd: {
    phasedRegistrationNames: {
      bubbled: 'onCompositionEnd',
      captured: 'onCompositionEndCapture',
    },
    dependencies: [
      'topBlur',
      'topCompositionEnd',
      'topKeyDown',
      'topKeyPress',
      'topKeyUp',
      'topMouseDown',
    ],
  },
  compositionStart: {
    phasedRegistrationNames: {
      bubbled: 'onCompositionStart',
      captured: 'onCompositionStartCapture',
    },
    dependencies: [
      'topBlur',
      'topCompositionStart',
      'topKeyDown',
      'topKeyPress',
      'topKeyUp',
      'topMouseDown',
    ],
  },
  compositionUpdate: {
    phasedRegistrationNames: {
      bubbled: 'onCompositionUpdate',
      captured: 'onCompositionUpdateCapture',
    },
    dependencies: [
      'topBlur',
      'topCompositionUpdate',
      'topKeyDown',
      'topKeyPress',
      'topKeyUp',
      'topMouseDown',
    ],
  },
};

// Track whether we've ever handled a keypress on the space key.
let hasSpaceKeypress = false;

/**
 * Return whether a native keypress event is assumed to be a command.
 * This is required because Firefox fires `keypress` events for key commands
 * (cut, copy, select-all, etc.) even though no character is inserted.
 */
function isKeypressCommand(nativeEvent) {
  return (
    (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
    // ctrlKey && altKey is equivalent to AltGr, and is not a command.
    !(nativeEvent.ctrlKey && nativeEvent.altKey)
  );
}

/**
 * Translate native top level events into event types.
 *
 * @param {string} topLevelType
 * @return {object}
 */
function getCompositionEventType(topLevelType) {
  switch (topLevelType) {
    case 'topCompositionStart':
      return eventTypes.compositionStart;
    case 'topCompositionEnd':
      return eventTypes.compositionEnd;
    case 'topCompositionUpdate':
      return eventTypes.compositionUpdate;
  }
}

/**
 * Does our fallback best-guess model think this event signifies that
 * composition has begun?
 *
 * @param {string} topLevelType
 * @param {object} nativeEvent
 * @return {boolean}
 */
function isFallbackCompositionStart(topLevelType, nativeEvent) {
  return topLevelType === 'topKeyDown' && nativeEvent.keyCode === START_KEYCODE;
}

/**
 * Does our fallback mode think that this event is the end of composition?
 *
 * @param {string} topLevelType
 * @param {object} nativeEvent
 * @return {boolean}
 */
function isFallbackCompositionEnd(topLevelType, nativeEvent) {
  switch (topLevelType) {
    case 'topKeyUp':
      // Command keys insert or clear IME input.
      return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
    case 'topKeyDown':
      // Expect IME keyCode on each keydown. If we get any other
      // code we must have exited earlier.
      return nativeEvent.keyCode !== START_KEYCODE;
    case 'topKeyPress':
    case 'topMouseDown':
    case 'topBlur':
      // Events are not possible without cancelling IME.
      return true;
    default:
      return false;
  }
}

/**
 * Google Input Tools provides composition data via a CustomEvent,
 * with the `data` property populated in the `detail` object. If this
 * is available on the event object, use it. If not, this is a plain
 * composition event and we have nothing special to extract.
 *
 * @param {object} nativeEvent
 * @return {?string}
 */
function getDataFromCustomEvent(nativeEvent) {
  const detail = nativeEvent.detail;
  if (typeof detail === 'object' && 'data' in detail) {
    return detail.data;
  }
  return null;
}

// Track the current IME composition status, if any.
let isComposing = false;

/**
 * @return {?object} A SyntheticCompositionEvent.
 */
function extractCompositionEvent(
  topLevelType,
  targetInst,
  nativeEvent,
  nativeEventTarget,
) {
  let eventType;
  let fallbackData;

  if (canUseCompositionEvent) {
    eventType = getCompositionEventType(topLevelType);
  } else if (!isComposing) {
    if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
      eventType = eventTypes.compositionStart;
    }
  } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
    eventType = eventTypes.compositionEnd;
  }

  if (!eventType) {
    return null;
  }

  if (useFallbackCompositionData) {
    // The current composition is stored statically and must not be
    // overwritten while composition continues.
    if (!isComposing && eventType === eventTypes.compositionStart) {
      isComposing = FallbackCompositionState.initialize(nativeEventTarget);
    } else if (eventType === eventTypes.compositionEnd) {
      if (isComposing) {
        fallbackData = FallbackCompositionState.getData();
      }
    }
  }

  const event = SyntheticCompositionEvent.getPooled(
    eventType,
    targetInst,
    nativeEvent,
    nativeEventTarget,
  );

  if (fallbackData) {
    // Inject data generated from fallback path into the synthetic event.
    // This matches the property of native CompositionEventInterface.
    event.data = fallbackData;
  } else {
    const customData = getDataFromCustomEvent(nativeEvent);
    if (customData !== null) {
      event.data = customData;
    }
  }

  accumulateTwoPhaseDispatches(event);
  return event;
}

/**
 * @param {TopLevelTypes} topLevelType Record from `BrowserEventConstants`.
 * @param {object} nativeEvent Native browser event.
 * @return {?string} The string corresponding to this `beforeInput` event.
 */
function getNativeBeforeInputChars(topLevelType: TopLevelTypes, nativeEvent) {
  switch (topLevelType) {
    case 'topCompositionEnd':
      return getDataFromCustomEvent(nativeEvent);
    case 'topKeyPress':
      /**
       * If native `textInput` events are available, our goal is to make
       * use of them. However, there is a special case: the spacebar key.
       * In Webkit, preventing default on a spacebar `textInput` event
       * cancels character insertion, but it *also* causes the browser
       * to fall back to its default spacebar behavior of scrolling the
       * page.
       *
       * Tracking at:
       * https://code.google.com/p/chromium/issues/detail?id=355103
       *
       * To avoid this issue, use the keypress event as if no `textInput`
       * event is available.
       */
      const which = nativeEvent.which;
      if (which !== SPACEBAR_CODE) {
        return null;
      }

      hasSpaceKeypress = true;
      return SPACEBAR_CHAR;

    case 'topTextInput':
      // Record the characters to be added to the DOM.
      const chars = nativeEvent.data;

      // If it's a spacebar character, assume that we have already handled
      // it at the keypress level and bail immediately. Android Chrome
      // doesn't give us keycodes, so we need to blacklist it.
      if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
        return null;
      }

      return chars;

    default:
      // For other native event types, do nothing.
      return null;
  }
}

/**
 * For browsers that do not provide the `textInput` event, extract the
 * appropriate string to use for SyntheticInputEvent.
 *
 * @param {string} topLevelType Record from `BrowserEventConstants`.
 * @param {object} nativeEvent Native browser event.
 * @return {?string} The fallback string for this `beforeInput` event.
 */
function getFallbackBeforeInputChars(topLevelType: TopLevelTypes, nativeEvent) {
  // If we are currently composing (IME) and using a fallback to do so,
  // try to extract the composed characters from the fallback object.
  // If composition event is available, we extract a string only at
  // compositionevent, otherwise extract it at fallback events.
  if (isComposing) {
    if (
      topLevelType === 'topCompositionEnd' ||
      (!canUseCompositionEvent &&
        isFallbackCompositionEnd(topLevelType, nativeEvent))
    ) {
      const chars = FallbackCompositionState.getData();
      FallbackCompositionState.reset();
      isComposing = false;
      return chars;
    }
    return null;
  }

  switch (topLevelType) {
    case 'topPaste':
      // If a paste event occurs after a keypress, throw out the input
      // chars. Paste events should not lead to BeforeInput events.
      return null;
    case 'topKeyPress':
      /**
       * As of v27, Firefox may fire keypress events even when no character
       * will be inserted. A few possibilities:
       *
       * - `which` is `0`. Arrow keys, Esc key, etc.
       *
       * - `which` is the pressed key code, but no char is available.
       *   Ex: 'AltGr + d` in Polish. There is no modified character for
       *   this key combination and no character is inserted into the
       *   document, but FF fires the keypress for char code `100` anyway.
       *   No `input` event will occur.
       *
       * - `which` is the pressed key code, but a command combination is
       *   being used. Ex: `Cmd+C`. No character is inserted, and no
       *   `input` event will occur.
       */
      if (!isKeypressCommand(nativeEvent)) {
        // IE fires the `keypress` event when a user types an emoji via
        // Touch keyboard of Windows.  In such a case, the `char` property
        // holds an emoji character like `\uD83D\uDE0A`.  Because its length
        // is 2, the property `which` does not represent an emoji correctly.
        // In such a case, we directly return the `char` property instead of
        // using `which`.
        if (nativeEvent.char && nativeEvent.char.length > 1) {
          return nativeEvent.char;
        } else if (nativeEvent.which) {
          return String.fromCharCode(nativeEvent.which);
        }
      }
      return null;
    case 'topCompositionEnd':
      return useFallbackCompositionData ? null : nativeEvent.data;
    default:
      return null;
  }
}

/**
 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
 * `textInput` or fallback behavior.
 *
 * @return {?object} A SyntheticInputEvent.
 */
function extractBeforeInputEvent(
  topLevelType,
  targetInst,
  nativeEvent,
  nativeEventTarget,
) {
  let chars;

  if (canUseTextInputEvent) {
    chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
  } else {
    chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
  }

  // If no characters are being inserted, no BeforeInput event should
  // be fired.
  if (!chars) {
    return null;
  }

  const event = SyntheticInputEvent.getPooled(
    eventTypes.beforeInput,
    targetInst,
    nativeEvent,
    nativeEventTarget,
  );

  event.data = chars;
  accumulateTwoPhaseDispatches(event);
  return event;
}

/**
 * Create an `onBeforeInput` event to match
 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
 *
 * This event plugin is based on the native `textInput` event
 * available in Chrome, Safari, Opera, and IE. This event fires after
 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
 *
 * `beforeInput` is spec'd but not implemented in any browsers, and
 * the `input` event does not provide any useful information about what has
 * actually been added, contrary to the spec. Thus, `textInput` is the best
 * available event to identify the characters that have actually been inserted
 * into the target node.
 *
 * This plugin is also responsible for emitting `composition` events, thus
 * allowing us to share composition fallback code for both `beforeInput` and
 * `composition` event types.
 */
const BeforeInputEventPlugin = {
  eventTypes: eventTypes,

  extractEvents: function(
    topLevelType,
    targetInst,
    nativeEvent,
    nativeEventTarget,
  ) {
    const composition = extractCompositionEvent(
      topLevelType,
      targetInst,
      nativeEvent,
      nativeEventTarget,
    );

    const beforeInput = extractBeforeInputEvent(
      topLevelType,
      targetInst,
      nativeEvent,
      nativeEventTarget,
    );

    if (composition === null) {
      return beforeInput;
    }

    if (beforeInput === null) {
      return composition;
    }

    return [composition, beforeInput];
  },
};

export default BeforeInputEventPlugin;
<|endoftext|>


<commit_before>"use strict";
/* jshint newcap:false */

var BaseState;
var BaseComponent;
var inherit;
var jQuery = require("../jquery");
var ready = require("../ready");

var complain = "MARKO_DEBUG" && require("complain");

module.exports = function defineWidget(def, renderer) {
    def = def.Widget || def;

    if (def.___isComponent) {
        return def;
    }

    var ComponentClass = function() {};
    var proto;

    if (typeof def === "function") {
        proto = def.prototype;
        proto.init = def;
    } else if (typeof def === "object") {
        proto = def;
    } else {
        throw TypeError();
    }

    ComponentClass.prototype = proto;

    // We don't use the constructor provided by the user
    // since we don't invoke their constructor until
    // we have had a chance to do our own initialization.
    // Instead, we store their constructor in the "initComponent"
    // property and that method gets called later inside
    // init-components-browser.js
    function Component(id, doc) {
        BaseComponent.call(this, id, doc);
    }

    if (!proto.___isComponent) {
        // Inherit from Component if they didn't already
        inherit(ComponentClass, BaseComponent);
    }

    // The same prototype will be used by our constructor after
    // we he have set up the prototype chain using the inherit function
    proto = Component.prototype = ComponentClass.prototype;
    proto.___isLegacy = true;

    proto.constructor = def.constructor = Component;

    Object.defineProperty(proto, "__document", {
        get: function() {
            // eslint-disable-next-line no-constant-condition
            if ("MARKO_DEBUG") {
                complain("__document is deprecated");
            }
            return this.___document;
        }
    });

    Object.defineProperty(proto, "el", {
        get: function() {
            // eslint-disable-next-line no-constant-condition
            if ("MARKO_DEBUG") {
                complain(
                    "this.el is deprecated. assign a key to the root element and use getEl(key) instead."
                );
            }
            return (
                this.getEl("_wbind") ||
                (this.___rootNode && this.___rootNode.firstChild)
            );
        }
    });

    // get legacy methods
    var init = proto.init;
    var onRender = proto.onRender;
    var onBeforeUpdate = proto.onBeforeUpdate;
    var onUpdate = proto.onUpdate;
    var onBeforeDestroy = proto.onBeforeDestroy;
    var onDestroy = proto.onDestroy;

    // delete legacy methods that conflict
    delete proto.onRender;
    delete proto.onBeforeUpdate;
    delete proto.onUpdate;
    delete proto.onBeforeDestroy;
    delete proto.onDestroy;

    proto.getWidget = proto.getComponent;
    proto.getWidgets = proto.getComponents;

    // convert legacy to modern
    var originalUpdate = proto.update;
    proto.update = function() {
        this.___legacyExplicitUpdate = true;
        onBeforeUpdate && onBeforeUpdate.call(this);
        originalUpdate.apply(this, arguments);
        this.___legacyExplicitUpdate = false;
    };

    proto.onMount = function() {
        var self = this;
        var config = this.widgetConfig;
        if (this.el) {
            Object.defineProperty(this.el, "__widget", {
                get: function() {
                    // eslint-disable-next-line no-constant-condition
                    if ("MARKO_DEBUG") {
                        complain("__widget is deprecated");
                    }
                    return self;
                }
            });
        }
        if (init) init.call(this, config || {});
        if (onRender) {
            onRender.call(this, { firstRender: true });
        }
        this.on("___legacyRender", function() {
            if (!self.___legacyExplicitUpdate && onBeforeUpdate) {
                onBeforeUpdate.call(this);
            }

            self.___didUpdate = true;
        });
        this.___input = null;
    };

    proto.onUpdate = function() {
        if (onUpdate) onUpdate.call(this);
        if (onRender && this.___didUpdate) onRender.call(this, {});
        this.___didUpdate = false;
        this.___input = null;
    };

    if (onBeforeDestroy || onDestroy) {
        proto.onDestroy = function() {
            if (onBeforeDestroy) onBeforeDestroy.call(this);
            if (onDestroy) onDestroy.call(this);
        };
    }

    // Set a flag on the constructor function to make it clear this is
    // a component so that we can short-circuit this work later
    Component.___isComponent = true;

    function State() {
        BaseState.apply(this, arguments);
    }
    inherit(State, BaseState);
    proto.___State = State;

    jQuery.patchComponent(
        window.$,
        proto,
        true /* don't throw error until used if `$` is missing*/
    );

    ready.patchComponent(proto);

    if (!renderer) {
        renderer = ComponentClass.renderer || ComponentClass.prototype.renderer;
        if (renderer) {
            // Legacy support
            var createOut = renderer.createOut;
            if (typeof renderer !== "function") {
                var rendererObject = renderer;
                renderer = function(input, out) {
                    var rendererFunc =
                        rendererObject.renderer || rendererObject.render;
                    rendererFunc(input, out);
                };
                renderer.createOut = createOut;
            }

            renderer.render = function(input) {
                var out = createOut();
                renderer(input, out);
                return out.end();
            };
        }
    }

    if (renderer) {
        // Add the rendering related methods as statics on the
        // new component constructor function
        Component.renderer = proto.___renderer = renderer;
        Component.render = renderer.render;
        Component.renderSync = renderer.renderSync;
    }

    Object.defineProperty(Component, "_isWidget", {
        get: function() {
            // eslint-disable-next-line no-constant-condition
            if ("MARKO_DEBUG") {
                complain("_isWidget is deprecated");
            }
            return true;
        }
    });

    return Component;
};

BaseState = require("./State-legacy");
BaseComponent = require("../Component");
inherit = require("raptor-util/inherit");
<commit_msg>use a for-in loop to extend the BaseComponent (doesn't support getters properly) to maintain the same behavior as marko-widgets<commit_after>"use strict";
/* jshint newcap:false */

var BaseState;
var BaseComponent;
var inherit;
var jQuery = require("../jquery");
var ready = require("../ready");

var complain = "MARKO_DEBUG" && require("complain");

module.exports = function defineWidget(def, renderer) {
    def = def.Widget || def;

    if (def.___isComponent) {
        return def;
    }

    var ComponentClass = function() {};
    var proto;

    if (typeof def === "function") {
        proto = def.prototype;
        proto.init = def;
    } else if (typeof def === "object") {
        proto = def;
    } else {
        throw TypeError();
    }

    ComponentClass.prototype = proto;

    // We don't use the constructor provided by the user
    // since we don't invoke their constructor until
    // we have had a chance to do our own initialization.
    // Instead, we store their constructor in the "initComponent"
    // property and that method gets called later inside
    // init-components-browser.js
    function Component(id, doc) {
        BaseComponent.call(this, id, doc);
    }

    if (!proto.___isComponent) {
        // Inherit from Component if they didn't already
        ComponentClass.prototype = Object.create(BaseComponent.prototype);
        for (var propName in proto) {
            if (proto.hasOwnProperty(propName)) {
                ComponentClass.prototype[propName] = proto[propName];
            }
        }
    }

    // The same prototype will be used by our constructor after
    // we he have set up the prototype chain using the inherit function
    proto = Component.prototype = ComponentClass.prototype;
    proto.___isLegacy = true;

    proto.constructor = def.constructor = Component;

    Object.defineProperty(proto, "__document", {
        get: function() {
            // eslint-disable-next-line no-constant-condition
            if ("MARKO_DEBUG") {
                complain("__document is deprecated");
            }
            return this.___document;
        }
    });

    Object.defineProperty(proto, "el", {
        get: function() {
            // eslint-disable-next-line no-constant-condition
            if ("MARKO_DEBUG") {
                complain(
                    "this.el is deprecated. assign a key to the root element and use getEl(key) instead."
                );
            }
            return (
                this.getEl("_wbind") ||
                (this.___rootNode && this.___rootNode.firstChild)
            );
        }
    });

    // get legacy methods
    var init = proto.init;
    var onRender = proto.onRender;
    var onBeforeUpdate = proto.onBeforeUpdate;
    var onUpdate = proto.onUpdate;
    var onBeforeDestroy = proto.onBeforeDestroy;
    var onDestroy = proto.onDestroy;

    // delete legacy methods that conflict
    delete proto.onRender;
    delete proto.onBeforeUpdate;
    delete proto.onUpdate;
    delete proto.onBeforeDestroy;
    delete proto.onDestroy;

    proto.getWidget = proto.getComponent;
    proto.getWidgets = proto.getComponents;

    // convert legacy to modern
    var originalUpdate = proto.update;
    proto.update = function() {
        this.___legacyExplicitUpdate = true;
        onBeforeUpdate && onBeforeUpdate.call(this);
        originalUpdate.apply(this, arguments);
        this.___legacyExplicitUpdate = false;
    };

    proto.onMount = function() {
        var self = this;
        var config = this.widgetConfig;
        if (this.el) {
            Object.defineProperty(this.el, "__widget", {
                get: function() {
                    // eslint-disable-next-line no-constant-condition
                    if ("MARKO_DEBUG") {
                        complain("__widget is deprecated");
                    }
                    return self;
                }
            });
        }
        if (init) init.call(this, config || {});
        if (onRender) {
            onRender.call(this, { firstRender: true });
        }
        this.on("___legacyRender", function() {
            if (!self.___legacyExplicitUpdate && onBeforeUpdate) {
                onBeforeUpdate.call(this);
            }

            self.___didUpdate = true;
        });
        this.___input = null;
    };

    proto.onUpdate = function() {
        if (onUpdate) onUpdate.call(this);
        if (onRender && this.___didUpdate) onRender.call(this, {});
        this.___didUpdate = false;
        this.___input = null;
    };

    if (onBeforeDestroy || onDestroy) {
        proto.onDestroy = function() {
            if (onBeforeDestroy) onBeforeDestroy.call(this);
            if (onDestroy) onDestroy.call(this);
        };
    }

    // Set a flag on the constructor function to make it clear this is
    // a component so that we can short-circuit this work later
    Component.___isComponent = true;

    function State() {
        BaseState.apply(this, arguments);
    }
    inherit(State, BaseState);
    proto.___State = State;

    jQuery.patchComponent(
        window.$,
        proto,
        true /* don't throw error until used if `$` is missing*/
    );

    ready.patchComponent(proto);

    if (!renderer) {
        renderer = ComponentClass.renderer || ComponentClass.prototype.renderer;
        if (renderer) {
            // Legacy support
            var createOut = renderer.createOut;
            if (typeof renderer !== "function") {
                var rendererObject = renderer;
                renderer = function(input, out) {
                    var rendererFunc =
                        rendererObject.renderer || rendererObject.render;
                    rendererFunc(input, out);
                };
                renderer.createOut = createOut;
            }

            renderer.render = function(input) {
                var out = createOut();
                renderer(input, out);
                return out.end();
            };
        }
    }

    if (renderer) {
        // Add the rendering related methods as statics on the
        // new component constructor function
        Component.renderer = proto.___renderer = renderer;
        Component.render = renderer.render;
        Component.renderSync = renderer.renderSync;
    }

    Object.defineProperty(Component, "_isWidget", {
        get: function() {
            // eslint-disable-next-line no-constant-condition
            if ("MARKO_DEBUG") {
                complain("_isWidget is deprecated");
            }
            return true;
        }
    });

    return Component;
};

BaseState = require("./State-legacy");
BaseComponent = require("../Component");
inherit = require("raptor-util/inherit");
<|endoftext|>


<commit_before>/**
 * @overview Notification service for Kabam application
 */
angular.module('ng-kabam-notification', [])
  .factory('WebNotification', function() {
    return {

      /**
       * To check if Web Notification is supported or not in running browser.
       * @service isSupported
       * @return {Boolean} return true if Web Notification is supported
       */
      isSupported: function() {
        var webNotifIsSupported = ('Notification' in window) ? true : false;
        return webNotifIsSupported;
      },
      /**
       * To request Web Notification permission
       */
      requestPermission: function() {
        var userAgent = navigator.userAgent,
          notification = null;

        var FIREFOX_USER_AGENT = userAgent.match(/Firefox\//),
          CHROME_USER_AGENT = userAgent.match(/Chrome\//);

        if (FIREFOX_USER_AGENT) {
          notification = Notification;
        } else if (CHROME_USER_AGENT) {
          notification = webkitNotifications;
        }

        if (notification && notification.permission !== 'denied') {

          notification.requestPermission(function(status) {
            if (notification.permission !== status) {
              notification.permission = status;
            }
          });
        }
      }
    };
  });<commit_msg>docs(service): add more docs about the Web Notification service<commit_after>/**
 * @overview Web Notification service for Kabam application
 * @ngdoc service
 *
 * @description service that carry out specific tasks like
 * requesting permission, checking the notification permission status,
 * so this Notification service kinda like a wrapper to access the
 * Web Notification.
 *
 * Notes on Google Chrome usage:
 * There's one very important caveat about requesting permission:
 * the page can only request permission when a user initiates some action on
 * a page, in this case, clicking on a button. So, when using this directive
 * only click event will work best on Google Chrome, otherwise will not be
 * working as expected.
 */
angular.module('ng-kabam-notification', [])
  .factory('WebNotification', function() {
    return {

      /**
       * To check if Web Notification is supported or not in running browser.
       * @service isSupported
       * @return {Boolean} return true if Web Notification is supported
       */
      isSupported: function() {
        var webNotifIsSupported = ('Notification' in window) ? true : false;
        return webNotifIsSupported;
      },
      /**
       * To request Web Notification permission
       */
      requestPermission: function() {
        var userAgent = navigator.userAgent,
          notification = null;

        var FIREFOX_USER_AGENT = userAgent.match(/Firefox\//),
          CHROME_USER_AGENT = userAgent.match(/Chrome\//);

        if (FIREFOX_USER_AGENT) {
          notification = Notification;
        } else if (CHROME_USER_AGENT) {
          notification = webkitNotifications;
        }

        if (notification && notification.permission !== 'denied') {

          notification.requestPermission(function(status) {
            if (notification.permission !== status) {
              notification.permission = status;
            }
          });
        }
      }
    };
  });<|endoftext|>


<commit_before>/**
 * Binding observer.fire to keydown event.
 */
document.addEventListener("keydown", function(event){keydown_observer.fire(event)}, false);

/**
 * KeyDown event observer.
 */
var keydown_observer = new function(){

    this.listeners = {};

    this.emulate_key = function(key_code){

        this.fire({"keyCode" : key_code});
    };

    this.fire = function(e){

        var code = e.keyCode || e.which;

        if (stb && stb.key_lock === true && code != key.FRAME){
            _debug('key locked');
            return;
        }

        if (e.shiftKey){
            code += 1000;
        }

        if (e.altKey){
            code += 2000;
        }

        _debug('code:', code);

        var item;
        var priority_item;
        var normal_item;

        if (this.listeners.hasOwnProperty(code)){
            for(var i=0; i<this.listeners[code].length; i++){

                item = this.listeners[code][i];

                if (item.c.hasOwnProperty('con_menu')){
                    if (item.c.con_menu.on){
                        continue;
                    }
                }

                if (item.c.on && item.priority){
                    priority_item = item;
                    break;
                } else if (item.c.on || item.c === window){
                    if (!normal_item){
                        normal_item = item;
                    }
                }
            }

            if (priority_item){
                priority_item.f.apply(priority_item.c, priority_item.a);
            }else if (normal_item){
                normal_item.f.apply(normal_item.c, normal_item.a);
            }

        }

        _debug('keydown exit');

        this.triggerCustomEventListener('keypress', e);
    }
};

/**
 * Binding function to key.
 * @param {number} key
 * @param {Object} context The object to be used as the value of 'this' within 'f'
 * @param {*} args
 * @return {Function}
 */
Function.prototype.bind = function(key, context, args){
    context = context || window;
    keydown_observer.listeners[key] = keydown_observer.listeners[key] || [];
    args = Array.prototype.splice.apply(arguments, [2, arguments.length]);
    keydown_observer.listeners[key].unshift({"f" : this, "c" : context, "a" : args});
    return this;
};

Function.prototype.priority_bind = function(key, context, args){
    context = context || window;
    keydown_observer.listeners[key] = keydown_observer.listeners[key] || [];
    args = Array.prototype.splice.apply(arguments, [2, arguments.length]);
    keydown_observer.listeners[key].unshift({"f" : this, "c" : context, "a" : args, "priority" : true});
    return this;
};<commit_msg>Added filter for zero keys<commit_after>/**
 * Binding observer.fire to keydown event.
 */
document.addEventListener("keydown", function(event){keydown_observer.fire(event)}, false);

/**
 * KeyDown event observer.
 */
var keydown_observer = new function(){

    this.listeners = {};

    this.emulate_key = function(key_code){

        this.fire({"keyCode" : key_code});
    };

    this.fire = function(e){

        var code = e.keyCode || e.which;

        if (stb && stb.key_lock === true && code != key.FRAME){
            _debug('key locked');
            return;
        }

        if (e.shiftKey){
            code += 1000;
        }

        if (e.altKey){
            code += 2000;
        }

        _debug('code:', code);

        if ([1000, 2000, 3000].indexOf(code) >= 0){
            return;
        }

        var item;
        var priority_item;
        var normal_item;

        if (this.listeners.hasOwnProperty(code)){
            for(var i=0; i<this.listeners[code].length; i++){

                item = this.listeners[code][i];

                if (item.c.hasOwnProperty('con_menu')){
                    if (item.c.con_menu.on){
                        continue;
                    }
                }

                if (item.c.on && item.priority){
                    priority_item = item;
                    break;
                } else if (item.c.on || item.c === window){
                    if (!normal_item){
                        normal_item = item;
                    }
                }
            }

            if (priority_item){
                priority_item.f.apply(priority_item.c, priority_item.a);
            }else if (normal_item){
                normal_item.f.apply(normal_item.c, normal_item.a);
            }

        }

        _debug('keydown handler exit');

        this.triggerCustomEventListener('keypress', e);
    }
};

/**
 * Binding function to key.
 * @param {number} key
 * @param {Object} context The object to be used as the value of 'this' within 'f'
 * @param {*} args
 * @return {Function}
 */
Function.prototype.bind = function(key, context, args){
    context = context || window;
    keydown_observer.listeners[key] = keydown_observer.listeners[key] || [];
    args = Array.prototype.splice.apply(arguments, [2, arguments.length]);
    keydown_observer.listeners[key].unshift({"f" : this, "c" : context, "a" : args});
    return this;
};

Function.prototype.priority_bind = function(key, context, args){
    context = context || window;
    keydown_observer.listeners[key] = keydown_observer.listeners[key] || [];
    args = Array.prototype.splice.apply(arguments, [2, arguments.length]);
    keydown_observer.listeners[key].unshift({"f" : this, "c" : context, "a" : args, "priority" : true});
    return this;
};<|endoftext|>


<commit_before>/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule EventPropagators
 */

'use strict';

var EventPluginHub = require('EventPluginHub');
var ReactTreeTraversal = require('ReactTreeTraversal');

var accumulateInto = require('accumulateInto');
var forEachAccumulated = require('forEachAccumulated');
var warning = require('warning');

import type { PropagationPhases } from 'EventConstants';

var getListener = EventPluginHub.getListener;

/**
 * Some event types have a notion of different registration names for different
 * "phases" of propagation. This finds listeners by a given phase.
 */
function listenerAtPhase(inst, event, propagationPhase: PropagationPhases) {
  var registrationName =
    event.dispatchConfig.phasedRegistrationNames[propagationPhase];
  return getListener(inst, registrationName);
}

/**
 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
 * here, allows us to not have to bind or create functions for each event.
 * Mutating the event's members allows us to not have to create a wrapping
 * "dispatch" object that pairs the event with the listener.
 */
function accumulateDirectionalDispatches(inst, phase, event) {
  if (__DEV__) {
    warning(
      inst,
      'Dispatching inst must not be null'
    );
  }
  var listener = listenerAtPhase(inst, event, phase);
  if (listener) {
    event._dispatchListeners =
      accumulateInto(event._dispatchListeners, listener);
    event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
  }
}

/**
 * Collect dispatches (must be entirely collected before dispatching - see unit
 * tests). Lazily allocate the array to conserve memory.  We must loop through
 * each event and perform the traversal for each one. We cannot perform a
 * single traversal for the entire collection of events because each event may
 * have a different target.
 */
function accumulateTwoPhaseDispatchesSingle(event) {
  if (event && event.dispatchConfig.phasedRegistrationNames) {
    ReactTreeTraversal.traverseTwoPhase(
      event._targetInst,
      accumulateDirectionalDispatches,
      event
    );
  }
}

/**
 * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID.
 */
function accumulateTwoPhaseDispatchesSingleSkipTarget(event) {
  if (event && event.dispatchConfig.phasedRegistrationNames) {
    var targetInst = event._targetInst;
    var parentInst =
      targetInst ? ReactTreeTraversal.getParentInstance(targetInst) : null;
    ReactTreeTraversal.traverseTwoPhase(
      parentInst,
      accumulateDirectionalDispatches,
      event
    );
  }
}

/**
 * Accumulates without regard to direction, does not look for phased
 * registration names. Same as `accumulateDirectDispatchesSingle` but without
 * requiring that the `dispatchMarker` be the same as the dispatched ID.
 */
function accumulateDispatches(inst, ignoredDirection, event) {
  if (event && event.dispatchConfig.registrationName) {
    var registrationName = event.dispatchConfig.registrationName;
    var listener = getListener(inst, registrationName);
    if (listener) {
      event._dispatchListeners =
        accumulateInto(event._dispatchListeners, listener);
      event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
    }
  }
}

/**
 * Accumulates dispatches on an `SyntheticEvent`, but only for the
 * `dispatchMarker`.
 * @param {SyntheticEvent} event
 */
function accumulateDirectDispatchesSingle(event) {
  if (event && event.dispatchConfig.registrationName) {
    accumulateDispatches(event._targetInst, null, event);
  }
}

function accumulateTwoPhaseDispatches(events) {
  forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
}

function accumulateTwoPhaseDispatchesSkipTarget(events) {
  forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget);
}

function accumulateEnterLeaveDispatches(leave, enter, from, to) {
  ReactTreeTraversal.traverseEnterLeave(
    from,
    to,
    accumulateDispatches,
    leave,
    enter
  );
}

function accumulateDirectDispatches(events) {
  forEachAccumulated(events, accumulateDirectDispatchesSingle);
}

/**
 * A small set of propagation patterns, each of which will accept a small amount
 * of information, and generate a set of "dispatch ready event objects" - which
 * are sets of events that have already been annotated with a set of dispatched
 * listener functions/ids. The API is designed this way to discourage these
 * propagation strategies from actually executing the dispatches, since we
 * always want to collect the entire set of dispatches before executing event a
 * single one.
 *
 * @constructor EventPropagators
 */
var EventPropagators = {
  accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches,
  accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget,
  accumulateDirectDispatches: accumulateDirectDispatches,
  accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches,
};

module.exports = EventPropagators;
<commit_msg>Fix typo in EventPropagators.js (#8879)<commit_after>/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule EventPropagators
 */

'use strict';

var EventPluginHub = require('EventPluginHub');
var ReactTreeTraversal = require('ReactTreeTraversal');

var accumulateInto = require('accumulateInto');
var forEachAccumulated = require('forEachAccumulated');
var warning = require('warning');

import type { PropagationPhases } from 'EventConstants';

var getListener = EventPluginHub.getListener;

/**
 * Some event types have a notion of different registration names for different
 * "phases" of propagation. This finds listeners by a given phase.
 */
function listenerAtPhase(inst, event, propagationPhase: PropagationPhases) {
  var registrationName =
    event.dispatchConfig.phasedRegistrationNames[propagationPhase];
  return getListener(inst, registrationName);
}

/**
 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
 * here, allows us to not have to bind or create functions for each event.
 * Mutating the event's members allows us to not have to create a wrapping
 * "dispatch" object that pairs the event with the listener.
 */
function accumulateDirectionalDispatches(inst, phase, event) {
  if (__DEV__) {
    warning(
      inst,
      'Dispatching inst must not be null'
    );
  }
  var listener = listenerAtPhase(inst, event, phase);
  if (listener) {
    event._dispatchListeners =
      accumulateInto(event._dispatchListeners, listener);
    event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
  }
}

/**
 * Collect dispatches (must be entirely collected before dispatching - see unit
 * tests). Lazily allocate the array to conserve memory.  We must loop through
 * each event and perform the traversal for each one. We cannot perform a
 * single traversal for the entire collection of events because each event may
 * have a different target.
 */
function accumulateTwoPhaseDispatchesSingle(event) {
  if (event && event.dispatchConfig.phasedRegistrationNames) {
    ReactTreeTraversal.traverseTwoPhase(
      event._targetInst,
      accumulateDirectionalDispatches,
      event
    );
  }
}

/**
 * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID.
 */
function accumulateTwoPhaseDispatchesSingleSkipTarget(event) {
  if (event && event.dispatchConfig.phasedRegistrationNames) {
    var targetInst = event._targetInst;
    var parentInst =
      targetInst ? ReactTreeTraversal.getParentInstance(targetInst) : null;
    ReactTreeTraversal.traverseTwoPhase(
      parentInst,
      accumulateDirectionalDispatches,
      event
    );
  }
}

/**
 * Accumulates without regard to direction, does not look for phased
 * registration names. Same as `accumulateDirectDispatchesSingle` but without
 * requiring that the `dispatchMarker` be the same as the dispatched ID.
 */
function accumulateDispatches(inst, ignoredDirection, event) {
  if (event && event.dispatchConfig.registrationName) {
    var registrationName = event.dispatchConfig.registrationName;
    var listener = getListener(inst, registrationName);
    if (listener) {
      event._dispatchListeners =
        accumulateInto(event._dispatchListeners, listener);
      event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
    }
  }
}

/**
 * Accumulates dispatches on an `SyntheticEvent`, but only for the
 * `dispatchMarker`.
 * @param {SyntheticEvent} event
 */
function accumulateDirectDispatchesSingle(event) {
  if (event && event.dispatchConfig.registrationName) {
    accumulateDispatches(event._targetInst, null, event);
  }
}

function accumulateTwoPhaseDispatches(events) {
  forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
}

function accumulateTwoPhaseDispatchesSkipTarget(events) {
  forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget);
}

function accumulateEnterLeaveDispatches(leave, enter, from, to) {
  ReactTreeTraversal.traverseEnterLeave(
    from,
    to,
    accumulateDispatches,
    leave,
    enter
  );
}

function accumulateDirectDispatches(events) {
  forEachAccumulated(events, accumulateDirectDispatchesSingle);
}

/**
 * A small set of propagation patterns, each of which will accept a small amount
 * of information, and generate a set of "dispatch ready event objects" - which
 * are sets of events that have already been annotated with a set of dispatched
 * listener functions/ids. The API is designed this way to discourage these
 * propagation strategies from actually executing the dispatches, since we
 * always want to collect the entire set of dispatches before executing even a
 * single one.
 *
 * @constructor EventPropagators
 */
var EventPropagators = {
  accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches,
  accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget,
  accumulateDirectDispatches: accumulateDirectDispatches,
  accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches,
};

module.exports = EventPropagators;
<|endoftext|>