From 486c7872c0c44eda724836fb21121b5a7ab067ea Mon Sep 17 00:00:00 2001
From: Marius Stefan Bethge
Date: Thu, 26 Mar 2015 01:16:55 +0100
Subject: [PATCH 1/3] Pointerevents: Add PEP
---
external/pep/PEP.js | 1318 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 1318 insertions(+)
create mode 100644 external/pep/PEP.js
diff --git a/external/pep/PEP.js b/external/pep/PEP.js
new file mode 100644
index 00000000000..e876d97ddb8
--- /dev/null
+++ b/external/pep/PEP.js
@@ -0,0 +1,1318 @@
+/*!
+ * PEP v0.0.0 | https://github.com/jquery/PEP
+ * Copyright jQuery Foundation and other contributors | http://jquery.org/license
+ */
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ global.PointerEventsPolyfill = factory()
+}(this, function () { 'use strict';
+
+ /**
+ * This module implements an map of pointer states
+ */
+ var USE_MAP = window.Map && window.Map.prototype.forEach;
+ var POINTERS_FN = function(){ return this.size; };
+ function PointerMap() {
+ if (USE_MAP) {
+ var m = new Map();
+ m.pointers = POINTERS_FN;
+ return m;
+ } else {
+ this.keys = [];
+ this.values = [];
+ }
+ }
+
+ PointerMap.prototype = {
+ set: function(inId, inEvent) {
+ var i = this.keys.indexOf(inId);
+ if (i > -1) {
+ this.values[i] = inEvent;
+ } else {
+ this.keys.push(inId);
+ this.values.push(inEvent);
+ }
+ },
+ has: function(inId) {
+ return this.keys.indexOf(inId) > -1;
+ },
+ 'delete': function(inId) {
+ var i = this.keys.indexOf(inId);
+ if (i > -1) {
+ this.keys.splice(i, 1);
+ this.values.splice(i, 1);
+ }
+ },
+ get: function(inId) {
+ var i = this.keys.indexOf(inId);
+ return this.values[i];
+ },
+ clear: function() {
+ this.keys.length = 0;
+ this.values.length = 0;
+ },
+ // return value, key, map
+ forEach: function(callback, thisArg) {
+ this.values.forEach(function(v, i) {
+ callback.call(thisArg, v, this.keys[i], this);
+ }, this);
+ },
+ pointers: function() {
+ return this.keys.length;
+ }
+ };
+
+ var CLONE_PROPS = [
+ // MouseEvent
+ 'bubbles',
+ 'cancelable',
+ 'view',
+ 'detail',
+ 'screenX',
+ 'screenY',
+ 'clientX',
+ 'clientY',
+ 'ctrlKey',
+ 'altKey',
+ 'shiftKey',
+ 'metaKey',
+ 'button',
+ 'relatedTarget',
+ // DOM Level 3
+ 'buttons',
+ // PointerEvent
+ 'pointerId',
+ 'width',
+ 'height',
+ 'pressure',
+ 'tiltX',
+ 'tiltY',
+ 'pointerType',
+ 'hwTimestamp',
+ 'isPrimary',
+ // event instance
+ 'type',
+ 'target',
+ 'currentTarget',
+ 'which',
+ 'pageX',
+ 'pageY',
+ 'timeStamp'
+ ];
+
+ var CLONE_DEFAULTS = [
+ // MouseEvent
+ false,
+ false,
+ null,
+ null,
+ 0,
+ 0,
+ 0,
+ 0,
+ false,
+ false,
+ false,
+ false,
+ 0,
+ null,
+ // DOM Level 3
+ 0,
+ // PointerEvent
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ '',
+ 0,
+ false,
+ // event instance
+ '',
+ null,
+ null,
+ 0,
+ 0,
+ 0,
+ 0
+ ];
+
+ var HAS_SVG_INSTANCE = (typeof SVGElementInstance !== 'undefined');
+
+ /**
+ * This module is for normalizing events. Mouse and Touch events will be
+ * collected here, and fire PointerEvents that have the same semantics, no
+ * matter the source.
+ * Events fired:
+ * - pointerdown: a pointing is added
+ * - pointerup: a pointer is removed
+ * - pointermove: a pointer is moved
+ * - pointerover: a pointer crosses into an element
+ * - pointerout: a pointer leaves an element
+ * - pointercancel: a pointer will no longer generate events
+ */
+ var dispatcher = {
+ pointermap: new PointerMap(),
+ eventMap: Object.create(null),
+ captureInfo: Object.create(null),
+ // Scope objects for native events.
+ // This exists for ease of testing.
+ eventSources: Object.create(null),
+ eventSourceList: [],
+ /**
+ * Add a new event source that will generate pointer events.
+ *
+ * `inSource` must contain an array of event names named `events`, and
+ * functions with the names specified in the `events` array.
+ * @param {string} name A name for the event source
+ * @param {Object} source A new source of platform events.
+ */
+ registerSource: function(name, source) {
+ var s = source;
+ var newEvents = s.events;
+ if (newEvents) {
+ newEvents.forEach(function(e) {
+ if (s[e]) {
+ this.eventMap[e] = s[e].bind(s);
+ }
+ }, this);
+ this.eventSources[name] = s;
+ this.eventSourceList.push(s);
+ }
+ },
+ register: function(element) {
+ var l = this.eventSourceList.length;
+ for (var i = 0, es; (i < l) && (es = this.eventSourceList[i]); i++) {
+ // call eventsource register
+ es.register.call(es, element);
+ }
+ },
+ unregister: function(element) {
+ var l = this.eventSourceList.length;
+ for (var i = 0, es; (i < l) && (es = this.eventSourceList[i]); i++) {
+ // call eventsource register
+ es.unregister.call(es, element);
+ }
+ },
+ contains: /*scope.external.contains || */function(container, contained) {
+ return container.contains(contained);
+ },
+ // EVENTS
+ down: function(inEvent) {
+ inEvent.bubbles = true;
+ this.fireEvent('pointerdown', inEvent);
+ },
+ move: function(inEvent) {
+ inEvent.bubbles = true;
+ this.fireEvent('pointermove', inEvent);
+ },
+ up: function(inEvent) {
+ inEvent.bubbles = true;
+ this.fireEvent('pointerup', inEvent);
+ },
+ enter: function(inEvent) {
+ inEvent.bubbles = false;
+ this.fireEvent('pointerenter', inEvent);
+ },
+ leave: function(inEvent) {
+ inEvent.bubbles = false;
+ this.fireEvent('pointerleave', inEvent);
+ },
+ over: function(inEvent) {
+ inEvent.bubbles = true;
+ this.fireEvent('pointerover', inEvent);
+ },
+ out: function(inEvent) {
+ inEvent.bubbles = true;
+ this.fireEvent('pointerout', inEvent);
+ },
+ cancel: function(inEvent) {
+ inEvent.bubbles = true;
+ this.fireEvent('pointercancel', inEvent);
+ },
+ leaveOut: function(event) {
+ this.out(event);
+ if (!this.contains(event.target, event.relatedTarget)) {
+ this.leave(event);
+ }
+ },
+ enterOver: function(event) {
+ this.over(event);
+ if (!this.contains(event.target, event.relatedTarget)) {
+ this.enter(event);
+ }
+ },
+ // LISTENER LOGIC
+ eventHandler: function(inEvent) {
+ // This is used to prevent multiple dispatch of pointerevents from
+ // platform events. This can happen when two elements in different scopes
+ // are set up to create pointer events, which is relevant to Shadow DOM.
+ if (inEvent._handledByPE) {
+ return;
+ }
+ var type = inEvent.type;
+ var fn = this.eventMap && this.eventMap[type];
+ if (fn) {
+ fn(inEvent);
+ }
+ inEvent._handledByPE = true;
+ },
+ // set up event listeners
+ listen: function(target, events) {
+ events.forEach(function(e) {
+ this.addEvent(target, e);
+ }, this);
+ },
+ // remove event listeners
+ unlisten: function(target, events) {
+ events.forEach(function(e) {
+ this.removeEvent(target, e);
+ }, this);
+ },
+ addEvent: /*scope.external.addEvent || */function(target, eventName) {
+ target.addEventListener(eventName, this.boundHandler);
+ },
+ removeEvent: /*scope.external.removeEvent || */function(target, eventName) {
+ target.removeEventListener(eventName, this.boundHandler);
+ },
+ // EVENT CREATION AND TRACKING
+ /**
+ * Creates a new Event of type `inType`, based on the information in
+ * `inEvent`.
+ *
+ * @param {string} inType A string representing the type of event to create
+ * @param {Event} inEvent A platform event with a target
+ * @return {Event} A PointerEvent of type `inType`
+ */
+ makeEvent: function(inType, inEvent) {
+ // relatedTarget must be null if pointer is captured
+ if (this.captureInfo[inEvent.pointerId]) {
+ inEvent.relatedTarget = null;
+ }
+ var e = new PointerEvent(inType, inEvent);
+ if (inEvent.preventDefault) {
+ e.preventDefault = inEvent.preventDefault;
+ }
+ e._target = e._target || inEvent.target;
+ return e;
+ },
+ // make and dispatch an event in one call
+ fireEvent: function(inType, inEvent) {
+ var e = this.makeEvent(inType, inEvent);
+ return this.dispatchEvent(e);
+ },
+ /**
+ * Returns a snapshot of inEvent, with writable properties.
+ *
+ * @param {Event} inEvent An event that contains properties to copy.
+ * @return {Object} An object containing shallow copies of `inEvent`'s
+ * properties.
+ */
+ cloneEvent: function(inEvent) {
+ var eventCopy = Object.create(null), p;
+ for (var i = 0; i < CLONE_PROPS.length; i++) {
+ p = CLONE_PROPS[i];
+ eventCopy[p] = inEvent[p] || CLONE_DEFAULTS[i];
+ // Work around SVGInstanceElement shadow tree
+ // Return the