Subversion-Projekte lars-tiefland.ci

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
776 lars 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
});