<NME> util.js
<BEF> /*globals fdom:true, crypto, freedomcfg, WebKitBlobBuilder, Blob, URL */
/*globals webkitURL, Uint8Array, Uint16Array, ArrayBuffer */
/*jslint indent:2,white:true,browser:true,sloppy:true */
if (typeof fdom === 'undefined') {
  fdom = {};
}

/**
 * Utility method used within the freedom Library.
 * @class util
 * @static
 */
fdom.util = {};


/**
 * returns a true value, it will break out of the loop.
 * @method eachReverse
 * @method eachReverse
 * @static
 */
fdom.util.eachReverse = function(ary, func) {
  if (ary) {
    var i;
    for (i = ary.length - 1; i > -1; i -= 1) {
        break;
      }
    }
  }
};

/**
 * @method hasProp
 * @method hasProp
 * @static
 */
fdom.util.hasProp = function(obj, prop) {
  return Object.prototype.hasOwnProperty.call(obj, prop);
};

 * Cycles over properties in an object and calls a function for each
 * property value. If the function returns a truthy value, then the
 * iteration is stopped.
 * @method eachProp
 * @method eachProp
 * @static
 */
fdom.util.eachProp = function(obj, func) {
  var prop;
  for (prop in obj) {
    if (obj.hasOwnProperty(prop)) {
        break;
      }
    }
  }
};

/**
 * Simple function to mix in properties from source into target,
 * but only if target does not already have a property of the same name.
 * This is not robust in IE for transferring methods that match
 * Object.prototype names, but the uses of mixin here seem unlikely to
 * trigger a problem related to that.
 * @method mixin
 * @method mixin
 * @static
 */
