pointer events generated by mouse events
This commit is contained in:
@@ -8,7 +8,8 @@ goog.require('goog.events');
|
||||
goog.require('goog.events.BrowserEvent');
|
||||
goog.require('goog.events.EventTarget');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.object');
|
||||
|
||||
goog.require('ol.pointer.PointerEventHandler');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.MapEvent');
|
||||
goog.require('ol.Pixel');
|
||||
@@ -114,12 +115,6 @@ ol.MapBrowserEventHandler = function(map) {
|
||||
*/
|
||||
this.dragListenerKeys_ = null;
|
||||
|
||||
/**
|
||||
* @type {goog.events.Key}
|
||||
* @private
|
||||
*/
|
||||
this.mousedownListenerKey_ = null;
|
||||
|
||||
/**
|
||||
* @type {goog.events.Key}
|
||||
* @private
|
||||
@@ -127,10 +122,10 @@ ol.MapBrowserEventHandler = function(map) {
|
||||
this.pointerdownListenerKey_ = null;
|
||||
|
||||
/**
|
||||
* @type {goog.events.Key}
|
||||
* @type {goog.events.BrowserEvent}
|
||||
* @private
|
||||
*/
|
||||
this.touchstartListenerKey_ = null;
|
||||
this.down_ = null;
|
||||
|
||||
if (ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE) {
|
||||
/**
|
||||
@@ -141,38 +136,23 @@ ol.MapBrowserEventHandler = function(map) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {goog.events.BrowserEvent}
|
||||
* @type {ol.pointer.PointerEventHandler}
|
||||
* @private
|
||||
*/
|
||||
this.down_ = null;
|
||||
this.PointerEventHandler_ = null;
|
||||
|
||||
var element = this.map_.getViewport();
|
||||
|
||||
this.relayedListenerKeys_ = [
|
||||
goog.events.listen(element,
|
||||
goog.events.EventType.MOUSEMOVE,
|
||||
this.relayEvent_, false, this),
|
||||
goog.events.listen(element,
|
||||
goog.events.EventType.CLICK,
|
||||
this.relayEvent_, false, this)
|
||||
];
|
||||
|
||||
this.mousedownListenerKey_ = goog.events.listen(element,
|
||||
goog.events.EventType.MOUSEDOWN,
|
||||
this.handleMouseDown_, false, this);
|
||||
|
||||
this.pointerdownListenerKey_ = goog.events.listen(element,
|
||||
goog.events.EventType.MSPOINTERDOWN,
|
||||
this.pointerEventHandler_ = new ol.pointer.PointerEventHandler(element);
|
||||
this.pointerdownListenerKey_ = goog.events.listen(this.pointerEventHandler_,
|
||||
ol.pointer.EventType.POINTERDOWN,
|
||||
this.handlePointerDown_, false, this);
|
||||
|
||||
this.touchstartListenerKey_ = goog.events.listen(element,
|
||||
goog.events.EventType.TOUCHSTART,
|
||||
this.handleTouchStart_, false, this);
|
||||
|
||||
if (ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE) {
|
||||
this.ieDblclickListenerKey_ = goog.events.listen(element,
|
||||
goog.events.EventType.DBLCLICK, this.emulateClick_, false, this);
|
||||
}
|
||||
this.relayedListenerKeys_ = [
|
||||
goog.events.listen(this.pointerEventHandler_,
|
||||
ol.pointer.EventType.POINTERMOVE,
|
||||
this.relayEvent_, false, this)
|
||||
];
|
||||
};
|
||||
goog.inherits(ol.MapBrowserEventHandler, goog.events.EventTarget);
|
||||
|
||||
@@ -232,7 +212,7 @@ ol.MapBrowserEventHandler.prototype.emulateClick_ = function(browserEvent) {
|
||||
* @param {goog.events.BrowserEvent} browserEvent Browser event.
|
||||
* @private
|
||||
*/
|
||||
ol.MapBrowserEventHandler.prototype.handleMouseUp_ = function(browserEvent) {
|
||||
ol.MapBrowserEventHandler.prototype.handlePointerUp_ = function(browserEvent) {
|
||||
if (this.down_) {
|
||||
goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey);
|
||||
this.dragListenerKeys_ = null;
|
||||
@@ -251,28 +231,17 @@ ol.MapBrowserEventHandler.prototype.handleMouseUp_ = function(browserEvent) {
|
||||
* @param {goog.events.BrowserEvent} browserEvent Browser event.
|
||||
* @private
|
||||
*/
|
||||
ol.MapBrowserEventHandler.prototype.handleMouseDown_ = function(browserEvent) {
|
||||
if (!goog.isNull(this.pointerdownListenerKey_)) {
|
||||
// mouse device detected - unregister the pointerdown and touchstart
|
||||
// listeners
|
||||
goog.events.unlistenByKey(this.pointerdownListenerKey_);
|
||||
this.pointerdownListenerKey_ = null;
|
||||
|
||||
goog.asserts.assert(!goog.isNull(this.touchstartListenerKey_));
|
||||
goog.events.unlistenByKey(this.touchstartListenerKey_);
|
||||
this.touchstartListenerKey_ = null;
|
||||
}
|
||||
|
||||
ol.MapBrowserEventHandler.prototype.handlePointerDown_ = function(browserEvent) {
|
||||
var newEvent = new ol.MapBrowserEvent(
|
||||
ol.MapBrowserEvent.EventType.DOWN, this.map_, browserEvent);
|
||||
this.dispatchEvent(newEvent);
|
||||
this.down_ = browserEvent;
|
||||
this.dragged_ = false;
|
||||
this.dragListenerKeys_ = [
|
||||
goog.events.listen(goog.global.document, goog.events.EventType.MOUSEMOVE,
|
||||
this.handleMouseMove_, false, this),
|
||||
goog.events.listen(goog.global.document, goog.events.EventType.MOUSEUP,
|
||||
this.handleMouseUp_, false, this)
|
||||
goog.events.listen(this.pointerEventHandler_, ol.MapBrowserEvent.EventType.POINTERMOVE,
|
||||
this.handlePointerMove_, false, this),
|
||||
goog.events.listen(this.pointerEventHandler_, ol.MapBrowserEvent.EventType.POINTERUP,
|
||||
this.handlePointerUp_, false, this)
|
||||
];
|
||||
// prevent browser image dragging with the dom renderer
|
||||
browserEvent.preventDefault();
|
||||
@@ -283,7 +252,7 @@ ol.MapBrowserEventHandler.prototype.handleMouseDown_ = function(browserEvent) {
|
||||
* @param {goog.events.BrowserEvent} browserEvent Browser event.
|
||||
* @private
|
||||
*/
|
||||
ol.MapBrowserEventHandler.prototype.handleMouseMove_ = function(browserEvent) {
|
||||
ol.MapBrowserEventHandler.prototype.handlePointerMove_ = function(browserEvent) {
|
||||
var newEvent;
|
||||
if (!this.dragged_) {
|
||||
this.dragged_ = true;
|
||||
@@ -297,159 +266,6 @@ ol.MapBrowserEventHandler.prototype.handleMouseMove_ = function(browserEvent) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.events.BrowserEvent} browserEvent Browser event.
|
||||
* @private
|
||||
*/
|
||||
ol.MapBrowserEventHandler.prototype.handlePointerDown_ =
|
||||
function(browserEvent) {
|
||||
if (!goog.isNull(this.mousedownListenerKey_)) {
|
||||
// pointer device detected - unregister the mousedown and touchstart
|
||||
// listeners
|
||||
goog.events.unlistenByKey(this.mousedownListenerKey_);
|
||||
this.mousedownListenerKey_ = null;
|
||||
|
||||
goog.asserts.assert(!goog.isNull(this.touchstartListenerKey_));
|
||||
goog.events.unlistenByKey(this.touchstartListenerKey_);
|
||||
this.touchstartListenerKey_ = null;
|
||||
}
|
||||
|
||||
var newEvent = new ol.MapBrowserEvent(
|
||||
ol.MapBrowserEvent.EventType.TOUCHSTART, this.map_, browserEvent);
|
||||
this.dispatchEvent(newEvent);
|
||||
|
||||
this.down_ = browserEvent;
|
||||
this.dragged_ = false;
|
||||
this.dragListenerKeys_ = [
|
||||
goog.events.listen(goog.global.document,
|
||||
goog.events.EventType.MSPOINTERMOVE,
|
||||
this.handlePointerMove_, false, this),
|
||||
goog.events.listen(goog.global.document, goog.events.EventType.MSPOINTERUP,
|
||||
this.handlePointerUp_, false, this)
|
||||
];
|
||||
|
||||
// FIXME check if/when this is necessary
|
||||
// prevent context menu
|
||||
browserEvent.preventDefault();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.events.BrowserEvent} browserEvent Browser event.
|
||||
* @private
|
||||
*/
|
||||
ol.MapBrowserEventHandler.prototype.handlePointerMove_ =
|
||||
function(browserEvent) {
|
||||
// Fix IE10 on windows Surface : When you tap the tablet, it triggers
|
||||
// multiple pointermove events between pointerdown and pointerup with
|
||||
// the exact same coordinates of the pointerdown event. To avoid a
|
||||
// 'false' touchmove event to be dispatched , we test if the pointer
|
||||
// effectively moved.
|
||||
if (browserEvent.clientX != this.down_.clientX ||
|
||||
browserEvent.clientY != this.down_.clientY) {
|
||||
this.dragged_ = true;
|
||||
var newEvent = new ol.MapBrowserEvent(
|
||||
ol.MapBrowserEvent.EventType.TOUCHMOVE, this.map_, browserEvent);
|
||||
this.dispatchEvent(newEvent);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.events.BrowserEvent} browserEvent Browser event.
|
||||
* @private
|
||||
*/
|
||||
ol.MapBrowserEventHandler.prototype.handlePointerUp_ = function(browserEvent) {
|
||||
var newEvent = new ol.MapBrowserEvent(
|
||||
ol.MapBrowserEvent.EventType.TOUCHEND, this.map_, browserEvent);
|
||||
this.dispatchEvent(newEvent);
|
||||
goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey);
|
||||
|
||||
// We emulate click event on left mouse button click, touch contact, and pen
|
||||
// contact. isMouseActionButton returns true in these cases (evt.button is set
|
||||
// to 0).
|
||||
// See http://www.w3.org/TR/pointerevents/#button-states .
|
||||
if (!this.dragged_ && browserEvent.isMouseActionButton()) {
|
||||
goog.asserts.assert(!goog.isNull(this.down_));
|
||||
this.emulateClick_(this.down_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.events.BrowserEvent} browserEvent Browser event.
|
||||
* @private
|
||||
*/
|
||||
ol.MapBrowserEventHandler.prototype.handleTouchStart_ = function(browserEvent) {
|
||||
if (!goog.isNull(this.mousedownListenerKey_)) {
|
||||
// touch device detected - unregister the mousedown and pointerdown
|
||||
// listeners
|
||||
goog.events.unlistenByKey(this.mousedownListenerKey_);
|
||||
this.mousedownListenerKey_ = null;
|
||||
|
||||
goog.asserts.assert(!goog.isNull(this.pointerdownListenerKey_));
|
||||
goog.events.unlistenByKey(this.pointerdownListenerKey_);
|
||||
this.pointerdownListenerKey_ = null;
|
||||
}
|
||||
|
||||
var newEvent = new ol.MapBrowserEvent(
|
||||
ol.MapBrowserEvent.EventType.TOUCHSTART, this.map_, browserEvent);
|
||||
this.dispatchEvent(newEvent);
|
||||
|
||||
this.down_ = browserEvent;
|
||||
this.dragged_ = false;
|
||||
|
||||
if (goog.isNull(this.dragListenerKeys_)) {
|
||||
this.dragListenerKeys_ = [
|
||||
goog.events.listen(goog.global.document, goog.events.EventType.TOUCHMOVE,
|
||||
this.handleTouchMove_, false, this),
|
||||
goog.events.listen(goog.global.document, goog.events.EventType.TOUCHEND,
|
||||
this.handleTouchEnd_, false, this)
|
||||
];
|
||||
}
|
||||
|
||||
// FIXME check if/when this is necessary
|
||||
browserEvent.preventDefault();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.events.BrowserEvent} browserEvent Browser event.
|
||||
* @private
|
||||
*/
|
||||
ol.MapBrowserEventHandler.prototype.handleTouchMove_ = function(browserEvent) {
|
||||
this.dragged_ = true;
|
||||
var newEvent = new ol.MapBrowserEvent(
|
||||
ol.MapBrowserEvent.EventType.TOUCHMOVE, this.map_, browserEvent);
|
||||
this.dispatchEvent(newEvent);
|
||||
|
||||
// Some native android browser triggers mousemove events during small period
|
||||
// of time. See: https://code.google.com/p/android/issues/detail?id=5491 or
|
||||
// https://code.google.com/p/android/issues/detail?id=19827
|
||||
// ex: Galaxy Tab P3110 + Android 4.1.1
|
||||
browserEvent.preventDefault();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.events.BrowserEvent} browserEvent Browser event.
|
||||
* @private
|
||||
*/
|
||||
ol.MapBrowserEventHandler.prototype.handleTouchEnd_ = function(browserEvent) {
|
||||
var newEvent = new ol.MapBrowserEvent(
|
||||
ol.MapBrowserEvent.EventType.TOUCHEND, this.map_, browserEvent);
|
||||
this.dispatchEvent(newEvent);
|
||||
if (browserEvent.getBrowserEvent().targetTouches.length === 0) {
|
||||
goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey);
|
||||
this.dragListenerKeys_ = null;
|
||||
}
|
||||
if (!this.dragged_) {
|
||||
goog.asserts.assert(!goog.isNull(this.down_));
|
||||
this.emulateClick_(this.down_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
@@ -502,13 +318,22 @@ ol.MapBrowserEventHandler.prototype.relayEvent_ = function(browserEvent) {
|
||||
ol.MapBrowserEvent.EventType = {
|
||||
CLICK: goog.events.EventType.CLICK,
|
||||
DBLCLICK: goog.events.EventType.DBLCLICK,
|
||||
MOUSEMOVE: goog.events.EventType.MOUSEMOVE,
|
||||
DOWN: 'down',
|
||||
DRAGSTART: 'dragstart',
|
||||
DRAG: 'drag',
|
||||
DRAGEND: 'dragend',
|
||||
DOWN: 'down',
|
||||
|
||||
MOUSEMOVE: goog.events.EventType.MOUSEMOVE,
|
||||
SINGLECLICK: 'singleclick',
|
||||
TOUCHSTART: goog.events.EventType.TOUCHSTART,
|
||||
TOUCHMOVE: goog.events.EventType.TOUCHMOVE,
|
||||
TOUCHEND: goog.events.EventType.TOUCHEND
|
||||
TOUCHEND: goog.events.EventType.TOUCHEND,
|
||||
|
||||
POINTERMOVE: 'pointermove',
|
||||
POINTERDOWN: 'pointerdown',
|
||||
POINTERUP: 'pointerup',
|
||||
POINTEROVER: 'pointerover',
|
||||
POINTERENTER: 'pointerenter',
|
||||
POINTERLEAVE: 'pointerleave',
|
||||
POINTERCANCEL: 'pointercancel'
|
||||
};
|
||||
|
||||
40
src/ol/pointer/eventsource.js
Normal file
40
src/ol/pointer/eventsource.js
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
goog.provide('ol.pointer.EventSource');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.pointer.PointerEventHandler} dispatcher
|
||||
* @constructor
|
||||
*/
|
||||
ol.pointer.EventSource = function(dispatcher) {
|
||||
/**
|
||||
* @type {ol.pointer.PointerEventHandler}
|
||||
*/
|
||||
this.dispatcher = dispatcher;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* List of events supported by this source.
|
||||
* @return {Array.<string>} Event names
|
||||
*/
|
||||
ol.pointer.EventSource.prototype.getEvents = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Returns a mapping between the supported event types and
|
||||
* the handlers that should handle an event.
|
||||
* @return {Object.<string, function(Event)>} Event/Handler mapping
|
||||
*/
|
||||
ol.pointer.EventSource.prototype.getMapping = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the handler that should handle a given event type.
|
||||
* @param {string} eventType
|
||||
* @return {function(Event)} Handler
|
||||
*/
|
||||
ol.pointer.EventSource.prototype.getHandlerForEvent = function(eventType) {
|
||||
return this.getMapping()[eventType];
|
||||
};
|
||||
197
src/ol/pointer/mousesource.js
Normal file
197
src/ol/pointer/mousesource.js
Normal file
@@ -0,0 +1,197 @@
|
||||
goog.provide('ol.pointer.MouseSource');
|
||||
|
||||
goog.require('ol.pointer.EventSource');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.pointer.PointerEventHandler} dispatcher
|
||||
* @constructor
|
||||
* @extends {ol.pointer.EventSource}
|
||||
*/
|
||||
ol.pointer.MouseSource = function(dispatcher) {
|
||||
goog.base(this, dispatcher);
|
||||
|
||||
this.pointerMap = dispatcher.pointerMap;
|
||||
|
||||
// radius around touchend that swallows mouse events
|
||||
this.DEDUP_DIST = 25;
|
||||
|
||||
this.POINTER_ID = 1;
|
||||
this.POINTER_TYPE = 'mouse';
|
||||
|
||||
this.events = [
|
||||
'mousedown',
|
||||
'mousemove',
|
||||
'mouseup',
|
||||
'mouseover',
|
||||
'mouseout'
|
||||
];
|
||||
this.mapping = {
|
||||
'mousedown': this.mousedown,
|
||||
'mousemove': this.mousemove,
|
||||
'mouseup': this.mouseup,
|
||||
'mouseover': this.mouseover,
|
||||
'mouseout': this.mouseout
|
||||
};
|
||||
|
||||
this.lastTouches = [];
|
||||
};
|
||||
goog.inherits(ol.pointer.MouseSource, ol.pointer.EventSource);
|
||||
|
||||
|
||||
/** @inheritDoc */
|
||||
ol.pointer.MouseSource.prototype.getEvents = function() {
|
||||
return this.events;
|
||||
};
|
||||
|
||||
|
||||
/** @inheritDoc */
|
||||
ol.pointer.MouseSource.prototype.getMapping = function() {
|
||||
return this.mapping;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Collide with the global mouse listener
|
||||
*
|
||||
* @private
|
||||
* @param {goog.events.BrowserEvent} inEvent
|
||||
* @return {boolean} True, if the event was generated by a touch.
|
||||
*/
|
||||
ol.pointer.MouseSource.prototype.isEventSimulatedFromTouch_ =
|
||||
function(inEvent) {
|
||||
var lts = this.lastTouches;
|
||||
var x = inEvent.clientX, y = inEvent.clientY;
|
||||
for (var i = 0, l = lts.length, t; i < l && (t = lts[i]); i++) {
|
||||
// simulated mouse events will be swallowed near a primary touchend
|
||||
var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y);
|
||||
if (dx <= this.DEDUP_DIST && dy <= this.DEDUP_DIST) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a copy of the original event that will be used
|
||||
* for the fake pointer event.
|
||||
*
|
||||
* @private
|
||||
* @param {goog.events.BrowserEvent} inEvent
|
||||
* @return {Object}
|
||||
*/
|
||||
ol.pointer.MouseSource.prototype.prepareEvent_ = function(inEvent) {
|
||||
var e = this.dispatcher.cloneEvent(inEvent);
|
||||
|
||||
// forward mouse preventDefault
|
||||
var pd = e.preventDefault;
|
||||
e.preventDefault = function() {
|
||||
inEvent.preventDefault();
|
||||
pd();
|
||||
};
|
||||
|
||||
e.pointerId = this.POINTER_ID;
|
||||
e.isPrimary = true;
|
||||
e.pointerType = this.POINTER_TYPE;
|
||||
|
||||
return e;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler for `mousedown`.
|
||||
*
|
||||
* @param {goog.events.BrowserEvent} inEvent
|
||||
*/
|
||||
ol.pointer.MouseSource.prototype.mousedown = function(inEvent) {
|
||||
if (!this.isEventSimulatedFromTouch_(inEvent)) {
|
||||
var p = this.pointerMap.containsKey(this.POINTER_ID);
|
||||
// TODO(dfreedman) workaround for some elements not sending mouseup
|
||||
// http://crbug/149091
|
||||
if (p) {
|
||||
this.cancel(inEvent);
|
||||
}
|
||||
var e = this.prepareEvent_(inEvent);
|
||||
this.pointerMap.set(this.POINTER_ID, inEvent);
|
||||
this.dispatcher.down(e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler for `mousemove`.
|
||||
*
|
||||
* @param {goog.events.BrowserEvent} inEvent
|
||||
*/
|
||||
ol.pointer.MouseSource.prototype.mousemove = function(inEvent) {
|
||||
if (!this.isEventSimulatedFromTouch_(inEvent)) {
|
||||
var e = this.prepareEvent_(inEvent);
|
||||
this.dispatcher.move(e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler for `mouseup`.
|
||||
*
|
||||
* @param {goog.events.BrowserEvent} inEvent
|
||||
*/
|
||||
ol.pointer.MouseSource.prototype.mouseup = function(inEvent) {
|
||||
if (!this.isEventSimulatedFromTouch_(inEvent)) {
|
||||
var p = this.pointerMap.get(this.POINTER_ID);
|
||||
|
||||
if (p && p.button === inEvent.button) {
|
||||
var e = this.prepareEvent_(inEvent);
|
||||
this.dispatcher.up(e);
|
||||
this.cleanupMouse();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler for `mouseover`.
|
||||
*
|
||||
* @param {goog.events.BrowserEvent} inEvent
|
||||
*/
|
||||
ol.pointer.MouseSource.prototype.mouseover = function(inEvent) {
|
||||
if (!this.isEventSimulatedFromTouch_(inEvent)) {
|
||||
var e = this.prepareEvent_(inEvent);
|
||||
this.dispatcher.enterOver(e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler for `mouseout`.
|
||||
*
|
||||
* @param {goog.events.BrowserEvent} inEvent
|
||||
*/
|
||||
ol.pointer.MouseSource.prototype.mouseout = function(inEvent) {
|
||||
if (!this.isEventSimulatedFromTouch_(inEvent)) {
|
||||
var e = this.prepareEvent_(inEvent);
|
||||
this.dispatcher.leaveOut(e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Dispatches a `pointercancel` event.
|
||||
*
|
||||
* @param {goog.events.BrowserEvent} inEvent
|
||||
*/
|
||||
ol.pointer.MouseSource.prototype.cancel = function(inEvent) {
|
||||
var e = this.prepareEvent_(inEvent);
|
||||
this.dispatcher.cancel(e);
|
||||
this.cleanupMouse();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove the mouse from the list of active pointers.
|
||||
*/
|
||||
ol.pointer.MouseSource.prototype.cleanupMouse = function() {
|
||||
this.pointerMap.remove(this.POINTER_ID);
|
||||
};
|
||||
209
src/ol/pointer/pointerevent.js
Normal file
209
src/ol/pointer/pointerevent.js
Normal file
@@ -0,0 +1,209 @@
|
||||
goog.provide('ol.pointer.PointerEvent');
|
||||
|
||||
|
||||
//goog.require('goog.events.Event');
|
||||
goog.require('goog.events');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This is the constructor for new PointerEvents.
|
||||
*
|
||||
* New Pointer Events must be given a type, and an optional dictionary of
|
||||
* initialization properties.
|
||||
*
|
||||
* Due to certain platform requirements, events returned from the constructor
|
||||
* identify as MouseEvents.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {Event}
|
||||
* @param {string} inType The type of the event to create.
|
||||
* @param {Object.<string, ?>=} opt_inDict An optional dictionary of
|
||||
* initial event properties.
|
||||
*/
|
||||
ol.pointer.PointerEvent = function(inType, opt_inDict) {
|
||||
opt_inDict = opt_inDict || {};
|
||||
// According to the w3c spec,
|
||||
// http://www.w3.org/TR/DOM-Level-3-Events/#events-MouseEvent-button
|
||||
// MouseEvent.button == 0 can mean either no mouse button depressed, or the
|
||||
// left mouse button depressed.
|
||||
//
|
||||
// As of now, the only way to distinguish between the two states of
|
||||
// MouseEvent.button is by using the deprecated MouseEvent.which property, as
|
||||
// this maps mouse buttons to positive integers > 0, and uses 0 to mean that
|
||||
// no mouse button is held.
|
||||
//
|
||||
// MouseEvent.which is derived from MouseEvent.button at MouseEvent creation,
|
||||
// but initMouseEvent does not expose an argument with which to set
|
||||
// MouseEvent.which. Calling initMouseEvent with a buttonArg of 0 will set
|
||||
// MouseEvent.button == 0 and MouseEvent.which == 1, breaking the expectations
|
||||
// of app developers.
|
||||
//
|
||||
// The only way to propagate the correct state of MouseEvent.which and
|
||||
// MouseEvent.button to a new MouseEvent.button == 0 and MouseEvent.which == 0
|
||||
// is to call initMouseEvent with a buttonArg value of -1.
|
||||
//
|
||||
// This is fixed with DOM Level 4's use of buttons
|
||||
var buttons;
|
||||
if (opt_inDict.buttons || ol.pointer.PointerEvent.HAS_BUTTONS) {
|
||||
buttons = opt_inDict.buttons;
|
||||
} else {
|
||||
switch (opt_inDict.which) {
|
||||
case 1: buttons = 1; break;
|
||||
case 2: buttons = 4; break;
|
||||
case 3: buttons = 2; break;
|
||||
default: buttons = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var e;
|
||||
if (ol.pointer.PointerEvent.NEW_MOUSE_EVENT) {
|
||||
e = ol.pointer.PointerEvent.createMouseEvent(inType, opt_inDict);
|
||||
} else {
|
||||
e = document.createEvent('MouseEvent');
|
||||
|
||||
// import values from the given dictionary
|
||||
/**
|
||||
* @type {Object.<string, ?>}
|
||||
*/
|
||||
var props = {};
|
||||
var p;
|
||||
for (var i = 0; i < ol.pointer.PointerEvent.MOUSE_PROPS.length; i++) {
|
||||
p = ol.pointer.PointerEvent.MOUSE_PROPS[i];
|
||||
props[p] = opt_inDict[p] || ol.pointer.PointerEvent.MOUSE_DEFAULTS[i];
|
||||
}
|
||||
|
||||
// define the properties inherited from MouseEvent
|
||||
e.initMouseEvent(
|
||||
inType, props.bubbles, props.cancelable, props.view, props.detail,
|
||||
props.screenX, props.screenY, props.clientX, props.clientY,
|
||||
props.ctrlKey, props.altKey, props.shiftKey, props.metaKey,
|
||||
props.button, props.relatedTarget
|
||||
);
|
||||
}
|
||||
|
||||
// make the event pass instanceof checks
|
||||
e.__proto__ = ol.pointer.PointerEvent.prototype;
|
||||
|
||||
// define the buttons property according to DOM Level 3 spec
|
||||
if (!ol.pointer.PointerEvent.HAS_BUTTONS) {
|
||||
// IE 10 has buttons on MouseEvent.prototype as a getter w/o any setting
|
||||
// mechanism
|
||||
Object.defineProperty(e, 'buttons',
|
||||
{get: function() { return buttons; }, enumerable: true});
|
||||
}
|
||||
|
||||
// Spec requires that pointers without pressure specified use 0.5 for down
|
||||
// state and 0 for up state.
|
||||
var pressure = 0;
|
||||
if (opt_inDict.pressure) {
|
||||
pressure = opt_inDict.pressure;
|
||||
} else {
|
||||
pressure = buttons ? 0.5 : 0;
|
||||
}
|
||||
|
||||
// define the properties of the PointerEvent interface
|
||||
Object.defineProperties(e, {
|
||||
pointerId: { value: opt_inDict.pointerId || 0, enumerable: true },
|
||||
width: { value: opt_inDict.width || 0, enumerable: true },
|
||||
height: { value: opt_inDict.height || 0, enumerable: true },
|
||||
pressure: { value: pressure, enumerable: true },
|
||||
tiltX: { value: opt_inDict.tiltX || 0, enumerable: true },
|
||||
tiltY: { value: opt_inDict.tiltY || 0, enumerable: true },
|
||||
pointerType: { value: opt_inDict.pointerType || '', enumerable: true },
|
||||
hwTimestamp: { value: opt_inDict.hwTimestamp || 0, enumerable: true },
|
||||
isPrimary: { value: opt_inDict.isPrimary || false, enumerable: true }
|
||||
});
|
||||
|
||||
return e;
|
||||
};
|
||||
|
||||
// PointerEvent extends MouseEvent
|
||||
ol.pointer.PointerEvent.prototype = Object.create(MouseEvent.prototype);
|
||||
|
||||
|
||||
// test for DOM Level 4 Events
|
||||
|
||||
|
||||
/**
|
||||
* Does the browser support the `MouseEvent` type?
|
||||
* @type {boolean}
|
||||
*/
|
||||
ol.pointer.PointerEvent.NEW_MOUSE_EVENT = false;
|
||||
|
||||
|
||||
/**
|
||||
* Is the `buttons` property supported?
|
||||
* @type {boolean}
|
||||
*/
|
||||
ol.pointer.PointerEvent.HAS_BUTTONS = false;
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the `MouseEvent` type is supported.
|
||||
*/
|
||||
ol.pointer.PointerEvent.checkNewMouseEvent = function() {
|
||||
try {
|
||||
var ev = ol.pointer.PointerEvent.createMouseEvent('click', {buttons: 1});
|
||||
ol.pointer.PointerEvent.NEW_MOUSE_EVENT = true;
|
||||
ol.pointer.PointerEvent.HAS_BUTTONS = ev.buttons === 1;
|
||||
} catch (e) {
|
||||
}
|
||||
};
|
||||
ol.pointer.PointerEvent.checkNewMouseEvent();
|
||||
|
||||
|
||||
/**
|
||||
* Warning is suppressed because Closure thinks MouseEvent
|
||||
* has no arguments.
|
||||
* @param {string} inType The type of the event to create.
|
||||
* @param {Object} inDict An dictionary of initial event properties.
|
||||
* @return {MouseEvent}
|
||||
* @suppress {checkTypes}
|
||||
*/
|
||||
ol.pointer.PointerEvent.createMouseEvent = function(inType, inDict) {
|
||||
return new MouseEvent(inType, inDict);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* List of properties to copy when creating an event.
|
||||
* @type {Array.<string>}
|
||||
*/
|
||||
ol.pointer.PointerEvent.MOUSE_PROPS = [
|
||||
'bubbles',
|
||||
'cancelable',
|
||||
'view',
|
||||
'detail',
|
||||
'screenX',
|
||||
'screenY',
|
||||
'clientX',
|
||||
'clientY',
|
||||
'ctrlKey',
|
||||
'altKey',
|
||||
'shiftKey',
|
||||
'metaKey',
|
||||
'button',
|
||||
'relatedTarget'
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* List of default values when creating an event.
|
||||
*/
|
||||
ol.pointer.PointerEvent.MOUSE_DEFAULTS = [
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
null
|
||||
];
|
||||
509
src/ol/pointer/pointereventhandler.js
Normal file
509
src/ol/pointer/pointereventhandler.js
Normal file
@@ -0,0 +1,509 @@
|
||||
goog.provide('ol.pointer.PointerEventHandler');
|
||||
|
||||
|
||||
goog.require('goog.debug.Console');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.BrowserEvent');
|
||||
goog.require('goog.events.Event');
|
||||
goog.require('goog.events.EventTarget');
|
||||
goog.require('goog.structs.Map');
|
||||
|
||||
goog.require('ol.pointer.MouseSource');
|
||||
// goog.require('ol.pointer.MsSource');
|
||||
// goog.require('ol.pointer.NativeSource');
|
||||
goog.require('ol.pointer.PointerEvent');
|
||||
// goog.require('ol.pointer.TouchSource');
|
||||
goog.require('ol.structs.WeakMap');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {goog.events.EventTarget}
|
||||
* @param {Element} element Viewport element.
|
||||
*/
|
||||
ol.pointer.PointerEventHandler = function(element) {
|
||||
goog.base(this);
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @private
|
||||
* @type {Element}
|
||||
*/
|
||||
this.element_ = element;
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {goog.structs.Map}
|
||||
*/
|
||||
this.pointerMap = new goog.structs.Map();
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {ol.structs.WeakMap}
|
||||
*/
|
||||
this.targets = new ol.structs.WeakMap();
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {ol.structs.WeakMap}
|
||||
*/
|
||||
this.handledEvents = new ol.structs.WeakMap();
|
||||
|
||||
this.eventMap = {};
|
||||
|
||||
// Scope objects for native events.
|
||||
// This exists for ease of testing.
|
||||
this.eventSources = {};
|
||||
this.eventSourceList = [];
|
||||
|
||||
this.boundHandler_ = this.eventHandler_.bind(this);
|
||||
|
||||
this.registerSources();
|
||||
};
|
||||
goog.inherits(ol.pointer.PointerEventHandler, goog.events.EventTarget);
|
||||
|
||||
|
||||
/**
|
||||
* Set up the event sources (mouse, touch and native pointers)
|
||||
* that generate pointer events.
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.registerSources = function() {
|
||||
if (this.isPointerEnabled_()) {
|
||||
// this.registerSource('native', new ol.pointer.NativeSource(this));
|
||||
} else if (this.isMsPointerEnabled_()) {
|
||||
// this.registerSource('ms', new ol.pointer.MsSource(this));
|
||||
} else {
|
||||
var mouseSource = new ol.pointer.MouseSource(this);
|
||||
this.registerSource('mouse', mouseSource);
|
||||
|
||||
if (this.isTouchDefined_()) {
|
||||
//this.registerSource('touch',
|
||||
// new ol.pointer.TouchSource(this, mouseSource));
|
||||
}
|
||||
}
|
||||
|
||||
// register events on the viewport element
|
||||
this.register_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @return {boolean} Returns true if the browser supports
|
||||
* native pointer events.
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.isPointerEnabled_ = function() {
|
||||
/* TODO navigation.pointerEnabled is actually not part of the
|
||||
* spec: https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890#c3
|
||||
*/
|
||||
return window.navigator['pointerEnabled'] !== undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @return {boolean} Returns true if the browser supports
|
||||
* ms pointer events (IE10).
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.isMsPointerEnabled_ = function() {
|
||||
return window.navigator['msPointerEnabled'] !== undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @return {boolean} Returns true if the browser supports
|
||||
* touch events.
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.isTouchDefined_ = function() {
|
||||
return window['ontouchstart'] !== undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add a new event source that will generate pointer events.
|
||||
*
|
||||
* @param {string} name A name for the event source
|
||||
* @param {ol.pointer.EventSource} source
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.registerSource =
|
||||
function(name, source) {
|
||||
var s = source;
|
||||
var newEvents = s.getEvents();
|
||||
|
||||
if (newEvents) {
|
||||
newEvents.forEach(function(e) {
|
||||
var handler = s.getHandlerForEvent(e);
|
||||
|
||||
if (handler) {
|
||||
this.eventMap[e] = handler.bind(s);
|
||||
}
|
||||
}, this);
|
||||
this.eventSources[name] = s;
|
||||
this.eventSourceList.push(s);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @suppress {undefinedVars}
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.log = function(obj) {
|
||||
console.log(obj);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set up the events for all registered event sources.
|
||||
* @private
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.register_ = function() {
|
||||
var l = this.eventSourceList.length;
|
||||
for (var i = 0, es; (i < l) && (es = this.eventSourceList[i]); i++) {
|
||||
this.addEvents_(es.getEvents());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove all registered events.
|
||||
* @private
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.unregister_ = function() {
|
||||
var l = this.eventSourceList.length;
|
||||
for (var i = 0, es; (i < l) && (es = this.eventSourceList[i]); i++) {
|
||||
this.removeEvents_(es.getEvents());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls the right handler for a new event.
|
||||
* @private
|
||||
* @param {goog.events.BrowserEvent} inEvent Browser event.
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.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 (this.handledEvents['get'](inEvent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var type = inEvent.type;
|
||||
var handler = this.eventMap[type];
|
||||
if (handler) {
|
||||
handler(inEvent);
|
||||
}
|
||||
this.handledEvents['set'](inEvent, true);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Setup listeners for the given events.
|
||||
* @private
|
||||
* @param {Array.<string>} events List of events.
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.addEvents_ = function(events) {
|
||||
events.forEach(function(eventName) {
|
||||
goog.events.listen(this.element_, eventName,
|
||||
this.boundHandler_);
|
||||
}, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Unregister listeners for the given events.
|
||||
* @private
|
||||
* @param {Array.<string>} events List of events.
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.removeEvents_ = function(events) {
|
||||
events.forEach(function(e) {
|
||||
goog.events.unlisten(this.element_, e,
|
||||
this.boundHandler_);
|
||||
}, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a snapshot of inEvent, with writable properties.
|
||||
*
|
||||
* @param {goog.events.BrowserEvent} inEvent An event that contains
|
||||
* properties to copy.
|
||||
* @return {Object} An object containing shallow copies of
|
||||
* `inEvent`'s properties.
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.cloneEvent = function(inEvent) {
|
||||
var eventCopy = {}, p;
|
||||
for (var i = 0; i < ol.pointer.CLONE_PROPS.length; i++) {
|
||||
p = ol.pointer.CLONE_PROPS[i];
|
||||
eventCopy[p] = inEvent[p] || ol.pointer.CLONE_DEFAULTS[i];
|
||||
}
|
||||
|
||||
// keep the semantics of preventDefault
|
||||
if (inEvent.preventDefault) {
|
||||
eventCopy.preventDefault = function() {
|
||||
inEvent.preventDefault();
|
||||
};
|
||||
}
|
||||
|
||||
return eventCopy;
|
||||
};
|
||||
|
||||
|
||||
// EVENTS
|
||||
|
||||
|
||||
/**
|
||||
* Triggers a 'pointerdown' event.
|
||||
* @param {Object} inEvent
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.down = function(inEvent) {
|
||||
this.fireEvent('pointerdown', inEvent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Triggers a 'pointermove' event.
|
||||
* @param {Object} inEvent
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.move = function(inEvent) {
|
||||
this.fireEvent('pointermove', inEvent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Triggers a 'pointerup' event.
|
||||
* @param {Object} inEvent
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.up = function(inEvent) {
|
||||
this.fireEvent('pointerup', inEvent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Triggers a 'pointerenter' event.
|
||||
* @param {Object} inEvent
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.enter = function(inEvent) {
|
||||
inEvent.bubbles = false;
|
||||
this.fireEvent('pointerenter', inEvent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Triggers a 'pointerleave' event.
|
||||
* @param {Object} inEvent
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.leave = function(inEvent) {
|
||||
inEvent.bubbles = false;
|
||||
this.fireEvent('pointerleave', inEvent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Triggers a 'pointerover' event.
|
||||
* @param {Object} inEvent
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.over = function(inEvent) {
|
||||
inEvent.bubbles = true;
|
||||
this.fireEvent('pointerover', inEvent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Triggers a 'pointerout' event.
|
||||
* @param {Object} inEvent
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.out = function(inEvent) {
|
||||
inEvent.bubbles = true;
|
||||
this.fireEvent('pointerout', inEvent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Triggers a 'pointercancel' event.
|
||||
* @param {Object} inEvent
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.cancel = function(inEvent) {
|
||||
this.fireEvent('pointercancel', inEvent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Triggers a combination of 'pointerout' and 'pointerleave' events.
|
||||
* @param {Object} inEvent
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.leaveOut = function(inEvent) {
|
||||
this.out(inEvent);
|
||||
if (!this.contains_(inEvent.target, inEvent.relatedTarget)) {
|
||||
this.leave(inEvent);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Triggers a combination of 'pointerover' and 'pointerevents' events.
|
||||
* @param {Object} inEvent
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.enterOver = function(inEvent) {
|
||||
this.over(inEvent);
|
||||
if (!this.contains_(inEvent.target, inEvent.relatedTarget)) {
|
||||
this.enter(inEvent);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Element} container
|
||||
* @param {Element} contained
|
||||
* @return {boolean} Returns true if the container element
|
||||
* contains the other element.
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.contains_ =
|
||||
function(container, contained) {
|
||||
return container.contains(contained);
|
||||
};
|
||||
|
||||
|
||||
// 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 {Object} inEvent A platform event with a target.
|
||||
* @return {ol.pointer.PointerEvent} A PointerEvent of type `inType`.
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.makeEvent = function(inType, inEvent) {
|
||||
// relatedTarget must be null if pointer is captured
|
||||
if (this.captureInfo) {
|
||||
inEvent.relatedTarget = null;
|
||||
}
|
||||
|
||||
var e = new ol.pointer.PointerEvent(inType, inEvent);
|
||||
if (inEvent.preventDefault) {
|
||||
e.preventDefault = inEvent.preventDefault;
|
||||
}
|
||||
this.targets['set'](e, this.targets['get'](inEvent) || inEvent.target);
|
||||
|
||||
return e;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Make and dispatch an event in one call.
|
||||
* @param {string} inType A string representing the type of event.
|
||||
* @param {Object} inEvent A platform event with a target.
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.fireEvent = function(inType, inEvent) {
|
||||
var e = this.makeEvent(inType, inEvent);
|
||||
var browserEvent = new goog.events.BrowserEvent(e);
|
||||
this.dispatchEvent(browserEvent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Re-fires a native pointer event.
|
||||
* @param {Event} nativeEvent A platform event with a target.
|
||||
*/
|
||||
ol.pointer.PointerEventHandler.prototype.fireNativeEvent =
|
||||
function(nativeEvent) {
|
||||
var browserEvent = new goog.events.BrowserEvent(nativeEvent);
|
||||
this.dispatchEvent(browserEvent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Constants for event names.
|
||||
* @enum {string}
|
||||
*/
|
||||
ol.pointer.EventType = {
|
||||
POINTERMOVE: 'pointermove',
|
||||
POINTERDOWN: 'pointerdown',
|
||||
POINTERUP: 'pointerup',
|
||||
POINTEROVER: 'pointerover',
|
||||
POINTERENTER: 'pointerenter',
|
||||
POINTERLEAVE: 'pointerleave',
|
||||
POINTERCANCEL: 'pointercancel'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* List of properties to copy when cloning an event.
|
||||
* @type {Array.<string>}
|
||||
*/
|
||||
ol.pointer.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'
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* List of default values when cloning an event.
|
||||
*/
|
||||
ol.pointer.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
|
||||
];
|
||||
77
src/ol/structs/weakmap.js
Normal file
77
src/ol/structs/weakmap.js
Normal file
@@ -0,0 +1,77 @@
|
||||
// Based on https://github.com/Polymer/WeakMap
|
||||
/*
|
||||
* Copyright 2012 The Polymer Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style
|
||||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('ol.structs.WeakMap');
|
||||
|
||||
|
||||
/**
|
||||
* @suppress {undefinedVars}
|
||||
* @return {boolean} Is `WeakMap` already defined?
|
||||
*/
|
||||
ol.structs.isWeakMapUndefined = function() {
|
||||
return typeof WeakMap === 'undefined';
|
||||
};
|
||||
|
||||
|
||||
if (ol.structs.isWeakMapUndefined()) {
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
ol.structs.WeakMap = function() {
|
||||
this.name = '__st' + (Math.random() * 1e9 >>> 0) +
|
||||
(ol.structs.WeakMap.counter++ + '__');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {*} key
|
||||
* @param {*} value
|
||||
*/
|
||||
ol.structs.WeakMap.prototype['set'] = function(key, value) {
|
||||
var entry = key[this.name];
|
||||
if (entry && entry[0] === key)
|
||||
entry[1] = value;
|
||||
else
|
||||
ol.structs.WeakMap.defineProperty(key, this.name,
|
||||
{value: [key, value], writable: true});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {*} key
|
||||
* @return {*}
|
||||
*/
|
||||
ol.structs.WeakMap.prototype['get'] = function(key) {
|
||||
var entry;
|
||||
return (entry = key[this.name]) && entry[0] === key ?
|
||||
entry[1] : undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @this {ol.structs.WeakMap}
|
||||
* @param {*} key
|
||||
*/
|
||||
ol.structs.WeakMap.prototype['delete'] = function(key) {
|
||||
this['set'](key, undefined);
|
||||
};
|
||||
} else {
|
||||
ol.structs.WeakMap = WeakMap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @type {function(...)}
|
||||
*/
|
||||
ol.structs.WeakMap.defineProperty = Object.defineProperty;
|
||||
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
ol.structs.WeakMap.counter = Date.now() % 1e9;
|
||||
Reference in New Issue
Block a user