153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// Because sometimes you need to mark the selected *text*. 253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// 353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// Adds an option 'styleSelectedText' which, when enabled, gives 493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// selected text the CSS class given as option value, or 593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// "CodeMirror-selectedtext" when the value is not a string. 653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 7aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch(function(mod) { 8aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch if (typeof exports == "object" && typeof module == "object") // CommonJS 9aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch mod(require("../../lib/codemirror")); 10aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch else if (typeof define == "function" && define.amd) // AMD 11aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch define(["../../lib/codemirror"], mod); 12aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch else // Plain browser env 13aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch mod(CodeMirror); 14aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch})(function(CodeMirror) { 1553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) "use strict"; 1653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 1753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) { 1853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) var prev = old && old != CodeMirror.Init; 1953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (val && !prev) { 2093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) cm.state.markedSelection = []; 2193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext"; 2293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) reset(cm); 2393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) cm.on("cursorActivity", onCursorActivity); 2493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) cm.on("change", onChange); 2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } else if (!val && prev) { 2693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) cm.off("cursorActivity", onCursorActivity); 2793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) cm.off("change", onChange); 2893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) clear(cm); 2993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) cm.state.markedSelection = cm.state.markedSelectionStyle = null; 3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) }); 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) function onCursorActivity(cm) { 3493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) cm.operation(function() { update(cm); }); 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) function onChange(cm) { 3893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (cm.state.markedSelection.length) 3993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) cm.operation(function() { clear(cm); }); 4093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 4193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 4293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) var CHUNK_SIZE = 8; 4393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) var Pos = CodeMirror.Pos; 44aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch var cmp = CodeMirror.cmpPos; 4593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 4693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) function coverRange(cm, from, to, addAt) { 4793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (cmp(from, to) == 0) return; 4893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) var array = cm.state.markedSelection; 4993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) var cls = cm.state.markedSelectionStyle; 5093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) for (var line = from.line;;) { 5193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) var start = line == from.line ? from : Pos(line, 0); 5293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line; 5393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) var end = atEnd ? to : Pos(endLine, 0); 5493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) var mark = cm.markText(start, end, {className: cls}); 5593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (addAt == null) array.push(mark); 5693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) else array.splice(addAt++, 0, mark); 5793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (atEnd) break; 5893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) line = endLine; 5993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 6093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 6153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 6293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) function clear(cm) { 6393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) var array = cm.state.markedSelection; 6493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) for (var i = 0; i < array.length; ++i) array[i].clear(); 6593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) array.length = 0; 6693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 6793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 6893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) function reset(cm) { 6993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) clear(cm); 70aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch var ranges = cm.listSelections(); 71aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch for (var i = 0; i < ranges.length; i++) 72aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch coverRange(cm, ranges[i].from(), ranges[i].to()); 7393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 7493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 7593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) function update(cm) { 76aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch if (!cm.somethingSelected()) return clear(cm); 77aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch if (cm.listSelections().length > 1) return reset(cm); 78aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch 7993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) var from = cm.getCursor("start"), to = cm.getCursor("end"); 8093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 8193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) var array = cm.state.markedSelection; 8293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (!array.length) return coverRange(cm, from, to); 8393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 8493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) var coverStart = array[0].find(), coverEnd = array[array.length - 1].find(); 8593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (!coverStart || !coverEnd || to.line - from.line < CHUNK_SIZE || 8693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0) 8793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return reset(cm); 8893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 8993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) while (cmp(from, coverStart.from) > 0) { 9093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) array.shift().clear(); 9193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) coverStart = array[0].find(); 9293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 9393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (cmp(from, coverStart.from) < 0) { 9493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (coverStart.to.line - from.line < CHUNK_SIZE) { 9593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) array.shift().clear(); 9693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) coverRange(cm, from, coverStart.to, 0); 9793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } else { 9893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) coverRange(cm, from, coverStart.from, 0); 9993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 10093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 10193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 10293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) while (cmp(to, coverEnd.to) < 0) { 10393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) array.pop().clear(); 10493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) coverEnd = array[array.length - 1].find(); 10593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 10693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (cmp(to, coverEnd.to) > 0) { 10793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (to.line - coverEnd.from.line < CHUNK_SIZE) { 10893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) array.pop().clear(); 10993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) coverRange(cm, coverEnd.from, to); 11093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } else { 11193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) coverRange(cm, coverEnd.to, to); 11293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 11393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 11453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 115aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch}); 116