From 3c1505d0444ffac75bb4da7c99c993780303c83b Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke <marijnh@gmail.com> Date: Thu, 22 Jan 2015 16:11:27 +0100 Subject: [PATCH] [selection-pointer addon] Add --- addon/selection/selection-pointer.js | 95 ++++++++++++++++++++++++++++ doc/manual.html | 8 +++ mode/htmlmixed/index.html | 6 +- 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 addon/selection/selection-pointer.js diff --git a/addon/selection/selection-pointer.js b/addon/selection/selection-pointer.js new file mode 100644 index 000000000..ba5999496 --- /dev/null +++ b/addon/selection/selection-pointer.js @@ -0,0 +1,95 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineOption("selectionPointer", false, function(cm, val) { + var data = cm.state.selectionPointer; + if (data) { + CodeMirror.off(cm.getWrapperElement(), "mousemove", data.mousemove); + CodeMirror.off(cm.getWrapperElement(), "mouseleave", data.mouseleave); + cm.off("cursorActivity", reset); + cm.off("scroll", reset); + cm.state.selectionPointer = null; + cm.display.lineDiv.style.cursor = ""; + } + if (val) { + data = cm.state.selectionPointer = { + value: typeof val == "string" ? val : "default", + mousemove: function(event) { mousemove(cm, event); }, + mouseleave: function(event) { mouseleave(cm, event); }, + rects: null, + mouseX: null, mouseY: null, + willUpdate: false + }; + CodeMirror.on(cm.getWrapperElement(), "mousemove", data.mousemove); + CodeMirror.on(cm.getWrapperElement(), "mousemove", data.mousemove); + cm.on("cursorActivity", reset); + cm.on("scroll", reset); + } + }); + + function mousemove(cm, event) { + var data = cm.state.selectionPointer; + if (event.buttons == null ? event.which : event.buttons) { + data.mouseX = data.mouseY = null; + } else { + data.mouseX = event.clientX; + data.mouseY = event.clientY; + } + scheduleUpdate(cm); + } + + function mouseout(cm, event) { + if (!cm.getWrapperElement().contains(event.relatedTarget)) { + var data = cm.state.selectionPointer; + data.mouseX = data.mouseY = null; + scheduleUpdate(cm); + } + } + + function reset(cm) { + cm.state.selectionPointer.rects = null; + scheduleUpdate(cm); + } + + function scheduleUpdate(cm) { + if (!cm.state.selectionPointer.willUpdate) { + cm.state.selectionPointer.willUpdate = true; + setTimeout(function() { + update(cm); + cm.state.selectionPointer.willUpdate = false; + }, 50); + } + } + + function update(cm) { + var data = cm.state.selectionPointer; + if (!data) return; + if (data.rects == null && data.mouseX != null) { + data.rects = []; + if (cm.somethingSelected()) { + for (var sel = cm.display.selectionDiv.firstChild; sel; sel = sel.nextSibling) + data.rects.push(sel.getBoundingClientRect()); + } + } + var inside = false; + if (data.mouseX != null) for (var i = 0; i < data.rects.length; i++) { + var rect = data.rects[i]; + if (rect.left <= data.mouseX && rect.right >= data.mouseX && + rect.top <= data.mouseY && rect.bottom >= data.mouseY) + inside = true; + } + var cursor = inside ? data.value : ""; + if (cm.display.lineDiv.style.cursor != cursor) + cm.display.lineDiv.style.cursor = cursor; + } +}); diff --git a/doc/manual.html b/doc/manual.html index 4fee2bed9..365104051 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -2635,6 +2635,14 @@ editor.setOption("extraKeys", { and adds a background with the class <code>CodeMirror-activeline-background</code>. is enabled. See the <a href="../demo/activeline.html">demo</a>.</dd> + <dt id="addon_selection-pointer"><a href="../addon/selection/selection-pointer.js"><code>selection/selection-pointer.js</code></a></dt> + <dd>Defines a <code>selectionPointer</code> option which you can + use to control the mouse cursor appearance when hovering over + the selection. It can be set to a string, + like <code>"pointer"</code>, or to true, in which case + the <code>"default"</code> (arrow) cursor will be used. You can + see a demo <a href="../mode/htmlmixed/index.html">here</a>.</dd> + <dt id="addon_loadmode"><a href="../addon/mode/loadmode.js"><code>mode/loadmode.js</code></a></dt> <dd>Defines a <code>CodeMirror.requireMode(modename, callback)</code> function that will try to load a given mode and diff --git a/mode/htmlmixed/index.html b/mode/htmlmixed/index.html index 61630293f..f94df9e21 100644 --- a/mode/htmlmixed/index.html +++ b/mode/htmlmixed/index.html @@ -6,6 +6,7 @@ <link rel="stylesheet" href="../../lib/codemirror.css"> <script src="../../lib/codemirror.js"></script> +<script src="../../addon/selection/selection-pointer.js"></script> <script src="../xml/xml.js"></script> <script src="../javascript/javascript.js"></script> <script src="../css/css.js"></script> @@ -62,7 +63,10 @@ {matches: /(text|application)\/(x-)?vb(a|script)/i, mode: "vbscript"}] }; - var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: mixedMode}); + var editor = CodeMirror.fromTextArea(document.getElementById("code"), { + mode: mixedMode, + selectionPointer: true + }); </script> <p>The HTML mixed mode depends on the XML, JavaScript, and CSS modes.</p> -- GitLab