Version 1
[yaffs-website] / web / modules / contrib / blazy / js / dblazy.js
diff --git a/web/modules/contrib/blazy/js/dblazy.js b/web/modules/contrib/blazy/js/dblazy.js
new file mode 100644 (file)
index 0000000..edce461
--- /dev/null
@@ -0,0 +1,324 @@
+/**
+ * @file
+ * Cherries by @toddmotto, @cferdinandi, @adamfschwartz, @daniellmb.
+ *
+ * @todo: Use Cash or Underscore when jQuery is dropped by supported plugins.
+ */
+
+/* global window, document, define, module */
+(function (root, factory) {
+
+  'use strict';
+
+  // Inspired by https://github.com/addyosmani/memoize.js/blob/master/memoize.js
+  if (typeof define === 'function' && define.amd) {
+    // AMD. Register as an anonymous module.
+    define([], factory);
+  }
+  else if (typeof exports === 'object') {
+    // Node. Does not work with strict CommonJS, but only CommonJS-like
+    // environments that support module.exports, like Node.
+    module.exports = factory();
+  }
+  else {
+    // Browser globals (root is window).
+    root.dBlazy = factory();
+  }
+})(this, function () {
+
+  'use strict';
+
+  /**
+   * Object for public APIs where dBlazy stands for drupalBlazy.
+   *
+   * @namespace
+   */
+  var dBlazy = {};
+
+  /**
+   * Check if the given element matches the selector.
+   *
+   * @name dBlazy.matches
+   *
+   * @param {Element} elem
+   *   The current element.
+   * @param {String} selector
+   *   Selector to match against (class, ID, data attribute, or tag).
+   *
+   * @return {Boolean}
+   *   Returns true if found, else false.
+   *
+   * @see http://caniuse.com/#feat=matchesselector
+   * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
+   */
+  dBlazy.matches = function (elem, selector) {
+    // Element.matches() polyfill.
+    var p = Element.prototype;
+    if (!p.matches) {
+      p.matches =
+        p.matchesSelector ||
+        p.mozMatchesSelector ||
+        p.msMatchesSelector ||
+        p.oMatchesSelector ||
+        p.webkitMatchesSelector ||
+        function (s) {
+          var matches = (this.document || this.ownerDocument).querySelectorAll(s);
+          var i = matches.length;
+          while (--i >= 0 && matches.item(i) !== this) {
+            // Empty block to satisfy coder and eslint.
+          }
+          return i > -1;
+        };
+    }
+
+    // Check if matches.
+    if (elem.matches(selector)) {
+      return true;
+    }
+
+    return false;
+  };
+
+  /**
+   * Get the closest matching element up the DOM tree.
+   *
+   * Inspired by Chris Ferdinandi, http://github.com/cferdinandi/smooth-scroll.
+   *
+   * @name dBlazy.closest
+   *
+   * @param {Element} elem
+   *   Starting element.
+   * @param {String} selector
+   *   Selector to match against (class, ID, data attribute, or tag).
+   *
+   * @return {Boolean|Element}
+   *   Returns null if not match found.
+   *
+   * @see http://caniuse.com/#feat=element-closest
+   * @see http://caniuse.com/#feat=matchesselector
+   * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
+   */
+  dBlazy.closest = function (elem, selector) {
+    for (; elem && elem !== document; elem = elem.parentNode) {
+      if (dBlazy.matches(elem, selector)) {
+        return elem;
+      }
+    }
+
+    return null;
+  };
+
+  /**
+   * Returns a new object after merging two, or more objects.
+   *
+   * Or use https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/
+   * Global_Objects/Object/assign.
+   *
+   * @name dBlazy.extend
+   *
+   * Inspired by @adamfschwartz, @zackbloom, http://youmightnotneedjquery.com.
+   *
+   * @param {Object} out
+   *   The objects to merge together.
+   *
+   * @return {Object}
+   *   Merged values of defaults and options.
+   */
+  dBlazy.extend = Object.assign || function (out) {
+    out = out || {};
+
+    for (var i = 1, len = arguments.length; i < len; i++) {
+      if (!arguments[i]) {
+        continue;
+      }
+
+      for (var key in arguments[i]) {
+        if (arguments[i].hasOwnProperty(key)) {
+          out[key] = arguments[i][key];
+        }
+      }
+    }
+
+    return out;
+  };
+
+  /**
+   * A simple forEach() implementation for Arrays, Objects and NodeLists.
+   *
+   * @name dBlazy.forEach
+   *
+   * @author Todd Motto
+   * @link https://github.com/toddmotto/foreach
+   *
+   * @param {Array|Object|NodeList} collection
+   *   Collection of items to iterate.
+   * @param {Function} callback
+   *   Callback function for each iteration.
+   * @param {Array|Object|NodeList} scope
+   *   Object/NodeList/Array that forEach is iterating over (aka `this`).
+   */
+  dBlazy.forEach = function (collection, callback, scope) {
+    var proto = Object.prototype;
+    if (proto.toString.call(collection) === '[object Object]') {
+      for (var prop in collection) {
+        if (proto.hasOwnProperty.call(collection, prop)) {
+          callback.call(scope, collection[prop], prop, collection);
+        }
+      }
+    }
+    else {
+      for (var i = 0, len = collection.length; i < len; i++) {
+        callback.call(scope, collection[i], i, collection);
+      }
+    }
+  };
+
+  /**
+   * A simple wrapper for event delegation like jQuery.on().
+   *
+   * Inspired by http://stackoverflow.com/questions/30880757/
+   * javascript-equivalent-to-on.
+   *
+   * @name dBlazy.on
+   *
+   * @param {Element} elm
+   *   The parent HTML element.
+   * @param {String} eventName
+   *   The event name to trigger.
+   * @param {String} childEl
+   *   Child selector to match against (class, ID, data attribute, or tag).
+   * @param {Function} callback
+   *   The callback function.
+   */
+  dBlazy.on = function (elm, eventName, childEl, callback) {
+    elm.addEventListener(eventName, function (event) {
+      var t = event.target;
+      while (t && t !== this) {
+        if (dBlazy.matches(t, childEl)) {
+          callback.call(t, event);
+        }
+        t = t.parentNode;
+      }
+    });
+  };
+
+  /**
+   * Executes a function once.
+   *
+   * @name dBlazy.once
+   *
+   * @author Daniel Lamb <dlamb.open.source@gmail.com>
+   * @link https://github.com/daniellmb/once.js
+   *
+   * @param {Function} fn
+   *   The executed function.
+   *
+   * @return {Object}
+   *   The function result.
+   */
+  dBlazy.once = function (fn) {
+    var result;
+    var ran = false;
+    return function proxy() {
+      if (ran) {
+        return result;
+      }
+      ran = true;
+      result = fn.apply(this, arguments);
+      // For garbage collection.
+      fn = null;
+      return result;
+    };
+  };
+
+  /**
+   * A simple wrapper for JSON.parse() for string within data-* attributes.
+   *
+   * @name dBlazy.parse
+   *
+   * @param {String} str
+   *   The string to convert into JSON object.
+   *
+   * @return {Object|Boolean}
+   *   The JSON object, or false in case invalid.
+   */
+  dBlazy.parse = function (str) {
+    try {
+      return JSON.parse(str);
+    }
+    catch (e) {
+      return false;
+    }
+  };
+
+  /**
+   * A simple wrapper to delay callback function on window resize.
+   *
+   * @name dBlazy.resize
+   *
+   * @link https://github.com/louisremi/jquery-smartresize
+   *
+   * @param {Function} c
+   *   The callback function.
+   * @param {Int} t
+   *   The timeout.
+   *
+   * @return {Function}
+   *   The callback function.
+   */
+  dBlazy.resize = function (c, t) {
+    window.onresize = function () {
+      window.clearTimeout(t);
+      t = window.setTimeout(c, 200);
+    };
+    return c;
+  };
+
+  /**
+   * A simple wrapper for triggering event like jQuery.trigger().
+   *
+   * @name dBlazy.trigger
+   *
+   * @param {Element} elm
+   *   The HTML element.
+   * @param {String} eventName
+   *   The event name to trigger.
+   * @param {Object} custom
+   *   The optional object passed into a custom event.
+   * @param {String} type
+   *   Default to MouseEvents, can be either:
+   *     MouseEvents: click, mousedown, mouseup.
+   *     HTMLEvents: focus, change, blur, select.
+   *
+   * @see https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
+   * @todo: See if any consistent way for both custom and native events.
+   */
+  dBlazy.trigger = function (elm, eventName, custom, type) {
+    var event;
+    custom = custom || {};
+    type = type || 'MouseEvents';
+
+    var addEvent = function (eventName, data) {
+      data = data || {};
+      // @todo: Use Event constructor, pending as not supported by all IEs.
+      event = document.createEvent(data && typeof data === 'object' ? 'Event' : type);
+      event.initEvent(eventName, true, true, data);
+
+      return event;
+    };
+
+    // IE >= 9 compat, else SCRIPT445: Object doesn't support this action.
+    // https://msdn.microsoft.com/library/ff975299(v=vs.85).aspx
+    try {
+      event = custom ? new CustomEvent(eventName, {detail: custom}) : addEvent(eventName);
+    }
+    catch (e) {
+      event = addEvent(eventName, custom);
+    }
+
+    elm.dispatchEvent(event);
+  };
+
+  return dBlazy;
+
+});