|
19 | 19 | * @return {Event} A new PointerEvent of type `inType` and initialized with properties from `inDict`.
|
20 | 20 | */
|
21 | 21 | (function(scope) {
|
22 |
| - // test for DOM Level 4 Events |
23 |
| - var NEW_MOUSE_EVENT = false; |
24 |
| - var HAS_BUTTONS = false; |
25 |
| - try { |
26 |
| - var ev = new MouseEvent('click', {buttons: 1}); |
27 |
| - NEW_MOUSE_EVENT = true; |
28 |
| - HAS_BUTTONS = ev.buttons === 1; |
29 |
| - ev = null; |
30 |
| - } catch(e) { |
31 |
| - } |
32 | 22 |
|
33 | 23 | var MOUSE_PROPS = [
|
34 | 24 | 'bubbles',
|
|
45 | 35 | 'metaKey',
|
46 | 36 | 'button',
|
47 | 37 | 'relatedTarget',
|
| 38 | + 'pageX', |
| 39 | + 'pageY' |
48 | 40 | ];
|
49 | 41 |
|
50 | 42 | var MOUSE_DEFAULTS = [
|
|
61 | 53 | false,
|
62 | 54 | false,
|
63 | 55 | 0,
|
64 |
| - null |
| 56 | + null, |
| 57 | + 0, |
| 58 | + 0 |
65 | 59 | ];
|
66 | 60 |
|
67 | 61 | function PointerEvent(inType, inDict) {
|
68 |
| - inDict = inDict || {}; |
69 |
| - // According to the w3c spec, |
70 |
| - // http://www.w3.org/TR/DOM-Level-3-Events/#events-MouseEvent-button |
71 |
| - // MouseEvent.button == 0 can mean either no mouse button depressed, or the |
72 |
| - // left mouse button depressed. |
73 |
| - // |
74 |
| - // As of now, the only way to distinguish between the two states of |
75 |
| - // MouseEvent.button is by using the deprecated MouseEvent.which property, as |
76 |
| - // this maps mouse buttons to positive integers > 0, and uses 0 to mean that |
77 |
| - // no mouse button is held. |
78 |
| - // |
79 |
| - // MouseEvent.which is derived from MouseEvent.button at MouseEvent creation, |
80 |
| - // but initMouseEvent does not expose an argument with which to set |
81 |
| - // MouseEvent.which. Calling initMouseEvent with a buttonArg of 0 will set |
82 |
| - // MouseEvent.button == 0 and MouseEvent.which == 1, breaking the expectations |
83 |
| - // of app developers. |
84 |
| - // |
85 |
| - // The only way to propagate the correct state of MouseEvent.which and |
86 |
| - // MouseEvent.button to a new MouseEvent.button == 0 and MouseEvent.which == 0 |
87 |
| - // is to call initMouseEvent with a buttonArg value of -1. |
88 |
| - // |
89 |
| - // This is fixed with DOM Level 4's use of buttons |
90 |
| - var buttons = inDict.buttons; |
91 |
| - // touch has two possible buttons state: 0 and 1, rely on being told the right one |
92 |
| - if (!HAS_BUTTONS && !buttons && inType !== 'touch') { |
93 |
| - switch (inDict.which) { |
94 |
| - case 1: buttons = 1; break; |
95 |
| - case 2: buttons = 4; break; |
96 |
| - case 3: buttons = 2; break; |
97 |
| - default: buttons = 0; |
98 |
| - } |
99 |
| - } |
100 |
| - |
101 |
| - var e; |
102 |
| - if (NEW_MOUSE_EVENT) { |
103 |
| - e = new MouseEvent(inType, inDict); |
104 |
| - } else { |
105 |
| - e = document.createEvent('MouseEvent'); |
| 62 | + inDict = inDict || Object.create(null); |
106 | 63 |
|
107 |
| - // import values from the given dictionary |
108 |
| - var props = {}, p; |
109 |
| - for(var i = 0; i < MOUSE_PROPS.length; i++) { |
110 |
| - p = MOUSE_PROPS[i]; |
111 |
| - props[p] = inDict[p] || MOUSE_DEFAULTS[i]; |
112 |
| - } |
| 64 | + var e = document.createEvent('Event'); |
| 65 | + e.initEvent(inType, inDict.bubbles || false, inDict.cancelable || false); |
113 | 66 |
|
114 |
| - // define the properties inherited from MouseEvent |
115 |
| - e.initMouseEvent( |
116 |
| - inType, props.bubbles, props.cancelable, props.view, props.detail, |
117 |
| - props.screenX, props.screenY, props.clientX, props.clientY, props.ctrlKey, |
118 |
| - props.altKey, props.shiftKey, props.metaKey, props.button, props.relatedTarget |
119 |
| - ); |
120 |
| - } |
121 |
| - |
122 |
| - // make the event pass instanceof checks |
123 |
| - e.__proto__ = PointerEvent.prototype; |
124 |
| - |
125 |
| - // define the buttons property according to DOM Level 3 spec |
126 |
| - if (!HAS_BUTTONS) { |
127 |
| - // IE 10 has buttons on MouseEvent.prototype as a getter w/o any setting |
128 |
| - // mechanism |
129 |
| - Object.defineProperty(e, 'buttons', {get: function(){ return buttons; }, enumerable: true}); |
| 67 | + // define inherited MouseEvent properties |
| 68 | + for(var i = 0, p; i < MOUSE_PROPS.length; i++) { |
| 69 | + p = MOUSE_PROPS[i]; |
| 70 | + e[p] = inDict[p] || MOUSE_DEFAULTS[i]; |
130 | 71 | }
|
| 72 | + e.buttons = inDict.buttons || 0; |
131 | 73 |
|
132 | 74 | // Spec requires that pointers without pressure specified use 0.5 for down
|
133 | 75 | // state and 0 for up state.
|
134 | 76 | var pressure = 0;
|
135 | 77 | if (inDict.pressure) {
|
136 | 78 | pressure = inDict.pressure;
|
137 | 79 | } else {
|
138 |
| - pressure = buttons ? 0.5 : 0; |
| 80 | + pressure = e.buttons ? 0.5 : 0; |
139 | 81 | }
|
140 | 82 |
|
141 | 83 | // define the properties of the PointerEvent interface
|
142 |
| - Object.defineProperties(e, { |
143 |
| - pointerId: { value: inDict.pointerId || 0, enumerable: true }, |
144 |
| - width: { value: inDict.width || 0, enumerable: true }, |
145 |
| - height: { value: inDict.height || 0, enumerable: true }, |
146 |
| - pressure: { value: pressure, enumerable: true }, |
147 |
| - tiltX: { value: inDict.tiltX || 0, enumerable: true }, |
148 |
| - tiltY: { value: inDict.tiltY || 0, enumerable: true }, |
149 |
| - pointerType: { value: inDict.pointerType || '', enumerable: true }, |
150 |
| - hwTimestamp: { value: inDict.hwTimestamp || 0, enumerable: true }, |
151 |
| - isPrimary: { value: inDict.isPrimary || false, enumerable: true } |
152 |
| - }); |
| 84 | + e.pointerId = inDict.pointerId || 0; |
| 85 | + e.width = inDict.width || 0; |
| 86 | + e.height = inDict.height || 0; |
| 87 | + e.pressure = pressure; |
| 88 | + e.tiltX = inDict.tiltX || 0; |
| 89 | + e.tiltY = inDict.tiltY || 0; |
| 90 | + e.pointerType = inDict.pointerType || ''; |
| 91 | + e.hwTimestamp = inDict.hwTimestamp || 0; |
| 92 | + e.isPrimary = inDict.isPrimary || false; |
153 | 93 | return e;
|
154 | 94 | }
|
155 | 95 |
|
156 |
| - // PointerEvent extends MouseEvent |
157 |
| - PointerEvent.prototype = Object.create(MouseEvent.prototype); |
158 |
| - |
159 | 96 | // attach to window
|
160 | 97 | if (!scope.PointerEvent) {
|
161 | 98 | scope.PointerEvent = PointerEvent;
|
|
0 commit comments