Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 (function() {
2 "use strict";
4 CodeMirror.defineOption("foldGutter", false, function(cm, val, old) {
5 if (old && old != CodeMirror.Init) {
6 cm.clearGutter(cm.state.foldGutter.options.gutter);
7 cm.state.foldGutter = null;
8 cm.off("gutterClick", onGutterClick);
9 cm.off("change", onChange);
10 cm.off("viewportChange", onViewportChange);
11 cm.off("fold", onFold);
12 cm.off("unfold", onFold);
13 cm.off("swapDoc", updateInViewport);
14 }
15 if (val) {
16 cm.state.foldGutter = new State(parseOptions(val));
17 updateInViewport(cm);
18 cm.on("gutterClick", onGutterClick);
19 cm.on("change", onChange);
20 cm.on("viewportChange", onViewportChange);
21 cm.on("fold", onFold);
22 cm.on("unfold", onFold);
23 cm.on("swapDoc", updateInViewport);
24 }
25 });
27 var Pos = CodeMirror.Pos;
29 function State(options) {
30 this.options = options;
31 this.from = this.to = 0;
32 }
34 function parseOptions(opts) {
35 if (opts === true) opts = {};
36 if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter";
37 if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open";
38 if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded";
39 return opts;
40 }
42 function isFolded(cm, line) {
43 var marks = cm.findMarksAt(Pos(line));
44 for (var i = 0; i < marks.length; ++i)
45 if (marks[i].__isFold && marks[i].find().from.line == line) return true;
46 }
48 function marker(spec) {
49 if (typeof spec == "string") {
50 var elt = document.createElement("div");
51 elt.className = spec;
52 return elt;
53 } else {
54 return spec.cloneNode(true);
55 }
56 }
58 function updateFoldInfo(cm, from, to) {
59 var opts = cm.state.foldGutter.options, cur = from;
60 cm.eachLine(from, to, function(line) {
61 var mark = null;
62 if (isFolded(cm, cur)) {
63 mark = marker(opts.indicatorFolded);
64 } else {
65 var pos = Pos(cur, 0), func = opts.rangeFinder || CodeMirror.fold.auto;
66 var range = func && func(cm, pos);
67 if (range && range.from.line + 1 < range.to.line)
68 mark = marker(opts.indicatorOpen);
69 }
70 cm.setGutterMarker(line, opts.gutter, mark);
71 ++cur;
72 });
73 }
75 function updateInViewport(cm) {
76 var vp = cm.getViewport(), state = cm.state.foldGutter;
77 if (!state) return;
78 cm.operation(function() {
79 updateFoldInfo(cm, vp.from, vp.to);
80 });
81 state.from = vp.from; state.to = vp.to;
82 }
84 function onGutterClick(cm, line, gutter) {
85 var opts = cm.state.foldGutter.options;
86 if (gutter != opts.gutter) return;
87 cm.foldCode(Pos(line, 0), opts.rangeFinder);
88 }
90 function onChange(cm) {
91 var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
92 state.from = state.to = 0;
93 clearTimeout(state.changeUpdate);
94 state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
95 }
97 function onViewportChange(cm) {
98 var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
99 clearTimeout(state.changeUpdate);
100 state.changeUpdate = setTimeout(function() {
101 var vp = cm.getViewport();
102 if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {
103 updateInViewport(cm);
104 } else {
105 cm.operation(function() {
106 if (vp.from < state.from) {
107 updateFoldInfo(cm, vp.from, state.from);
108 state.from = vp.from;
109 }
110 if (vp.to > state.to) {
111 updateFoldInfo(cm, state.to, vp.to);
112 state.to = vp.to;
113 }
114 });
115 }
116 }, opts.updateViewportTimeSpan || 400);
117 }
119 function onFold(cm, from) {
120 var state = cm.state.foldGutter, line = from.line;
121 if (line >= state.from && line < state.to)
122 updateFoldInfo(cm, line, line + 1);
123 }
124 })();