selection-pointer.js (3292B)
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 // Distributed under an MIT license: http://codemirror.net/LICENSE 3 4 (function(mod) { 5 if (typeof exports == "object" && typeof module == "object") // CommonJS 6 mod(require("../../lib/codemirror")); 7 else if (typeof define == "function" && define.amd) // AMD 8 define(["../../lib/codemirror"], mod); 9 else // Plain browser env 10 mod(CodeMirror); 11 })(function(CodeMirror) { 12 "use strict"; 13 14 CodeMirror.defineOption("selectionPointer", false, function(cm, val) { 15 var data = cm.state.selectionPointer; 16 if (data) { 17 CodeMirror.off(cm.getWrapperElement(), "mousemove", data.mousemove); 18 CodeMirror.off(cm.getWrapperElement(), "mouseout", data.mouseout); 19 CodeMirror.off(window, "scroll", data.windowScroll); 20 cm.off("cursorActivity", reset); 21 cm.off("scroll", reset); 22 cm.state.selectionPointer = null; 23 cm.display.lineDiv.style.cursor = ""; 24 } 25 if (val) { 26 data = cm.state.selectionPointer = { 27 value: typeof val == "string" ? val : "default", 28 mousemove: function(event) { mousemove(cm, event); }, 29 mouseout: function(event) { mouseout(cm, event); }, 30 windowScroll: function() { reset(cm); }, 31 rects: null, 32 mouseX: null, mouseY: null, 33 willUpdate: false 34 }; 35 CodeMirror.on(cm.getWrapperElement(), "mousemove", data.mousemove); 36 CodeMirror.on(cm.getWrapperElement(), "mouseout", data.mouseout); 37 CodeMirror.on(window, "scroll", data.windowScroll); 38 cm.on("cursorActivity", reset); 39 cm.on("scroll", reset); 40 } 41 }); 42 43 function mousemove(cm, event) { 44 var data = cm.state.selectionPointer; 45 if (event.buttons == null ? event.which : event.buttons) { 46 data.mouseX = data.mouseY = null; 47 } else { 48 data.mouseX = event.clientX; 49 data.mouseY = event.clientY; 50 } 51 scheduleUpdate(cm); 52 } 53 54 function mouseout(cm, event) { 55 if (!cm.getWrapperElement().contains(event.relatedTarget)) { 56 var data = cm.state.selectionPointer; 57 data.mouseX = data.mouseY = null; 58 scheduleUpdate(cm); 59 } 60 } 61 62 function reset(cm) { 63 cm.state.selectionPointer.rects = null; 64 scheduleUpdate(cm); 65 } 66 67 function scheduleUpdate(cm) { 68 if (!cm.state.selectionPointer.willUpdate) { 69 cm.state.selectionPointer.willUpdate = true; 70 setTimeout(function() { 71 update(cm); 72 cm.state.selectionPointer.willUpdate = false; 73 }, 50); 74 } 75 } 76 77 function update(cm) { 78 var data = cm.state.selectionPointer; 79 if (!data) return; 80 if (data.rects == null && data.mouseX != null) { 81 data.rects = []; 82 if (cm.somethingSelected()) { 83 for (var sel = cm.display.selectionDiv.firstChild; sel; sel = sel.nextSibling) 84 data.rects.push(sel.getBoundingClientRect()); 85 } 86 } 87 var inside = false; 88 if (data.mouseX != null) for (var i = 0; i < data.rects.length; i++) { 89 var rect = data.rects[i]; 90 if (rect.left <= data.mouseX && rect.right >= data.mouseX && 91 rect.top <= data.mouseY && rect.bottom >= data.mouseY) 92 inside = true; 93 } 94 var cursor = inside ? data.value : ""; 95 if (cm.display.lineDiv.style.cursor != cursor) 96 cm.display.lineDiv.style.cursor = cursor; 97 } 98 });