browser/devtools/sourceeditor/codemirror/fold/foldgutter.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/browser/devtools/sourceeditor/codemirror/fold/foldgutter.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,124 @@
     1.4 +(function() {
     1.5 +  "use strict";
     1.6 +
     1.7 +  CodeMirror.defineOption("foldGutter", false, function(cm, val, old) {
     1.8 +    if (old && old != CodeMirror.Init) {
     1.9 +      cm.clearGutter(cm.state.foldGutter.options.gutter);
    1.10 +      cm.state.foldGutter = null;
    1.11 +      cm.off("gutterClick", onGutterClick);
    1.12 +      cm.off("change", onChange);
    1.13 +      cm.off("viewportChange", onViewportChange);
    1.14 +      cm.off("fold", onFold);
    1.15 +      cm.off("unfold", onFold);
    1.16 +      cm.off("swapDoc", updateInViewport);
    1.17 +    }
    1.18 +    if (val) {
    1.19 +      cm.state.foldGutter = new State(parseOptions(val));
    1.20 +      updateInViewport(cm);
    1.21 +      cm.on("gutterClick", onGutterClick);
    1.22 +      cm.on("change", onChange);
    1.23 +      cm.on("viewportChange", onViewportChange);
    1.24 +      cm.on("fold", onFold);
    1.25 +      cm.on("unfold", onFold);
    1.26 +      cm.on("swapDoc", updateInViewport);
    1.27 +    }
    1.28 +  });
    1.29 +
    1.30 +  var Pos = CodeMirror.Pos;
    1.31 +
    1.32 +  function State(options) {
    1.33 +    this.options = options;
    1.34 +    this.from = this.to = 0;
    1.35 +  }
    1.36 +
    1.37 +  function parseOptions(opts) {
    1.38 +    if (opts === true) opts = {};
    1.39 +    if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter";
    1.40 +    if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open";
    1.41 +    if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded";
    1.42 +    return opts;
    1.43 +  }
    1.44 +
    1.45 +  function isFolded(cm, line) {
    1.46 +    var marks = cm.findMarksAt(Pos(line));
    1.47 +    for (var i = 0; i < marks.length; ++i)
    1.48 +      if (marks[i].__isFold && marks[i].find().from.line == line) return true;
    1.49 +  }
    1.50 +
    1.51 +  function marker(spec) {
    1.52 +    if (typeof spec == "string") {
    1.53 +      var elt = document.createElement("div");
    1.54 +      elt.className = spec;
    1.55 +      return elt;
    1.56 +    } else {
    1.57 +      return spec.cloneNode(true);
    1.58 +    }
    1.59 +  }
    1.60 +
    1.61 +  function updateFoldInfo(cm, from, to) {
    1.62 +    var opts = cm.state.foldGutter.options, cur = from;
    1.63 +    cm.eachLine(from, to, function(line) {
    1.64 +      var mark = null;
    1.65 +      if (isFolded(cm, cur)) {
    1.66 +        mark = marker(opts.indicatorFolded);
    1.67 +      } else {
    1.68 +        var pos = Pos(cur, 0), func = opts.rangeFinder || CodeMirror.fold.auto;
    1.69 +        var range = func && func(cm, pos);
    1.70 +        if (range && range.from.line + 1 < range.to.line)
    1.71 +          mark = marker(opts.indicatorOpen);
    1.72 +      }
    1.73 +      cm.setGutterMarker(line, opts.gutter, mark);
    1.74 +      ++cur;
    1.75 +    });
    1.76 +  }
    1.77 +
    1.78 +  function updateInViewport(cm) {
    1.79 +    var vp = cm.getViewport(), state = cm.state.foldGutter;
    1.80 +    if (!state) return;
    1.81 +    cm.operation(function() {
    1.82 +      updateFoldInfo(cm, vp.from, vp.to);
    1.83 +    });
    1.84 +    state.from = vp.from; state.to = vp.to;
    1.85 +  }
    1.86 +
    1.87 +  function onGutterClick(cm, line, gutter) {
    1.88 +    var opts = cm.state.foldGutter.options;
    1.89 +    if (gutter != opts.gutter) return;
    1.90 +    cm.foldCode(Pos(line, 0), opts.rangeFinder);
    1.91 +  }
    1.92 +
    1.93 +  function onChange(cm) {
    1.94 +    var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
    1.95 +    state.from = state.to = 0;
    1.96 +    clearTimeout(state.changeUpdate);
    1.97 +    state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
    1.98 +  }
    1.99 +
   1.100 +  function onViewportChange(cm) {
   1.101 +    var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
   1.102 +    clearTimeout(state.changeUpdate);
   1.103 +    state.changeUpdate = setTimeout(function() {
   1.104 +      var vp = cm.getViewport();
   1.105 +      if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {
   1.106 +        updateInViewport(cm);
   1.107 +      } else {
   1.108 +        cm.operation(function() {
   1.109 +          if (vp.from < state.from) {
   1.110 +            updateFoldInfo(cm, vp.from, state.from);
   1.111 +            state.from = vp.from;
   1.112 +          }
   1.113 +          if (vp.to > state.to) {
   1.114 +            updateFoldInfo(cm, state.to, vp.to);
   1.115 +            state.to = vp.to;
   1.116 +          }
   1.117 +        });
   1.118 +      }
   1.119 +    }, opts.updateViewportTimeSpan || 400);
   1.120 +  }
   1.121 +
   1.122 +  function onFold(cm, from) {
   1.123 +    var state = cm.state.foldGutter, line = from.line;
   1.124 +    if (line >= state.from && line < state.to)
   1.125 +      updateFoldInfo(cm, line, line + 1);
   1.126 +  }
   1.127 +})();

mercurial