github.com/jancarloviray/community@v0.41.1-0.20170124221257-33a66c87cf2f/app/public/codemirror/addon/fold/foldgutter.js (about)

     1  // CodeMirror, copyright (c) by Marijn Haverbeke and others
     2  // Distributed under an MIT license: http://codemirror.net/LICENSE
     3  
     4  (function(mod) {
     5    if (typeof exports == "object" && typeof module == "object") // CommonJS
     6      mod(require("../../lib/codemirror"), require("./foldcode"));
     7    else if (typeof define == "function" && define.amd) // AMD
     8      define(["../../lib/codemirror", "./foldcode"], mod);
     9    else // Plain browser env
    10      mod(CodeMirror);
    11  })(function(CodeMirror) {
    12    "use strict";
    13  
    14    CodeMirror.defineOption("foldGutter", false, function(cm, val, old) {
    15      if (old && old != CodeMirror.Init) {
    16        cm.clearGutter(cm.state.foldGutter.options.gutter);
    17        cm.state.foldGutter = null;
    18        cm.off("gutterClick", onGutterClick);
    19        cm.off("change", onChange);
    20        cm.off("viewportChange", onViewportChange);
    21        cm.off("fold", onFold);
    22        cm.off("unfold", onFold);
    23        cm.off("swapDoc", updateInViewport);
    24      }
    25      if (val) {
    26        cm.state.foldGutter = new State(parseOptions(val));
    27        updateInViewport(cm);
    28        cm.on("gutterClick", onGutterClick);
    29        cm.on("change", onChange);
    30        cm.on("viewportChange", onViewportChange);
    31        cm.on("fold", onFold);
    32        cm.on("unfold", onFold);
    33        cm.on("swapDoc", updateInViewport);
    34      }
    35    });
    36  
    37    var Pos = CodeMirror.Pos;
    38  
    39    function State(options) {
    40      this.options = options;
    41      this.from = this.to = 0;
    42    }
    43  
    44    function parseOptions(opts) {
    45      if (opts === true) opts = {};
    46      if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter";
    47      if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open";
    48      if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded";
    49      return opts;
    50    }
    51  
    52    function isFolded(cm, line) {
    53      var marks = cm.findMarksAt(Pos(line));
    54      for (var i = 0; i < marks.length; ++i)
    55        if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i];
    56    }
    57  
    58    function marker(spec) {
    59      if (typeof spec == "string") {
    60        var elt = document.createElement("div");
    61        elt.className = spec + " CodeMirror-guttermarker-subtle";
    62        return elt;
    63      } else {
    64        return spec.cloneNode(true);
    65      }
    66    }
    67  
    68    function updateFoldInfo(cm, from, to) {
    69      var opts = cm.state.foldGutter.options, cur = from;
    70      var minSize = cm.foldOption(opts, "minFoldSize");
    71      var func = cm.foldOption(opts, "rangeFinder");
    72      cm.eachLine(from, to, function(line) {
    73        var mark = null;
    74        if (isFolded(cm, cur)) {
    75          mark = marker(opts.indicatorFolded);
    76        } else {
    77          var pos = Pos(cur, 0);
    78          var range = func && func(cm, pos);
    79          if (range && range.to.line - range.from.line >= minSize)
    80            mark = marker(opts.indicatorOpen);
    81        }
    82        cm.setGutterMarker(line, opts.gutter, mark);
    83        ++cur;
    84      });
    85    }
    86  
    87    function updateInViewport(cm) {
    88      var vp = cm.getViewport(), state = cm.state.foldGutter;
    89      if (!state) return;
    90      cm.operation(function() {
    91        updateFoldInfo(cm, vp.from, vp.to);
    92      });
    93      state.from = vp.from; state.to = vp.to;
    94    }
    95  
    96    function onGutterClick(cm, line, gutter) {
    97      var state = cm.state.foldGutter;
    98      if (!state) return;
    99      var opts = state.options;
   100      if (gutter != opts.gutter) return;
   101      var folded = isFolded(cm, line);
   102      if (folded) folded.clear();
   103      else cm.foldCode(Pos(line, 0), opts.rangeFinder);
   104    }
   105  
   106    function onChange(cm) {
   107      var state = cm.state.foldGutter;
   108      if (!state) return;
   109      var opts = state.options;
   110      state.from = state.to = 0;
   111      clearTimeout(state.changeUpdate);
   112      state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
   113    }
   114  
   115    function onViewportChange(cm) {
   116      var state = cm.state.foldGutter;
   117      if (!state) return;
   118      var opts = state.options;
   119      clearTimeout(state.changeUpdate);
   120      state.changeUpdate = setTimeout(function() {
   121        var vp = cm.getViewport();
   122        if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {
   123          updateInViewport(cm);
   124        } else {
   125          cm.operation(function() {
   126            if (vp.from < state.from) {
   127              updateFoldInfo(cm, vp.from, state.from);
   128              state.from = vp.from;
   129            }
   130            if (vp.to > state.to) {
   131              updateFoldInfo(cm, state.to, vp.to);
   132              state.to = vp.to;
   133            }
   134          });
   135        }
   136      }, opts.updateViewportTimeSpan || 400);
   137    }
   138  
   139    function onFold(cm, from) {
   140      var state = cm.state.foldGutter;
   141      if (!state) return;
   142      var line = from.line;
   143      if (line >= state.from && line < state.to)
   144        updateFoldInfo(cm, line, line + 1);
   145    }
   146  });