1 // Because sometimes you need to mark the selected *text*.
3 // Adds an option 'styleSelectedText' which, when enabled, gives
4 // selected text the CSS class given as option value, or
5 // "CodeMirror-selectedtext" when the value is not a string.
8 if (typeof exports
== "object" && typeof module
== "object") // CommonJS
9 mod(require("../../lib/codemirror"));
10 else if (typeof define
== "function" && define
.amd
) // AMD
11 define(["../../lib/codemirror"], mod
);
12 else // Plain browser env
14 })(function(CodeMirror
) {
17 CodeMirror
.defineOption("styleSelectedText", false, function(cm
, val
, old
) {
18 var prev
= old
&& old
!= CodeMirror
.Init
;
20 cm
.state
.markedSelection
= [];
21 cm
.state
.markedSelectionStyle
= typeof val
== "string" ? val
: "CodeMirror-selectedtext";
23 cm
.on("cursorActivity", onCursorActivity
);
24 cm
.on("change", onChange
);
25 } else if (!val
&& prev
) {
26 cm
.off("cursorActivity", onCursorActivity
);
27 cm
.off("change", onChange
);
29 cm
.state
.markedSelection
= cm
.state
.markedSelectionStyle
= null;
33 function onCursorActivity(cm
) {
34 cm
.operation(function() { update(cm
); });
37 function onChange(cm
) {
38 if (cm
.state
.markedSelection
.length
)
39 cm
.operation(function() { clear(cm
); });
43 var Pos
= CodeMirror
.Pos
;
44 var cmp
= CodeMirror
.cmpPos
;
46 function coverRange(cm
, from, to
, addAt
) {
47 if (cmp(from, to
) == 0) return;
48 var array
= cm
.state
.markedSelection
;
49 var cls
= cm
.state
.markedSelectionStyle
;
50 for (var line
= from.line
;;) {
51 var start
= line
== from.line
? from : Pos(line
, 0);
52 var endLine
= line
+ CHUNK_SIZE
, atEnd
= endLine
>= to
.line
;
53 var end
= atEnd
? to
: Pos(endLine
, 0);
54 var mark
= cm
.markText(start
, end
, {className
: cls
});
55 if (addAt
== null) array
.push(mark
);
56 else array
.splice(addAt
++, 0, mark
);
63 var array
= cm
.state
.markedSelection
;
64 for (var i
= 0; i
< array
.length
; ++i
) array
[i
].clear();
70 var ranges
= cm
.listSelections();
71 for (var i
= 0; i
< ranges
.length
; i
++)
72 coverRange(cm
, ranges
[i
].from(), ranges
[i
].to());
76 if (!cm
.somethingSelected()) return clear(cm
);
77 if (cm
.listSelections().length
> 1) return reset(cm
);
79 var from = cm
.getCursor("start"), to
= cm
.getCursor("end");
81 var array
= cm
.state
.markedSelection
;
82 if (!array
.length
) return coverRange(cm
, from, to
);
84 var coverStart
= array
[0].find(), coverEnd
= array
[array
.length
- 1].find();
85 if (!coverStart
|| !coverEnd
|| to
.line
- from.line
< CHUNK_SIZE
||
86 cmp(from, coverEnd
.to
) >= 0 || cmp(to
, coverStart
.from) <= 0)
89 while (cmp(from, coverStart
.from) > 0) {
90 array
.shift().clear();
91 coverStart
= array
[0].find();
93 if (cmp(from, coverStart
.from) < 0) {
94 if (coverStart
.to
.line
- from.line
< CHUNK_SIZE
) {
95 array
.shift().clear();
96 coverRange(cm
, from, coverStart
.to
, 0);
98 coverRange(cm
, from, coverStart
.from, 0);
102 while (cmp(to
, coverEnd
.to
) < 0) {
104 coverEnd
= array
[array
.length
- 1].find();
106 if (cmp(to
, coverEnd
.to
) > 0) {
107 if (to
.line
- coverEnd
.from.line
< CHUNK_SIZE
) {
109 coverRange(cm
, coverEnd
.from, to
);
111 coverRange(cm
, coverEnd
.to
, to
);