html5 boiler plate
[scannr.git] / js / flotr2 / examples / lib / codemirror / lib / util / foldcode.js
blob:a/js/flotr2/examples/lib/codemirror/lib/util/foldcode.js -> blob:b/js/flotr2/examples/lib/codemirror/lib/util/foldcode.js
--- a/js/flotr2/examples/lib/codemirror/lib/util/foldcode.js
+++ b/js/flotr2/examples/lib/codemirror/lib/util/foldcode.js
@@ -1,1 +1,67 @@
+CodeMirror.braceRangeFinder = function(cm, line) {
+  var lineText = cm.getLine(line);
+  var startChar = lineText.lastIndexOf("{");
+  if (startChar < 0 || lineText.lastIndexOf("}") > startChar) return;
+  var tokenType = cm.getTokenAt({line: line, ch: startChar}).className;
+  var count = 1, lastLine = cm.lineCount(), end;
+  outer: for (var i = line + 1; i < lastLine; ++i) {
+    var text = cm.getLine(i), pos = 0;
+    for (;;) {
+      var nextOpen = text.indexOf("{", pos), nextClose = text.indexOf("}", pos);
+      if (nextOpen < 0) nextOpen = text.length;
+      if (nextClose < 0) nextClose = text.length;
+      pos = Math.min(nextOpen, nextClose);
+      if (pos == text.length) break;
+      if (cm.getTokenAt({line: i, ch: pos + 1}).className == tokenType) {
+        if (pos == nextOpen) ++count;
+        else if (!--count) { end = i; break outer; }
+      }
+      ++pos;
+    }
+  }
+  if (end == null || end == line + 1) return;
+  return end;
+};
 
+
+CodeMirror.newFoldFunction = function(rangeFinder, markText) {
+  var folded = [];
+  if (markText == null) markText = '<div style="position: absolute; left: 2px; color:#600">&#x25bc;</div>%N%';
+
+  function isFolded(cm, n) {
+    for (var i = 0; i < folded.length; ++i) {
+      var start = cm.lineInfo(folded[i].start);
+      if (!start) folded.splice(i--, 1);
+      else if (start.line == n) return {pos: i, region: folded[i]};
+    }
+  }
+
+  function expand(cm, region) {
+    cm.clearMarker(region.start);
+    for (var i = 0; i < region.hidden.length; ++i)
+      cm.showLine(region.hidden[i]);
+  }
+
+  return function(cm, line) {
+    cm.operation(function() {
+      var known = isFolded(cm, line);
+      if (known) {
+        folded.splice(known.pos, 1);
+        expand(cm, known.region);
+      } else {
+        var end = rangeFinder(cm, line);
+        if (end == null) return;
+        var hidden = [];
+        for (var i = line + 1; i < end; ++i) {
+          var handle = cm.hideLine(i);
+          if (handle) hidden.push(handle);
+        }
+        var first = cm.setMarker(line, markText);
+        var region = {start: first, hidden: hidden};
+        cm.onDeleteLine(first, function() { expand(cm, region); });
+        folded.push(region);
+      }
+    });
+  };
+};
+