1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
4 // Because sometimes you need to mark the selected *text*.
6 // Adds an option 'styleSelectedText' which, when enabled, gives
7 // selected text the CSS class given as option value, or
8 // "CodeMirror-selectedtext" when the value is not a string.
11 if (typeof exports
== "object" && typeof module
== "object") // CommonJS
12 mod(require("../../lib/codemirror"));
13 else if (typeof define
== "function" && define
.amd
) // AMD
14 define(["../../lib/codemirror"], mod
);
15 else // Plain browser env
17 })(function(CodeMirror
) {
20 CodeMirror
.defineOption("styleSelectedText", false, function(cm
, val
, old
) {
21 var prev
= old
&& old
!= CodeMirror
.Init
;
23 cm
.state
.markedSelection
= [];
24 cm
.state
.markedSelectionStyle
= typeof val
== "string" ? val
: "CodeMirror-selectedtext";
26 cm
.on("cursorActivity", onCursorActivity
);
27 cm
.on("change", onChange
);
28 } else if (!val
&& prev
) {
29 cm
.off("cursorActivity", onCursorActivity
);
30 cm
.off("change", onChange
);
32 cm
.state
.markedSelection
= cm
.state
.markedSelectionStyle
= null;
36 function onCursorActivity(cm
) {
37 cm
.operation(function() { update(cm
); });
40 function onChange(cm
) {
41 if (cm
.state
.markedSelection
.length
)
42 cm
.operation(function() { clear(cm
); });
46 var Pos
= CodeMirror
.Pos
;
47 var cmp
= CodeMirror
.cmpPos
;
49 function coverRange(cm
, from, to
, addAt
) {
50 if (cmp(from, to
) == 0) return;
51 var array
= cm
.state
.markedSelection
;
52 var cls
= cm
.state
.markedSelectionStyle
;
53 for (var line
= from.line
;;) {
54 var start
= line
== from.line
? from : Pos(line
, 0);
55 var endLine
= line
+ CHUNK_SIZE
, atEnd
= endLine
>= to
.line
;
56 var end
= atEnd
? to
: Pos(endLine
, 0);
57 var mark
= cm
.markText(start
, end
, {className
: cls
});
58 if (addAt
== null) array
.push(mark
);
59 else array
.splice(addAt
++, 0, mark
);
66 var array
= cm
.state
.markedSelection
;
67 for (var i
= 0; i
< array
.length
; ++i
) array
[i
].clear();
73 var ranges
= cm
.listSelections();
74 for (var i
= 0; i
< ranges
.length
; i
++)
75 coverRange(cm
, ranges
[i
].from(), ranges
[i
].to());
79 if (!cm
.somethingSelected()) return clear(cm
);
80 if (cm
.listSelections().length
> 1) return reset(cm
);
82 var from = cm
.getCursor("start"), to
= cm
.getCursor("end");
84 var array
= cm
.state
.markedSelection
;
85 if (!array
.length
) return coverRange(cm
, from, to
);
87 var coverStart
= array
[0].find(), coverEnd
= array
[array
.length
- 1].find();
88 if (!coverStart
|| !coverEnd
|| to
.line
- from.line
< CHUNK_SIZE
||
89 cmp(from, coverEnd
.to
) >= 0 || cmp(to
, coverStart
.from) <= 0)
92 while (cmp(from, coverStart
.from) > 0) {
93 array
.shift().clear();
94 coverStart
= array
[0].find();
96 if (cmp(from, coverStart
.from) < 0) {
97 if (coverStart
.to
.line
- from.line
< CHUNK_SIZE
) {
98 array
.shift().clear();
99 coverRange(cm
, from, coverStart
.to
, 0);
101 coverRange(cm
, from, coverStart
.from, 0);
105 while (cmp(to
, coverEnd
.to
) < 0) {
107 coverEnd
= array
[array
.length
- 1].find();
109 if (cmp(to
, coverEnd
.to
) > 0) {
110 if (to
.line
- coverEnd
.from.line
< CHUNK_SIZE
) {
112 coverRange(cm
, coverEnd
.from, to
);
114 coverRange(cm
, coverEnd
.to
, to
);