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.
10 CodeMirror
.defineOption("styleSelectedText", false, function(cm
, val
, old
) {
11 var prev
= old
&& old
!= CodeMirror
.Init
;
13 cm
.state
.markedSelection
= [];
14 cm
.state
.markedSelectionStyle
= typeof val
== "string" ? val
: "CodeMirror-selectedtext";
16 cm
.on("cursorActivity", onCursorActivity
);
17 cm
.on("change", onChange
);
18 } else if (!val
&& prev
) {
19 cm
.off("cursorActivity", onCursorActivity
);
20 cm
.off("change", onChange
);
22 cm
.state
.markedSelection
= cm
.state
.markedSelectionStyle
= null;
26 function onCursorActivity(cm
) {
27 cm
.operation(function() { update(cm
); });
30 function onChange(cm
) {
31 if (cm
.state
.markedSelection
.length
)
32 cm
.operation(function() { clear(cm
); });
36 var Pos
= CodeMirror
.Pos
;
38 function cmp(pos1
, pos2
) {
39 return pos1
.line
- pos2
.line
|| pos1
.ch
- pos2
.ch
;
42 function coverRange(cm
, from, to
, addAt
) {
43 if (cmp(from, to
) == 0) return;
44 var array
= cm
.state
.markedSelection
;
45 var cls
= cm
.state
.markedSelectionStyle
;
46 for (var line
= from.line
;;) {
47 var start
= line
== from.line
? from : Pos(line
, 0);
48 var endLine
= line
+ CHUNK_SIZE
, atEnd
= endLine
>= to
.line
;
49 var end
= atEnd
? to
: Pos(endLine
, 0);
50 var mark
= cm
.markText(start
, end
, {className
: cls
});
51 if (addAt
== null) array
.push(mark
);
52 else array
.splice(addAt
++, 0, mark
);
59 var array
= cm
.state
.markedSelection
;
60 for (var i
= 0; i
< array
.length
; ++i
) array
[i
].clear();
66 var from = cm
.getCursor("start"), to
= cm
.getCursor("end");
67 coverRange(cm
, from, to
);
71 var from = cm
.getCursor("start"), to
= cm
.getCursor("end");
72 if (cmp(from, to
) == 0) return clear(cm
);
74 var array
= cm
.state
.markedSelection
;
75 if (!array
.length
) return coverRange(cm
, from, to
);
77 var coverStart
= array
[0].find(), coverEnd
= array
[array
.length
- 1].find();
78 if (!coverStart
|| !coverEnd
|| to
.line
- from.line
< CHUNK_SIZE
||
79 cmp(from, coverEnd
.to
) >= 0 || cmp(to
, coverStart
.from) <= 0)
82 while (cmp(from, coverStart
.from) > 0) {
83 array
.shift().clear();
84 coverStart
= array
[0].find();
86 if (cmp(from, coverStart
.from) < 0) {
87 if (coverStart
.to
.line
- from.line
< CHUNK_SIZE
) {
88 array
.shift().clear();
89 coverRange(cm
, from, coverStart
.to
, 0);
91 coverRange(cm
, from, coverStart
.from, 0);
95 while (cmp(to
, coverEnd
.to
) < 0) {
97 coverEnd
= array
[array
.length
- 1].find();
99 if (cmp(to
, coverEnd
.to
) > 0) {
100 if (to
.line
- coverEnd
.from.line
< CHUNK_SIZE
) {
102 coverRange(cm
, coverEnd
.from, to
);
104 coverRange(cm
, coverEnd
.to
, to
);