fdom.util.mixin = function(target, source, force) {
  if (source) {
    fdom.util.eachProp(source, function (value, prop) {
      if (force || !fdom.util.hasProp(target, prop)) {
        target[prop] = value;
      }
    });
  return target;
};

/**
 * Get a unique ID.
 * @method getId
 * @method getId
 * @static
 */
fdom.util.getId = function() {
  var guid = 'guid',
      domain = 12,
      buffer;
  if (typeof crypto === 'object') {
    buffer = new Uint8Array(domain);
    crypto.getRandomValues(buffer);
    fdom.util.eachReverse(buffer, function(n) {
      guid += '-' + n;
    });
  } else {
  } else if (typeof crypto === 'object' && crypto.randomBytes) {
    buffer = crypto.randomBytes(domain);
    util.eachReverse(buffer, function(n) {
      guid += '-' + n;
    });
  } else {
    while (domain > 0) {
      guid += '-' + Math.ceil(255 * Math.random());
      domain -= 1;
    }
  }

  return guid;
};
 * @param {String} str The string to encode.
 * @returns {ArrayBuffer} The encoded string.
 */
fdom.util.str2ab = function(str) {
  var length = str.length,
      buffer = new ArrayBuffer(length * 2), // 2 bytes for each char
      bufferView = new Uint16Array(buffer),
 * @returns {ArrayBuffer} The encoded string.
 */
util.str2ab = function(str) {
  var length = str.length,
      buffer = new ArrayBuffer(length * 2), // 2 bytes for each char
      bufferView = new Uint16Array(buffer),
      i;
  for (i = 0; i < length; i += 1) {
    bufferView[i] = str.charCodeAt(i);
  }

  return buffer;
 * @param {ArrayBuffer} buffer The buffer to unwrap.
 * @returns {String} The decoded buffer.
 */
fdom.util.ab2str = function(buffer) {
  return String.fromCharCode.apply(null, new Uint16Array(buffer));
};

/**
 * Get a logger that logs messages prefixed by a given name.
 * @method getLogger
 * @static
 * @param {String} name The prefix for logged messages.
 * @returns {Console} A console-like object.
 */
fdom.util.getLogger = function(name) {
  var log = function(severity, source) {
    var args = Array.prototype.splice.call(arguments, 2);
    this.format(severity, source, args);
  },
  logger = {
    debug: log.bind(fdom.debug, 'debug', name),
    info: log.bind(fdom.debug, 'info', name),
    log: log.bind(fdom.debug, 'log', name),
    warn: log.bind(fdom.debug, 'warn', name),
    error: log.bind(fdom.debug, 'error', name),
    freedom: true
  };
  return logger;
};

/**
 * Add 'on' and 'emit' methods to an object, which act as a light weight
 * event handling structure.
 * @class handleEvents
 * @static
 */
fdom.util.handleEvents = function(obj) {
  var eventState = {
    multiple: {},
    maybemultiple: [],

/**
 * Add 'on' and 'emit' methods to an object, which act as a light weight
 * event handling structure.
 * @class handleEvents
 * @static
 */
util.handleEvents = function(obj) {
  var eventState = {
    DEBUG_BACKREF: obj,
    multiple: {},
    maybemultiple: [],
    single: {},
    maybesingle: []
  }, filter, push;

  /**
   * Filter a list based on a predicate. The list is filtered in place, with
   * selected items removed and returned by the function.
   * @method
   * @param {Array} list The list to filter
   * @param {Function} predicate The method to run on each item.
   * @returns {Array} Selected items
   */
  filter = function(list, predicate) {
    var ret = [], i;

    if (!list || !list.length) {
      return [];
    }

    for (i = list.length - 1; i >= 0; i -= 1) {
      if (predicate(list[i])) {
        ret.push(list.splice(i, 1));
      }
    }
    return ret;
  };

  /**
   * Enqueue a handler for a specific type.
   * @method
   * @param {String} to The queue ('single' or 'multiple') to queue on.
   * @param {String} type The type of event to wait for.
   * @param {Function} handler The handler to enqueue.
   */
  push = function(to, type, handler) {
    if (typeof type === 'function') {
      this['maybe' + to].push([type, handler]);
    } else if (this[to][type]) {
      this[to][type].push(handler);
    } else {
      this[to][type] = [handler];
    }
  };

  /**
   * Register a method to be executed when an event of a specific type occurs.
   * @method on
   * @param {String|Function} type The type of event to register against.
   * @param {Function} handler The handler to run when the event occurs.
   */
  obj.on = push.bind(eventState, 'multiple');

  /**
   * Register a method to be execute the next time an event occurs.
   * @method once
   * @param {String|Function} type The type of event to wait for.
   * @param {Function} handler The handler to run the next time a matching event
   *     is raised.
   */
  obj.once = push.bind(eventState, 'single');

  /**
   * Emit an event on this object.
   * @method emit
   * @param {String} type The type of event to raise.
   * @param {Object} data The payload of the event.
   */
  obj.emit = function(type, data) {
    var i, queue;
    // Note that registered handlers may stop events on the object, by calling
    // this.off(). As such, the presence of these keys must be checked on each
    // iteration of the relevant loops.
    for (i = 0; this.multiple[type] &&
         i < this.multiple[type].length; i += 1) {
      if (this.multiple[type][i](data) === false) {
        return;
      }
    }
    if (this.single[type]) {
      queue = this.single[type];
      this.single[type] = [];
      for (i = 0; i < queue.length; i += 1) {
        queue[i](data);
      }
    }
    for (i = 0; i < this.maybemultiple.length; i += 1) {
      if (this.maybemultiple[i][0](type, data)) {
        this.maybemultiple[i][1](data);
      }
    }
    for (i = this.maybesingle.length - 1; i >= 0; i -= 1) {
      if (this.maybesingle[i][0](type, data)) {
        queue = this.maybesingle.splice(i, 1);
        queue[0][1](data);
      }
    }
  }.bind(eventState);

  /**
   * Remove an event handler
   * @method off
   * @param {String} type The type of event to remove.
   * @param {Function?} handler The handler to remove.
   */
  obj.off = function(type, handler) {
    if (!type) {
      delete this.DEBUG_BACKREF;
      this.multiple = {};
      this.maybemultiple = [];
      this.single = {};
      this.maybesingle = [];
      return;
    }

    if (typeof type === 'function') {
      filter(this.maybesingle, function(item) {
        return item[0] === type && (!handler || item[1] === handler);
      });
      filter(this.maybemultiple, function(item) {
        return item[0] === type && (!handler || item[1] === handler);
      });
    }

    if (!handler) {
      delete this.multiple[type];
      delete this.single[type];
    } else {
 * @static
 */
/*!@preserve StartModuleContextDeclaration*/
fdom.util.isModuleContext = function() {
  return (typeof document === 'undefined');
};

  }.bind(eventState);
};

/**
 * @method forceModuleContext
 * @static
 */
fdom.util.forceModuleContext = function(src) {
  var definition = "function () { return true; }",
      idx = src.indexOf('StartModuleContextDeclaration'),
      funcidx = src.indexOf('function', idx),
      source,
      blob;
  if (idx === -1 || funcidx === -1) {
    fdom.debug.error('Unable to force mode, source is in unexpected condition.');
    return;
  }
  source = src.substr(0, funcidx) +  definition + ' || ' +
      src.substr(funcidx);
  blob = fdom.util.getBlob(source, 'text/javascript');
  return fdom.util.getURL(blob);
};

/**
    var builder = new WebKitBlobBuilder();
    builder.append(data);
    return builder.getBlob(type);
 * @method getBlob
 * @static
 */
fdom.util.getBlob = function(data, type) {
  if (typeof Blob !== 'function' && typeof WebKitBlobBuilder !== 'undefined') {
    var builder = new WebKitBlobBuilder();
    builder.append(data);
 * @method scripts
 * @static
 */
util.scripts = function(global) {
  return global.document.getElementsByTagName('script');
};

module.exports = util;
 * @method getURL
 * @static
 */
fdom.util.getURL = function(blob) {
  if (typeof URL !== 'object' && typeof webkitURL !== 'undefined') {
    return webkitURL.createObjectURL(blob);
  } else {
  }
};

/**
 * When running in a priviledged context, honor a global
 * 'freedomcfg' function to allow registration of additional API providers.
 * @method advertise
 * @param {Boolean} force Advertise even if not in a priviledged context.
 * @static
 */
fdom.util.advertise = function(force) {
  // TODO: Determine a better mechanism than this whitelisting.
  if (typeof location !== 'undefined') {
    if ((location.protocol === 'chrome-extension:' ||
        location.protocol === 'chrome:' ||
        location.protocol === 'resource:' || force) &&
        typeof freedomcfg !== "undefined") {
      freedomcfg(fdom.apis.register.bind(fdom.apis));
    }
  } else if (force && typeof freedomcfg !== "undefined") {
    freedomcfg(fdom.apis.register.bind(fdom.apis));
  }
};

/**
 * Find all scripts on the given page.
 * @method scripts
 * @static
 */
fdom.util.scripts = function(global) {
  return global.document.getElementsByTagName('script');
};

<MSG> start of refactoring freedom core into a require structure, rather than the previous concatination.

<DFF> @@ -1,16 +1,14 @@
-/*globals fdom:true, crypto, freedomcfg, WebKitBlobBuilder, Blob, URL */
+/*globals crypto, WebKitBlobBuilder, Blob, URL */
 /*globals webkitURL, Uint8Array, Uint16Array, ArrayBuffer */
-/*jslint indent:2,white:true,browser:true,sloppy:true */
-if (typeof fdom === 'undefined') {
-  fdom = {};
-}
+/*jslint indent:2,white:true,browser:true,node:true,sloppy:true */
+var debug = require('debug');
 
 /**
  * Utility method used within the freedom Library.
  * @class util
  * @static
  */
-fdom.util = {};
+var util = {};
 
 
 /**
@@ -19,7 +17,7 @@ fdom.util = {};
  * @method eachReverse
  * @static
  */
-fdom.util.eachReverse = function(ary, func) {
+util.eachReverse = function(ary, func) {
   if (ary) {
     var i;
     for (i = ary.length - 1; i > -1; i -= 1) {
@@ -34,7 +32,7 @@ fdom.util.eachReverse = function(ary, func) {
  * @method hasProp
  * @static
  */
-fdom.util.hasProp = function(obj, prop) {
+util.hasProp = function(obj, prop) {
   return Object.prototype.hasOwnProperty.call(obj, prop);
 };
 
@@ -45,7 +43,7 @@ fdom.util.hasProp = function(obj, prop) {
  * @method eachProp
  * @static
  */
-fdom.util.eachProp = function(obj, func) {
+util.eachProp = function(obj, func) {
   var prop;
   for (prop in obj) {
     if (obj.hasOwnProperty(prop)) {
@@ -65,10 +63,10 @@ fdom.util.eachProp = function(obj, func) {
  * @method mixin
  * @static
  */
-fdom.util.mixin = function(target, source, force) {
+util.mixin = function(target, source, force) {
   if (source) {
-    fdom.util.eachProp(source, function (value, prop) {
-      if (force || !fdom.util.hasProp(target, prop)) {
+    util.eachProp(source, function (value, prop) {
+      if (force || !util.hasProp(target, prop)) {
         target[prop] = value;
       }
     });
@@ -81,14 +79,14 @@ fdom.util.mixin = function(target, source, force) {
  * @method getId
  * @static
  */
-fdom.util.getId = function() {
+util.getId = function() {
   var guid = 'guid',
       domain = 12,
       buffer;
   if (typeof crypto === 'object') {
     buffer = new Uint8Array(domain);
     crypto.getRandomValues(buffer);
-    fdom.util.eachReverse(buffer, function(n) {
+    util.eachReverse(buffer, function(n) {
       guid += '-' + n;
     });
   } else {
@@ -109,7 +107,7 @@ fdom.util.getId = function() {
  * @param {String} str The string to encode.
  * @returns {ArrayBuffer} The encoded string.
  */
-fdom.util.str2ab = function(str) {
+util.str2ab = function(str) {
   var length = str.length,
       buffer = new ArrayBuffer(length * 2), // 2 bytes for each char
       bufferView = new Uint16Array(buffer),
@@ -128,40 +126,17 @@ fdom.util.str2ab = function(str) {
  * @param {ArrayBuffer} buffer The buffer to unwrap.
  * @returns {String} The decoded buffer.
  */
-fdom.util.ab2str = function(buffer) {
+util.ab2str = function(buffer) {
   return String.fromCharCode.apply(null, new Uint16Array(buffer));
 };
 
-/**
- * Get a logger that logs messages prefixed by a given name.
- * @method getLogger
- * @static
- * @param {String} name The prefix for logged messages.
- * @returns {Console} A console-like object.
- */
-fdom.util.getLogger = function(name) {
-  var log = function(severity, source) {
-    var args = Array.prototype.splice.call(arguments, 2);
-    this.format(severity, source, args);
-  },
-  logger = {
-    debug: log.bind(fdom.debug, 'debug', name),
-    info: log.bind(fdom.debug, 'info', name),
-    log: log.bind(fdom.debug, 'log', name),
-    warn: log.bind(fdom.debug, 'warn', name),
-    error: log.bind(fdom.debug, 'error', name),
-    freedom: true
-  };
-  return logger;
-};
-
 /**
  * Add 'on' and 'emit' methods to an object, which act as a light weight
  * event handling structure.
  * @class handleEvents
  * @static
  */
-fdom.util.handleEvents = function(obj) {
+util.handleEvents = function(obj) {
   var eventState = {
     multiple: {},
     maybemultiple: [],
@@ -307,7 +282,7 @@ fdom.util.handleEvents = function(obj) {
  * @static
  */
 /*!@preserve StartModuleContextDeclaration*/
-fdom.util.isModuleContext = function() {
+util.isModuleContext = function() {
   return (typeof document === 'undefined');
 };
 
@@ -318,20 +293,20 @@ fdom.util.isModuleContext = function() {
  * @method forceModuleContext
  * @static
  */
-fdom.util.forceModuleContext = function(src) {
+util.forceModuleContext = function(src) {
   var definition = "function () { return true; }",
       idx = src.indexOf('StartModuleContextDeclaration'),
       funcidx = src.indexOf('function', idx),
       source,
       blob;
   if (idx === -1 || funcidx === -1) {
-    fdom.debug.error('Unable to force mode, source is in unexpected condition.');
+    debug.error('Unable to force mode, source is in unexpected condition.');
     return;
   }
   source = src.substr(0, funcidx) +  definition + ' || ' +
       src.substr(funcidx);
-  blob = fdom.util.getBlob(source, 'text/javascript');
-  return fdom.util.getURL(blob);
+  blob = util.getBlob(source, 'text/javascript');
+  return util.getURL(blob);
 };
 
 /**
@@ -341,7 +316,7 @@ fdom.util.forceModuleContext = function(src) {
  * @method getBlob
  * @static
  */
-fdom.util.getBlob = function(data, type) {
+util.getBlob = function(data, type) {
   if (typeof Blob !== 'function' && typeof WebKitBlobBuilder !== 'undefined') {
     var builder = new WebKitBlobBuilder();
     builder.append(data);
@@ -358,7 +333,7 @@ fdom.util.getBlob = function(data, type) {
  * @method getURL
  * @static
  */
-fdom.util.getURL = function(blob) {
+util.getURL = function(blob) {
   if (typeof URL !== 'object' && typeof webkitURL !== 'undefined') {
     return webkitURL.createObjectURL(blob);
   } else {
@@ -366,32 +341,13 @@ fdom.util.getURL = function(blob) {
   }
 };
 
-/**
- * When running in a priviledged context, honor a global
- * 'freedomcfg' function to allow registration of additional API providers.
- * @method advertise
- * @param {Boolean} force Advertise even if not in a priviledged context.
- * @static
- */
-fdom.util.advertise = function(force) {
-  // TODO: Determine a better mechanism than this whitelisting.
-  if (typeof location !== 'undefined') {
-    if ((location.protocol === 'chrome-extension:' ||
-        location.protocol === 'chrome:' ||
-        location.protocol === 'resource:' || force) &&
-        typeof freedomcfg !== "undefined") {
-      freedomcfg(fdom.apis.register.bind(fdom.apis));
-    }
-  } else if (force && typeof freedomcfg !== "undefined") {
-    freedomcfg(fdom.apis.register.bind(fdom.apis));
-  }
-};
-
 /**
  * Find all scripts on the given page.
  * @method scripts
  * @static
  */
-fdom.util.scripts = function(global) {
+util.scripts = function(global) {
   return global.document.getElementsByTagName('script');
 };
+
+module.exports = util;

{'addition_count': 25, 'commit_subject': 'start of refactoring freedom core into a require structure, rather than the previous concatination.', 'deletion_count': 69, 'file_extension': '.js', 'lang': 'js', 'license': 'apache-2.0', 'repo_name': 'freedomjs/freedom'}