931c3726cc2f512813fe4d5e469fb4f52da00b8a
[myslice.git] / third-party / codemirror-3.15 / addon / fold / foldcode.js
1 (function() {
2   "use strict";
3
4   function doFold(cm, pos, options) {
5     var finder = options && (options.call ? options : options.rangeFinder);
6     if (!finder) finder = cm.getHelper(pos, "fold");
7     if (!finder) return;
8     if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0);
9     var minSize = options && options.minFoldSize || 0;
10
11     function getRange(allowFolded) {
12       var range = finder(cm, pos);
13       if (!range || range.to.line - range.from.line < minSize) return null;
14       var marks = cm.findMarksAt(range.from);
15       for (var i = 0; i < marks.length; ++i) {
16         if (marks[i].__isFold) {
17           if (!allowFolded) return null;
18           range.cleared = true;
19           marks[i].clear();
20         }
21       }
22       return range;
23     }
24
25     var range = getRange(true);
26     if (options && options.scanUp) while (!range && pos.line > cm.firstLine()) {
27       pos = CodeMirror.Pos(pos.line - 1, 0);
28       range = getRange(false);
29     }
30     if (!range || range.cleared) return;
31
32     var myWidget = makeWidget(options);
33     CodeMirror.on(myWidget, "mousedown", function() { myRange.clear(); });
34     var myRange = cm.markText(range.from, range.to, {
35       replacedWith: myWidget,
36       clearOnEnter: true,
37       __isFold: true
38     });
39     myRange.on("clear", function(from, to) {
40       CodeMirror.signal(cm, "unfold", cm, from, to);
41     });
42     CodeMirror.signal(cm, "fold", cm, range.from, range.to);
43   }
44
45   function makeWidget(options) {
46     var widget = (options && options.widget) || "\u2194";
47     if (typeof widget == "string") {
48       var text = document.createTextNode(widget);
49       widget = document.createElement("span");
50       widget.appendChild(text);
51       widget.className = "CodeMirror-foldmarker";
52     }
53     return widget;
54   }
55
56   // Clumsy backwards-compatible interface
57   CodeMirror.newFoldFunction = function(rangeFinder, widget) {
58     return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); };
59   };
60
61   // New-style interface
62   CodeMirror.defineExtension("foldCode", function(pos, options) { doFold(this, pos, options); });
63
64   CodeMirror.registerHelper("fold", "combine", function() {
65     var funcs = Array.prototype.slice.call(arguments, 0);
66     return function(cm, start) {
67       for (var i = 0; i < funcs.length; ++i) {
68         var found = funcs[i](cm, start);
69         if (found) return found;
70       }
71     };
72   });
73 })();