(cm)
| 3396 | |
| 3397 | // Attach the necessary event handlers when initializing the editor |
| 3398 | function registerEventHandlers(cm) { |
| 3399 | var d = cm.display; |
| 3400 | on(d.scroller, "mousedown", operation(cm, onMouseDown)); |
| 3401 | // Older IE's will not fire a second mousedown for a double click |
| 3402 | if (ie && ie_version < 11) |
| 3403 | on(d.scroller, "dblclick", operation(cm, function(e) { |
| 3404 | if (signalDOMEvent(cm, e)) return; |
| 3405 | var pos = posFromMouse(cm, e); |
| 3406 | if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return; |
| 3407 | e_preventDefault(e); |
| 3408 | var word = cm.findWordAt(pos); |
| 3409 | extendSelection(cm.doc, word.anchor, word.head); |
| 3410 | })); |
| 3411 | else |
| 3412 | on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); }); |
| 3413 | // Some browsers fire contextmenu *after* opening the menu, at |
| 3414 | // which point we can't mess with it anymore. Context menu is |
| 3415 | // handled in onMouseDown for these browsers. |
| 3416 | if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);}); |
| 3417 | |
| 3418 | // Used to suppress mouse event handling when a touch happens |
| 3419 | var touchFinished, prevTouch = {end: 0}; |
| 3420 | function finishTouch() { |
| 3421 | if (d.activeTouch) { |
| 3422 | touchFinished = setTimeout(function() {d.activeTouch = null;}, 1000); |
| 3423 | prevTouch = d.activeTouch; |
| 3424 | prevTouch.end = +new Date; |
| 3425 | } |
| 3426 | }; |
| 3427 | function isMouseLikeTouchEvent(e) { |
| 3428 | if (e.touches.length != 1) return false; |
| 3429 | var touch = e.touches[0]; |
| 3430 | return touch.radiusX <= 1 && touch.radiusY <= 1; |
| 3431 | } |
| 3432 | function farAway(touch, other) { |
| 3433 | if (other.left == null) return true; |
| 3434 | var dx = other.left - touch.left, dy = other.top - touch.top; |
| 3435 | return dx * dx + dy * dy > 20 * 20; |
| 3436 | } |
| 3437 | on(d.scroller, "touchstart", function(e) { |
| 3438 | if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e)) { |
| 3439 | clearTimeout(touchFinished); |
| 3440 | var now = +new Date; |
| 3441 | d.activeTouch = {start: now, moved: false, |
| 3442 | prev: now - prevTouch.end <= 300 ? prevTouch : null}; |
| 3443 | if (e.touches.length == 1) { |
| 3444 | d.activeTouch.left = e.touches[0].pageX; |
| 3445 | d.activeTouch.top = e.touches[0].pageY; |
| 3446 | } |
| 3447 | } |
| 3448 | }); |
| 3449 | on(d.scroller, "touchmove", function() { |
| 3450 | if (d.activeTouch) d.activeTouch.moved = true; |
| 3451 | }); |
| 3452 | on(d.scroller, "touchend", function(e) { |
| 3453 | var touch = d.activeTouch; |
| 3454 | if (touch && !eventInWidget(d, e) && touch.left != null && |
| 3455 | !touch.moved && new Date - touch.start < 300) { |
no test coverage detected