Dotclear

source: admin/js/codemirror/addon/edit/closebrackets.js @ 3532:3c9cac9dbe38

Revision 3532:3c9cac9dbe38, 7.1 KB checked in by franck <carnet.franck.paul@…>, 9 years ago (diff)

Update CodeMirror? lib from 5.15.3 to 5.24.3

Line 
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"));
7  else if (typeof define == "function" && define.amd) // AMD
8    define(["../../lib/codemirror"], mod);
9  else // Plain browser env
10    mod(CodeMirror);
11})(function(CodeMirror) {
12  var defaults = {
13    pairs: "()[]{}''\"\"",
14    triples: "",
15    explode: "[]{}"
16  };
17
18  var Pos = CodeMirror.Pos;
19
20  CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
21    if (old && old != CodeMirror.Init) {
22      cm.removeKeyMap(keyMap);
23      cm.state.closeBrackets = null;
24    }
25    if (val) {
26      cm.state.closeBrackets = val;
27      cm.addKeyMap(keyMap);
28    }
29  });
30
31  function getOption(conf, name) {
32    if (name == "pairs" && typeof conf == "string") return conf;
33    if (typeof conf == "object" && conf[name] != null) return conf[name];
34    return defaults[name];
35  }
36
37  var bind = defaults.pairs + "`";
38  var keyMap = {Backspace: handleBackspace, Enter: handleEnter};
39  for (var i = 0; i < bind.length; i++)
40    keyMap["'" + bind.charAt(i) + "'"] = handler(bind.charAt(i));
41
42  function handler(ch) {
43    return function(cm) { return handleChar(cm, ch); };
44  }
45
46  function getConfig(cm) {
47    var deflt = cm.state.closeBrackets;
48    if (!deflt || deflt.override) return deflt;
49    var mode = cm.getModeAt(cm.getCursor());
50    return mode.closeBrackets || deflt;
51  }
52
53  function handleBackspace(cm) {
54    var conf = getConfig(cm);
55    if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
56
57    var pairs = getOption(conf, "pairs");
58    var ranges = cm.listSelections();
59    for (var i = 0; i < ranges.length; i++) {
60      if (!ranges[i].empty()) return CodeMirror.Pass;
61      var around = charsAround(cm, ranges[i].head);
62      if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
63    }
64    for (var i = ranges.length - 1; i >= 0; i--) {
65      var cur = ranges[i].head;
66      cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete");
67    }
68  }
69
70  function handleEnter(cm) {
71    var conf = getConfig(cm);
72    var explode = conf && getOption(conf, "explode");
73    if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;
74
75    var ranges = cm.listSelections();
76    for (var i = 0; i < ranges.length; i++) {
77      if (!ranges[i].empty()) return CodeMirror.Pass;
78      var around = charsAround(cm, ranges[i].head);
79      if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
80    }
81    cm.operation(function() {
82      cm.replaceSelection("\n\n", null);
83      cm.execCommand("goCharLeft");
84      ranges = cm.listSelections();
85      for (var i = 0; i < ranges.length; i++) {
86        var line = ranges[i].head.line;
87        cm.indentLine(line, null, true);
88        cm.indentLine(line + 1, null, true);
89      }
90    });
91  }
92
93  function contractSelection(sel) {
94    var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0;
95    return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)),
96            head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))};
97  }
98
99  function handleChar(cm, ch) {
100    var conf = getConfig(cm);
101    if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
102
103    var pairs = getOption(conf, "pairs");
104    var pos = pairs.indexOf(ch);
105    if (pos == -1) return CodeMirror.Pass;
106    var triples = getOption(conf, "triples");
107
108    var identical = pairs.charAt(pos + 1) == ch;
109    var ranges = cm.listSelections();
110    var opening = pos % 2 == 0;
111
112    var type;
113    for (var i = 0; i < ranges.length; i++) {
114      var range = ranges[i], cur = range.head, curType;
115      var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
116      if (opening && !range.empty()) {
117        curType = "surround";
118      } else if ((identical || !opening) && next == ch) {
119        if (identical && stringStartsAfter(cm, cur))
120          curType = "both";
121        else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
122          curType = "skipThree";
123        else
124          curType = "skip";
125      } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
126                 cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch &&
127                 (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) {
128        curType = "addFour";
129      } else if (identical) {
130        if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both";
131        else return CodeMirror.Pass;
132      } else if (opening && (cm.getLine(cur.line).length == cur.ch ||
133                             isClosingBracket(next, pairs) ||
134                             /\s/.test(next))) {
135        curType = "both";
136      } else {
137        return CodeMirror.Pass;
138      }
139      if (!type) type = curType;
140      else if (type != curType) return CodeMirror.Pass;
141    }
142
143    var left = pos % 2 ? pairs.charAt(pos - 1) : ch;
144    var right = pos % 2 ? ch : pairs.charAt(pos + 1);
145    cm.operation(function() {
146      if (type == "skip") {
147        cm.execCommand("goCharRight");
148      } else if (type == "skipThree") {
149        for (var i = 0; i < 3; i++)
150          cm.execCommand("goCharRight");
151      } else if (type == "surround") {
152        var sels = cm.getSelections();
153        for (var i = 0; i < sels.length; i++)
154          sels[i] = left + sels[i] + right;
155        cm.replaceSelections(sels, "around");
156        sels = cm.listSelections().slice();
157        for (var i = 0; i < sels.length; i++)
158          sels[i] = contractSelection(sels[i]);
159        cm.setSelections(sels);
160      } else if (type == "both") {
161        cm.replaceSelection(left + right, null);
162        cm.triggerElectric(left + right);
163        cm.execCommand("goCharLeft");
164      } else if (type == "addFour") {
165        cm.replaceSelection(left + left + left + left, "before");
166        cm.execCommand("goCharRight");
167      }
168    });
169  }
170
171  function isClosingBracket(ch, pairs) {
172    var pos = pairs.lastIndexOf(ch);
173    return pos > -1 && pos % 2 == 1;
174  }
175
176  function charsAround(cm, pos) {
177    var str = cm.getRange(Pos(pos.line, pos.ch - 1),
178                          Pos(pos.line, pos.ch + 1));
179    return str.length == 2 ? str : null;
180  }
181
182  // Project the token type that will exists after the given char is
183  // typed, and use it to determine whether it would cause the start
184  // of a string token.
185  function enteringString(cm, pos, ch) {
186    var line = cm.getLine(pos.line);
187    var token = cm.getTokenAt(pos);
188    if (/\bstring2?\b/.test(token.type) || stringStartsAfter(cm, pos)) return false;
189    var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4);
190    stream.pos = stream.start = token.start;
191    for (;;) {
192      var type1 = cm.getMode().token(stream, token.state);
193      if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1);
194      stream.start = stream.pos;
195    }
196  }
197
198  function stringStartsAfter(cm, pos) {
199    var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1))
200    return /\bstring/.test(token.type) && token.start == pos.ch
201  }
202});
Note: See TracBrowser for help on using the repository browser.

Sites map