From 4025e07cc10ab11757d7fff15a2a003f5f4987c0 Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 27 Mar 2015 10:11:01 +0100 Subject: [PATCH 1/2] Better highlighting bevahior for codeeditor.js --- mix/qml/html/cm/codemirror.css | 4 +- mix/qml/html/cm/mark-selection.js | 118 ++++++++++++++++++++++++++++++ mix/qml/html/cm/solarized.css | 4 +- mix/qml/html/codeeditor.html | 1 + mix/qml/html/codeeditor.js | 3 +- mix/web.qrc | 1 + 6 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 mix/qml/html/cm/mark-selection.js diff --git a/mix/qml/html/cm/codemirror.css b/mix/qml/html/cm/codemirror.css index bdb3d5347..b182ab305 100644 --- a/mix/qml/html/cm/codemirror.css +++ b/mix/qml/html/cm/codemirror.css @@ -304,7 +304,7 @@ div.CodeMirror-cursors { @media print { /* Hide the cursor when printing */ .CodeMirror div.CodeMirror-cursors { - visibility: hidden; + visibility: hidden; } } @@ -312,4 +312,4 @@ div.CodeMirror-cursors { .cm-tab-wrap-hack:after { content: ''; } /* Help users use markselection to safely style text background */ -span.CodeMirror-selectedtext { background: none; } +span.CodeMirror-selectedtext { color: #586e75; } diff --git a/mix/qml/html/cm/mark-selection.js b/mix/qml/html/cm/mark-selection.js new file mode 100644 index 000000000..5c42d21eb --- /dev/null +++ b/mix/qml/html/cm/mark-selection.js @@ -0,0 +1,118 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Because sometimes you need to mark the selected *text*. +// +// Adds an option 'styleSelectedText' which, when enabled, gives +// selected text the CSS class given as option value, or +// "CodeMirror-selectedtext" when the value is not a string. + +(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("styleSelectedText", false, function(cm, val, old) { + var prev = old && old != CodeMirror.Init; + if (val && !prev) { + cm.state.markedSelection = []; + cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext"; + reset(cm); + cm.on("cursorActivity", onCursorActivity); + cm.on("change", onChange); + } else if (!val && prev) { + cm.off("cursorActivity", onCursorActivity); + cm.off("change", onChange); + clear(cm); + cm.state.markedSelection = cm.state.markedSelectionStyle = null; + } + }); + + function onCursorActivity(cm) { + cm.operation(function() { update(cm); }); + } + + function onChange(cm) { + if (cm.state.markedSelection.length) + cm.operation(function() { clear(cm); }); + } + + var CHUNK_SIZE = 8; + var Pos = CodeMirror.Pos; + var cmp = CodeMirror.cmpPos; + + function coverRange(cm, from, to, addAt) { + if (cmp(from, to) == 0) return; + var array = cm.state.markedSelection; + var cls = cm.state.markedSelectionStyle; + for (var line = from.line;;) { + var start = line == from.line ? from : Pos(line, 0); + var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line; + var end = atEnd ? to : Pos(endLine, 0); + var mark = cm.markText(start, end, {className: cls}); + if (addAt == null) array.push(mark); + else array.splice(addAt++, 0, mark); + if (atEnd) break; + line = endLine; + } + } + + function clear(cm) { + var array = cm.state.markedSelection; + for (var i = 0; i < array.length; ++i) array[i].clear(); + array.length = 0; + } + + function reset(cm) { + clear(cm); + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) + coverRange(cm, ranges[i].from(), ranges[i].to()); + } + + function update(cm) { + if (!cm.somethingSelected()) return clear(cm); + if (cm.listSelections().length > 1) return reset(cm); + + var from = cm.getCursor("start"), to = cm.getCursor("end"); + + var array = cm.state.markedSelection; + if (!array.length) return coverRange(cm, from, to); + + var coverStart = array[0].find(), coverEnd = array[array.length - 1].find(); + if (!coverStart || !coverEnd || to.line - from.line < CHUNK_SIZE || + cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0) + return reset(cm); + + while (cmp(from, coverStart.from) > 0) { + array.shift().clear(); + coverStart = array[0].find(); + } + if (cmp(from, coverStart.from) < 0) { + if (coverStart.to.line - from.line < CHUNK_SIZE) { + array.shift().clear(); + coverRange(cm, from, coverStart.to, 0); + } else { + coverRange(cm, from, coverStart.from, 0); + } + } + + while (cmp(to, coverEnd.to) < 0) { + array.pop().clear(); + coverEnd = array[array.length - 1].find(); + } + if (cmp(to, coverEnd.to) > 0) { + if (to.line - coverEnd.from.line < CHUNK_SIZE) { + array.pop().clear(); + coverRange(cm, coverEnd.from, to); + } else { + coverRange(cm, coverEnd.to, to); + } + } + } +}); diff --git a/mix/qml/html/cm/solarized.css b/mix/qml/html/cm/solarized.css index ece98a95c..c5d930627 100644 --- a/mix/qml/html/cm/solarized.css +++ b/mix/qml/html/cm/solarized.css @@ -166,7 +166,7 @@ view-port /* Code execution */ .CodeMirror-exechighlight { - background: rgba(255, 255, 255, 0.10); + background: #eee8d5; } /* Error annotation */ @@ -182,3 +182,5 @@ view-port padding: 2px; } +span.CodeMirror-selectedtext { color: #586e75 !important; } + diff --git a/mix/qml/html/codeeditor.html b/mix/qml/html/codeeditor.html index eec13f109..c9d4ff96a 100644 --- a/mix/qml/html/codeeditor.html +++ b/mix/qml/html/codeeditor.html @@ -22,6 +22,7 @@ + diff --git a/mix/qml/html/codeeditor.js b/mix/qml/html/codeeditor.js index daf1286d8..41e9749a3 100644 --- a/mix/qml/html/codeeditor.js +++ b/mix/qml/html/codeeditor.js @@ -4,7 +4,8 @@ var editor = CodeMirror(document.body, { matchBrackets: true, autofocus: true, gutters: ["CodeMirror-linenumbers", "breakpoints"], - autoCloseBrackets: true + autoCloseBrackets: true, + styleSelectedText: true }); var ternServer; diff --git a/mix/web.qrc b/mix/web.qrc index aa5b38a67..63a3a668f 100644 --- a/mix/web.qrc +++ b/mix/web.qrc @@ -39,5 +39,6 @@ qml/html/cm/acorn.js qml/html/cm/acorn_loose.js qml/html/cm/walk.js + qml/html/cm/mark-selection.js From c105714c63301b100f456c1403f5077f2a95c1a1 Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 27 Mar 2015 10:54:51 +0100 Subject: [PATCH 2/2] small changes --- mix/qml/html/cm/codemirror.css | 4 +- mix/qml/html/cm/mark-selection.js | 144 +++++++++++++++--------------- mix/qml/html/cm/solarized.css | 1 - 3 files changed, 74 insertions(+), 75 deletions(-) diff --git a/mix/qml/html/cm/codemirror.css b/mix/qml/html/cm/codemirror.css index b182ab305..625baa942 100644 --- a/mix/qml/html/cm/codemirror.css +++ b/mix/qml/html/cm/codemirror.css @@ -311,5 +311,5 @@ div.CodeMirror-cursors { /* See issue #2901 */ .cm-tab-wrap-hack:after { content: ''; } -/* Help users use markselection to safely style text background */ -span.CodeMirror-selectedtext { color: #586e75; } +/* Help users use markselection to safely style text background +span.CodeMirror-selectedtext { color: #586e75; } */ diff --git a/mix/qml/html/cm/mark-selection.js b/mix/qml/html/cm/mark-selection.js index 5c42d21eb..22e46ef32 100644 --- a/mix/qml/html/cm/mark-selection.js +++ b/mix/qml/html/cm/mark-selection.js @@ -9,37 +9,37 @@ (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); + mod(require("../../lib/codemirror")); else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); + define(["../../lib/codemirror"], mod); else // Plain browser env - mod(CodeMirror); + mod(CodeMirror); })(function(CodeMirror) { "use strict"; CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) { - var prev = old && old != CodeMirror.Init; - if (val && !prev) { - cm.state.markedSelection = []; - cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext"; - reset(cm); - cm.on("cursorActivity", onCursorActivity); - cm.on("change", onChange); - } else if (!val && prev) { - cm.off("cursorActivity", onCursorActivity); - cm.off("change", onChange); - clear(cm); - cm.state.markedSelection = cm.state.markedSelectionStyle = null; - } + var prev = old && old != CodeMirror.Init; + if (val && !prev) { + cm.state.markedSelection = []; + cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext"; + reset(cm); + cm.on("cursorActivity", onCursorActivity); + cm.on("change", onChange); + } else if (!val && prev) { + cm.off("cursorActivity", onCursorActivity); + cm.off("change", onChange); + clear(cm); + cm.state.markedSelection = cm.state.markedSelectionStyle = null; + } }); function onCursorActivity(cm) { - cm.operation(function() { update(cm); }); + cm.operation(function() { update(cm); }); } function onChange(cm) { - if (cm.state.markedSelection.length) - cm.operation(function() { clear(cm); }); + if (cm.state.markedSelection.length) + cm.operation(function() { clear(cm); }); } var CHUNK_SIZE = 8; @@ -47,72 +47,72 @@ var cmp = CodeMirror.cmpPos; function coverRange(cm, from, to, addAt) { - if (cmp(from, to) == 0) return; - var array = cm.state.markedSelection; - var cls = cm.state.markedSelectionStyle; - for (var line = from.line;;) { - var start = line == from.line ? from : Pos(line, 0); - var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line; - var end = atEnd ? to : Pos(endLine, 0); - var mark = cm.markText(start, end, {className: cls}); - if (addAt == null) array.push(mark); - else array.splice(addAt++, 0, mark); - if (atEnd) break; - line = endLine; - } + if (cmp(from, to) == 0) return; + var array = cm.state.markedSelection; + var cls = cm.state.markedSelectionStyle; + for (var line = from.line;;) { + var start = line == from.line ? from : Pos(line, 0); + var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line; + var end = atEnd ? to : Pos(endLine, 0); + var mark = cm.markText(start, end, {className: cls}); + if (addAt == null) array.push(mark); + else array.splice(addAt++, 0, mark); + if (atEnd) break; + line = endLine; + } } function clear(cm) { - var array = cm.state.markedSelection; - for (var i = 0; i < array.length; ++i) array[i].clear(); - array.length = 0; + var array = cm.state.markedSelection; + for (var i = 0; i < array.length; ++i) array[i].clear(); + array.length = 0; } function reset(cm) { - clear(cm); - var ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) - coverRange(cm, ranges[i].from(), ranges[i].to()); + clear(cm); + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) + coverRange(cm, ranges[i].from(), ranges[i].to()); } function update(cm) { - if (!cm.somethingSelected()) return clear(cm); - if (cm.listSelections().length > 1) return reset(cm); + if (!cm.somethingSelected()) return clear(cm); + if (cm.listSelections().length > 1) return reset(cm); - var from = cm.getCursor("start"), to = cm.getCursor("end"); + var from = cm.getCursor("start"), to = cm.getCursor("end"); - var array = cm.state.markedSelection; - if (!array.length) return coverRange(cm, from, to); + var array = cm.state.markedSelection; + if (!array.length) return coverRange(cm, from, to); - var coverStart = array[0].find(), coverEnd = array[array.length - 1].find(); - if (!coverStart || !coverEnd || to.line - from.line < CHUNK_SIZE || - cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0) - return reset(cm); + var coverStart = array[0].find(), coverEnd = array[array.length - 1].find(); + if (!coverStart || !coverEnd || to.line - from.line < CHUNK_SIZE || + cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0) + return reset(cm); - while (cmp(from, coverStart.from) > 0) { - array.shift().clear(); - coverStart = array[0].find(); - } - if (cmp(from, coverStart.from) < 0) { - if (coverStart.to.line - from.line < CHUNK_SIZE) { - array.shift().clear(); - coverRange(cm, from, coverStart.to, 0); - } else { - coverRange(cm, from, coverStart.from, 0); - } - } + while (cmp(from, coverStart.from) > 0) { + array.shift().clear(); + coverStart = array[0].find(); + } + if (cmp(from, coverStart.from) < 0) { + if (coverStart.to.line - from.line < CHUNK_SIZE) { + array.shift().clear(); + coverRange(cm, from, coverStart.to, 0); + } else { + coverRange(cm, from, coverStart.from, 0); + } + } - while (cmp(to, coverEnd.to) < 0) { - array.pop().clear(); - coverEnd = array[array.length - 1].find(); - } - if (cmp(to, coverEnd.to) > 0) { - if (to.line - coverEnd.from.line < CHUNK_SIZE) { - array.pop().clear(); - coverRange(cm, coverEnd.from, to); - } else { - coverRange(cm, coverEnd.to, to); - } - } + while (cmp(to, coverEnd.to) < 0) { + array.pop().clear(); + coverEnd = array[array.length - 1].find(); + } + if (cmp(to, coverEnd.to) > 0) { + if (to.line - coverEnd.from.line < CHUNK_SIZE) { + array.pop().clear(); + coverRange(cm, coverEnd.from, to); + } else { + coverRange(cm, coverEnd.to, to); + } + } } }); diff --git a/mix/qml/html/cm/solarized.css b/mix/qml/html/cm/solarized.css index 204654d28..d8c31bfb5 100644 --- a/mix/qml/html/cm/solarized.css +++ b/mix/qml/html/cm/solarized.css @@ -183,4 +183,3 @@ view-port } span.CodeMirror-selectedtext { color: #586e75 !important; } -