4 function doFold(cm, pos, options) {
5 var finder = options && (options.call ? options : options.rangeFinder);
6 if (!finder) finder = cm.getHelper(pos, "fold");
8 if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0);
9 var minSize = options && options.minFoldSize || 0;
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;
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);
30 if (!range || range.cleared) return;
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,
39 myRange.on("clear", function(from, to) {
40 CodeMirror.signal(cm, "unfold", cm, from, to);
42 CodeMirror.signal(cm, "fold", cm, range.from, range.to);
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";
56 // Clumsy backwards-compatible interface
57 CodeMirror.newFoldFunction = function(rangeFinder, widget) {
58 return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); };
61 // New-style interface
62 CodeMirror.defineExtension("foldCode", function(pos, options) { doFold(this, pos, options); });
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;