Commit | Line | Data |
---|---|---|
837afb80 TD |
1 | (function(mod) { |
2 | if (typeof exports == "object" && typeof module == "object") // CommonJS | |
3 | mod(require("../../lib/codemirror")); | |
4 | else if (typeof define == "function" && define.amd) // AMD | |
5 | define(["../../lib/codemirror"], mod); | |
6 | else // Plain browser env | |
7 | mod(CodeMirror); | |
8 | })(function(CodeMirror) { | |
9 | "use strict"; | |
77b7b761 | 10 | |
837afb80 TD |
11 | function doFold(cm, pos, options, force) { |
12 | var finder = options && (options.call ? options : options.rangeFinder); | |
13 | if (!finder) finder = CodeMirror.fold.auto; | |
77b7b761 | 14 | if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0); |
837afb80 TD |
15 | var minSize = options && options.minFoldSize || 0; |
16 | ||
17 | function getRange(allowFolded) { | |
18 | var range = finder(cm, pos); | |
19 | if (!range || range.to.line - range.from.line < minSize) return null; | |
20 | var marks = cm.findMarksAt(range.from); | |
21 | for (var i = 0; i < marks.length; ++i) { | |
22 | if (marks[i].__isFold && force !== "fold") { | |
23 | if (!allowFolded) return null; | |
24 | range.cleared = true; | |
25 | marks[i].clear(); | |
26 | } | |
77b7b761 | 27 | } |
837afb80 TD |
28 | return range; |
29 | } | |
30 | ||
31 | var range = getRange(true); | |
32 | if (options && options.scanUp) while (!range && pos.line > cm.firstLine()) { | |
33 | pos = CodeMirror.Pos(pos.line - 1, 0); | |
34 | range = getRange(false); | |
77b7b761 | 35 | } |
837afb80 | 36 | if (!range || range.cleared || force === "unfold") return; |
77b7b761 | 37 | |
837afb80 TD |
38 | var myWidget = makeWidget(options); |
39 | CodeMirror.on(myWidget, "mousedown", function() { myRange.clear(); }); | |
77b7b761 TD |
40 | var myRange = cm.markText(range.from, range.to, { |
41 | replacedWith: myWidget, | |
42 | clearOnEnter: true, | |
43 | __isFold: true | |
44 | }); | |
837afb80 TD |
45 | myRange.on("clear", function(from, to) { |
46 | CodeMirror.signal(cm, "unfold", cm, from, to); | |
47 | }); | |
48 | CodeMirror.signal(cm, "fold", cm, range.from, range.to); | |
49 | } | |
50 | ||
51 | function makeWidget(options) { | |
52 | var widget = (options && options.widget) || "\u2194"; | |
53 | if (typeof widget == "string") { | |
54 | var text = document.createTextNode(widget); | |
55 | widget = document.createElement("span"); | |
56 | widget.appendChild(text); | |
57 | widget.className = "CodeMirror-foldmarker"; | |
58 | } | |
59 | return widget; | |
60 | } | |
61 | ||
62 | // Clumsy backwards-compatible interface | |
63 | CodeMirror.newFoldFunction = function(rangeFinder, widget) { | |
64 | return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); }; | |
65 | }; | |
66 | ||
67 | // New-style interface | |
68 | CodeMirror.defineExtension("foldCode", function(pos, options, force) { | |
69 | doFold(this, pos, options, force); | |
70 | }); | |
71 | ||
72 | CodeMirror.defineExtension("isFolded", function(pos) { | |
73 | var marks = this.findMarksAt(pos); | |
74 | for (var i = 0; i < marks.length; ++i) | |
75 | if (marks[i].__isFold) return true; | |
76 | }); | |
77 | ||
78 | CodeMirror.commands.toggleFold = function(cm) { | |
79 | cm.foldCode(cm.getCursor()); | |
80 | }; | |
81 | CodeMirror.commands.fold = function(cm) { | |
82 | cm.foldCode(cm.getCursor(), null, "fold"); | |
83 | }; | |
84 | CodeMirror.commands.unfold = function(cm) { | |
85 | cm.foldCode(cm.getCursor(), null, "unfold"); | |
86 | }; | |
87 | CodeMirror.commands.foldAll = function(cm) { | |
88 | cm.operation(function() { | |
89 | for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) | |
90 | cm.foldCode(CodeMirror.Pos(i, 0), null, "fold"); | |
91 | }); | |
77b7b761 | 92 | }; |
837afb80 TD |
93 | CodeMirror.commands.unfoldAll = function(cm) { |
94 | cm.operation(function() { | |
95 | for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) | |
96 | cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold"); | |
97 | }); | |
98 | }; | |
99 | ||
100 | CodeMirror.registerHelper("fold", "combine", function() { | |
101 | var funcs = Array.prototype.slice.call(arguments, 0); | |
102 | return function(cm, start) { | |
103 | for (var i = 0; i < funcs.length; ++i) { | |
104 | var found = funcs[i](cm, start); | |
105 | if (found) return found; | |
106 | } | |
107 | }; | |
108 | }); | |
109 | ||
110 | CodeMirror.registerHelper("fold", "auto", function(cm, start) { | |
111 | var helpers = cm.getHelpers(start, "fold"); | |
112 | for (var i = 0; i < helpers.length; i++) { | |
113 | var cur = helpers[i](cm, start); | |
114 | if (cur) return cur; | |
115 | } | |
116 | }); | |
117 | }); |