Dotclear

source: admin/js/codemirror/addon/edit/closebrackets.js @ 3617:bb465743f804

Revision 3617:bb465743f804, 6.7 KB checked in by franck <carnet.franck.paul@…>, 8 years ago (diff)

Update CodeMirror? from 5.25.1 to 5.32.1

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

Sites map