|
70 | 70 | var windowStyle = window.getComputedStyle(document.body); |
71 | 71 | this.pointerEventsSupport = windowStyle.pointerEvents && windowStyle.pointerEvents === 'auto'; |
72 | 72 |
|
| 73 | + // Some useful regexes. |
| 74 | + this.regexOn = /^on/; |
| 75 | + this.regexMouseEvents = /^(dbl)?click$|^mouse(move|down|up|over|out|enter|leave)$|^contextmenu$/; |
| 76 | + this.regexUiEvents = /^(focus|blur|select|change|reset)$|^key(press|down|up)$/; |
| 77 | + this.regexHtmlEvents = /^(scroll|resize|(un)?load|abort|error)$/; |
| 78 | + // Whether to use event constructors. |
| 79 | + this.useEventConstructors = true; |
| 80 | + try { |
| 81 | + var e = new MouseEvent('click'); |
| 82 | + } catch (e) { |
| 83 | + this.useEventConstructors = false; |
| 84 | + } |
| 85 | + |
73 | 86 | // If mode is not provided, use PointerEvents, if it's supported. |
74 | 87 | if (typeof mode === 'undefined') { |
75 | 88 | this.mode = this.pointerEventsSupport ? 'PointerEvents' : 'EventForwarding'; |
|
86 | 99 | _createClass(NonBlock, [{ |
87 | 100 | key: 'initPointerEvents', |
88 | 101 | value: function initPointerEvents() { |
| 102 | + var _this = this; |
| 103 | + |
89 | 104 | // Using pointer-events, we can just detect whether an element is being |
90 | 105 | // hovered over. No event forwarding necessary. |
91 | 106 |
|
|
104 | 119 |
|
105 | 120 | var rect = nonblock.getBoundingClientRect(); |
106 | 121 | if (ev.clientX >= rect.left && ev.clientX <= rect.right && ev.clientY >= rect.top && ev.clientY <= rect.bottom) { |
107 | | - nonblock.classList.add('nonblock-hover'); |
| 122 | + if (!nonblock.classList.contains('nonblock-hover')) { |
| 123 | + nonblock.classList.add('nonblock-hover'); |
| 124 | + if (_this.isSimulateMouse(nonblock) && ev.isTrusted) { |
| 125 | + _this.domEvent(nonblock, 'onmouseenter', ev, false); |
| 126 | + _this.domEvent(nonblock, 'onmouseover', ev, true); |
| 127 | + } |
| 128 | + } else if (_this.isSimulateMouse(nonblock) && ev.isTrusted) { |
| 129 | + _this.domEvent(nonblock, 'onmousemove', ev, true); |
| 130 | + } |
108 | 131 | } else { |
109 | 132 | if (nonblock.classList.contains('nonblock-hover')) { |
| 133 | + if (_this.isSimulateMouse(nonblock) && ev.isTrusted) { |
| 134 | + _this.domEvent(nonblock, 'onmouseout', ev, true); |
| 135 | + _this.domEvent(nonblock, 'onmouseleave', ev, false); |
| 136 | + } |
110 | 137 | nonblock.classList.remove('nonblock-hover'); |
111 | 138 | } |
112 | 139 | } |
|
132 | 159 | }, { |
133 | 160 | key: 'initEventForwarding', |
134 | 161 | value: function initEventForwarding() { |
135 | | - var _this = this; |
| 162 | + var _this2 = this; |
136 | 163 |
|
137 | 164 | // No pointer-events means we have to fall back to using event forwarding. |
138 | 165 |
|
|
144 | 171 | // These are used for selecting text under a nonblock element. |
145 | 172 | this.isOverTextNode = false; |
146 | 173 | this.selectingText = false; |
147 | | - // Some useful regexes. |
148 | | - this.regexOn = /^on/; |
149 | | - this.regexMouseEvents = /^(dbl)?click$|^mouse(move|down|up|over|out|enter|leave)$|^contextmenu$/; |
150 | | - this.regexUiEvents = /^(focus|blur|select|change|reset)$|^key(press|down|up)$/; |
151 | | - this.regexHtmlEvents = /^(scroll|resize|(un)?load|abort|error)$/; |
152 | | - // Whether to use event constructors. |
153 | | - this.useEventConstructors = true; |
154 | | - try { |
155 | | - var e = new MouseEvent('click'); |
156 | | - } catch (e) { |
157 | | - this.useEventConstructors = false; |
158 | | - } |
159 | 174 |
|
160 | 175 | this.onmouseenter = function (ev) { |
161 | 176 | var nonblock = void 0; |
162 | | - if (ev.isTrusted && (nonblock = _this.getNonBlocking(ev.target))) { |
163 | | - _this.nonBlockLastElem = false; |
164 | | - if (!_this.isPropagating(nonblock)) { |
| 177 | + if (ev.isTrusted && (nonblock = _this2.getNonBlocking(ev.target))) { |
| 178 | + _this2.nonBlockLastElem = false; |
| 179 | + if (!_this2.isPropagating(nonblock)) { |
165 | 180 | ev.stopPropagation(); |
166 | 181 | } |
167 | 182 | } |
168 | 183 | }; |
169 | 184 | this.onmouseleave = function (ev) { |
170 | 185 | var nonblock = void 0; |
171 | | - if (ev.isTrusted && (nonblock = _this.getNonBlocking(ev.target))) { |
172 | | - _this.remCursor(nonblock); |
173 | | - _this.nonBlockLastElem = null; |
174 | | - _this.selectingText = false; |
175 | | - if (!_this.isPropagating(nonblock)) { |
| 186 | + if (ev.isTrusted && (nonblock = _this2.getNonBlocking(ev.target))) { |
| 187 | + _this2.remCursor(nonblock); |
| 188 | + _this2.nonBlockLastElem = null; |
| 189 | + _this2.selectingText = false; |
| 190 | + if (!_this2.isPropagating(nonblock)) { |
176 | 191 | ev.stopPropagation(); |
177 | 192 | } |
178 | 193 | } |
179 | 194 | }; |
180 | 195 | this.onmouseover = function (ev) { |
181 | 196 | var nonblock = void 0; |
182 | | - if (ev.isTrusted && (nonblock = _this.getNonBlocking(ev.target)) && !_this.isPropagating(nonblock)) { |
| 197 | + if (ev.isTrusted && (nonblock = _this2.getNonBlocking(ev.target)) && !_this2.isPropagating(nonblock)) { |
183 | 198 | ev.stopPropagation(); |
184 | 199 | } |
185 | 200 | }; |
186 | 201 | this.onmouseout = function (ev) { |
187 | 202 | var nonblock = void 0; |
188 | | - if (ev.isTrusted && (nonblock = _this.getNonBlocking(ev.target)) && !_this.isPropagating(nonblock)) { |
| 203 | + if (ev.isTrusted && (nonblock = _this2.getNonBlocking(ev.target)) && !_this2.isPropagating(nonblock)) { |
189 | 204 | ev.stopPropagation(); |
190 | 205 | } |
191 | 206 | }; |
192 | 207 | this.onmousemove = function (ev) { |
193 | 208 | var nonblock = void 0; |
194 | | - if (ev.isTrusted && (nonblock = _this.getNonBlocking(ev.target))) { |
195 | | - _this.nonblockPass(nonblock, ev, 'onmousemove'); |
| 209 | + if (ev.isTrusted && (nonblock = _this2.getNonBlocking(ev.target))) { |
| 210 | + _this2.nonblockPass(nonblock, ev, 'onmousemove'); |
196 | 211 | // If the user just clicks somewhere, we don't want to select text, so this |
197 | 212 | // detects that the user moved their mouse. |
198 | | - if (_this.selectingText === null) { |
| 213 | + if (_this2.selectingText === null) { |
199 | 214 | window.getSelection().removeAllRanges(); |
200 | | - _this.selectingText = true; |
201 | | - } else if (_this.selectingText) { |
| 215 | + _this2.selectingText = true; |
| 216 | + } else if (_this2.selectingText) { |
202 | 217 | // Stop the default action, which would be selecting text. |
203 | 218 | ev.preventDefault(); |
204 | 219 | } |
205 | | - if (!_this.isPropagating(nonblock)) { |
| 220 | + if (!_this2.isPropagating(nonblock)) { |
206 | 221 | ev.stopPropagation(); |
207 | 222 | } |
208 | 223 | } |
209 | 224 | }; |
210 | 225 | this.onmousedown = function (ev) { |
211 | 226 | var nonblock = void 0; |
212 | | - if (ev.isTrusted && (nonblock = _this.getNonBlocking(ev.target))) { |
213 | | - _this.nonblockPass(nonblock, ev, 'onmousedown'); |
214 | | - _this.selectingText = null; |
215 | | - if (!_this.isFocusable(nonblock)) { |
| 227 | + if (ev.isTrusted && (nonblock = _this2.getNonBlocking(ev.target))) { |
| 228 | + _this2.nonblockPass(nonblock, ev, 'onmousedown'); |
| 229 | + _this2.selectingText = null; |
| 230 | + if (!_this2.isFocusable(nonblock)) { |
216 | 231 | // Stop the default action, which would focus the element. |
217 | 232 | ev.preventDefault(); |
218 | 233 | } |
219 | | - if (!_this.isPropagating(nonblock) || !_this.isActionPropagating(nonblock)) { |
| 234 | + if (!_this2.isPropagating(nonblock) || !_this2.isActionPropagating(nonblock)) { |
220 | 235 | ev.stopPropagation(); |
221 | 236 | } |
222 | 237 | } |
223 | 238 | }; |
224 | 239 | this.onmouseup = function (ev) { |
225 | 240 | var nonblock = void 0; |
226 | | - if (ev.isTrusted && (nonblock = _this.getNonBlocking(ev.target))) { |
227 | | - _this.nonblockPass(nonblock, ev, 'onmouseup'); |
228 | | - if (_this.selectingText === null) { |
| 241 | + if (ev.isTrusted && (nonblock = _this2.getNonBlocking(ev.target))) { |
| 242 | + _this2.nonblockPass(nonblock, ev, 'onmouseup'); |
| 243 | + if (_this2.selectingText === null) { |
229 | 244 | window.getSelection().removeAllRanges(); |
230 | 245 | } |
231 | | - _this.selectingText = false; |
232 | | - if (!_this.isPropagating(nonblock) || !_this.isActionPropagating(nonblock)) { |
| 246 | + _this2.selectingText = false; |
| 247 | + if (!_this2.isPropagating(nonblock) || !_this2.isActionPropagating(nonblock)) { |
233 | 248 | ev.stopPropagation(); |
234 | 249 | } |
235 | 250 | } |
236 | 251 | }; |
237 | 252 | this.onclick = function (ev) { |
238 | 253 | var nonblock = void 0; |
239 | | - if (ev.isTrusted && (nonblock = _this.getNonBlocking(ev.target))) { |
240 | | - _this.nonblockPass(nonblock, ev, 'onclick'); |
241 | | - if (!_this.isPropagating(nonblock) || !_this.isActionPropagating(nonblock)) { |
| 254 | + if (ev.isTrusted && (nonblock = _this2.getNonBlocking(ev.target))) { |
| 255 | + _this2.nonblockPass(nonblock, ev, 'onclick'); |
| 256 | + if (!_this2.isPropagating(nonblock) || !_this2.isActionPropagating(nonblock)) { |
242 | 257 | ev.stopPropagation(); |
243 | 258 | } |
244 | 259 | } |
245 | 260 | }; |
246 | 261 | this.ondblclick = function (ev) { |
247 | 262 | var nonblock = void 0; |
248 | | - if (ev.isTrusted && (nonblock = _this.getNonBlocking(ev.target))) { |
249 | | - _this.nonblockPass(nonblock, ev, 'ondblclick'); |
250 | | - if (!_this.isPropagating(nonblock) || !_this.isActionPropagating(nonblock)) { |
| 263 | + if (ev.isTrusted && (nonblock = _this2.getNonBlocking(ev.target))) { |
| 264 | + _this2.nonblockPass(nonblock, ev, 'ondblclick'); |
| 265 | + if (!_this2.isPropagating(nonblock) || !_this2.isActionPropagating(nonblock)) { |
251 | 266 | ev.stopPropagation(); |
252 | 267 | } |
253 | 268 | } |
|
487 | 502 | value: function isFocusable(el) { |
488 | 503 | return el.classList.contains('nonblock-allow-focus'); |
489 | 504 | } |
| 505 | + }, { |
| 506 | + key: 'isSimulateMouse', |
| 507 | + value: function isSimulateMouse(el) { |
| 508 | + return !el.classList.contains('nonblock-stop-mouse-simulation'); |
| 509 | + } |
490 | 510 | }, { |
491 | 511 | key: 'getCursor', |
492 | 512 | value: function getCursor(el) { |
|
0 commit comments