|
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