Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(591)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/cm/closebrackets.js

Issue 2166603002: DevTools: roll CodeMirror (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Revert unnecessary typeIn change Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 (function(mod) { 4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror")); 6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD 7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod); 8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env 9 else // Plain browser env
10 mod(CodeMirror); 10 mod(CodeMirror);
11 })(function(CodeMirror) { 11 })(function(CodeMirror) {
12 var DEFAULT_BRACKETS = "()[]{}''\"\""; 12 var defaults = {
13 var DEFAULT_EXPLODE_ON_ENTER = "[]{}"; 13 pairs: "()[]{}''\"\"",
14 var SPACE_CHAR_REGEX = /\s/; 14 triples: "",
15 explode: "[]{}"
16 };
15 17
16 var Pos = CodeMirror.Pos; 18 var Pos = CodeMirror.Pos;
17 19
18 CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) { 20 CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
19 if (old != CodeMirror.Init && old) 21 if (old && old != CodeMirror.Init) {
20 cm.removeKeyMap("autoCloseBrackets"); 22 cm.removeKeyMap(keyMap);
21 if (!val) return; 23 cm.state.closeBrackets = null;
22 var pairs = DEFAULT_BRACKETS, explode = DEFAULT_EXPLODE_ON_ENTER;
23 if (typeof val == "string") pairs = val;
24 else if (typeof val == "object") {
25 if (val.pairs != null) pairs = val.pairs;
26 if (val.explode != null) explode = val.explode;
27 } 24 }
28 var map = buildKeymap(pairs); 25 if (val) {
29 if (explode) map.Enter = buildExplodeHandler(explode); 26 cm.state.closeBrackets = val;
30 cm.addKeyMap(map); 27 cm.addKeyMap(keyMap);
28 }
31 }); 29 });
32 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) return null;
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 (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
120 curType = "skipThree";
121 else
122 curType = "skip";
123 } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
124 cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch &&
125 (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur. line, cur.ch - 2)) != ch)) {
126 curType = "addFour";
127 } else if (identical) {
128 if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both";
129 else return CodeMirror.Pass;
130 } else if (opening && (cm.getLine(cur.line).length == cur.ch ||
131 isClosingBracket(next, pairs) ||
132 /\s/.test(next))) {
133 curType = "both";
134 } else {
135 return CodeMirror.Pass;
136 }
137 if (!type) type = curType;
138 else if (type != curType) return CodeMirror.Pass;
139 }
140
141 var left = pos % 2 ? pairs.charAt(pos - 1) : ch;
142 var right = pos % 2 ? ch : pairs.charAt(pos + 1);
143 cm.operation(function() {
144 if (type == "skip") {
145 cm.execCommand("goCharRight");
146 } else if (type == "skipThree") {
147 for (var i = 0; i < 3; i++)
148 cm.execCommand("goCharRight");
149 } else if (type == "surround") {
150 var sels = cm.getSelections();
151 for (var i = 0; i < sels.length; i++)
152 sels[i] = left + sels[i] + right;
153 cm.replaceSelections(sels, "around");
154 sels = cm.listSelections().slice();
155 for (var i = 0; i < sels.length; i++)
156 sels[i] = contractSelection(sels[i]);
157 cm.setSelections(sels);
158 } else if (type == "both") {
159 cm.replaceSelection(left + right, null);
160 cm.triggerElectric(left + right);
161 cm.execCommand("goCharLeft");
162 } else if (type == "addFour") {
163 cm.replaceSelection(left + left + left + left, "before");
164 cm.execCommand("goCharRight");
165 }
166 });
167 }
168
169 function isClosingBracket(ch, pairs) {
170 var pos = pairs.lastIndexOf(ch);
171 return pos > -1 && pos % 2 == 1;
172 }
173
33 function charsAround(cm, pos) { 174 function charsAround(cm, pos) {
34 var str = cm.getRange(Pos(pos.line, pos.ch - 1), 175 var str = cm.getRange(Pos(pos.line, pos.ch - 1),
35 Pos(pos.line, pos.ch + 1)); 176 Pos(pos.line, pos.ch + 1));
36 return str.length == 2 ? str : null; 177 return str.length == 2 ? str : null;
37 } 178 }
38 179
39 function buildKeymap(pairs) { 180 // Project the token type that will exists after the given char is
40 var map = { 181 // typed, and use it to determine whether it would cause the start
41 name : "autoCloseBrackets", 182 // of a string token.
42 Backspace: function(cm) { 183 function enteringString(cm, pos, ch) {
43 if (cm.getOption("disableInput")) return CodeMirror.Pass; 184 var line = cm.getLine(pos.line);
44 var ranges = cm.listSelections(); 185 var token = cm.getTokenAt(pos);
45 for (var i = 0; i < ranges.length; i++) { 186 if (/\bstring2?\b/.test(token.type)) return false;
46 if (!ranges[i].empty()) return CodeMirror.Pass; 187 var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.s lice(pos.ch), 4);
47 var around = charsAround(cm, ranges[i].head); 188 stream.pos = stream.start = token.start;
48 if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; 189 for (;;) {
49 } 190 var type1 = cm.getMode().token(stream, token.state);
50 for (var i = ranges.length - 1; i >= 0; i--) { 191 if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1);
51 var cur = ranges[i].head; 192 stream.start = stream.pos;
52 cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1)); 193 }
53 }
54 }
55 };
56 var closingBrackets = "";
57 for (var i = 0; i < pairs.length; i += 2) (function(left, right) {
58 if (left != right) closingBrackets += right;
59 map["'" + left + "'"] = function(cm) {
60 if (cm.getOption("disableInput")) return CodeMirror.Pass;
61 var ranges = cm.listSelections(), type, next;
62 for (var i = 0; i < ranges.length; i++) {
63 var range = ranges[i], cur = range.head, curType;
64 if (left == "'" && cm.getTokenTypeAt(cur) == "comment")
65 return CodeMirror.Pass;
66 var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
67 if (!range.empty())
68 curType = "surround";
69 else if (left == right && next == right) {
70 if (cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == left + left + lef t)
71 curType = "skipThree";
72 else
73 curType = "skip";
74 } else if (left == right && cur.ch > 1 &&
75 cm.getRange(Pos(cur.line, cur.ch - 2), cur) == left + left &&
76 (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos( cur.line, cur.ch - 2)) != left))
77 curType = "addFour";
78 else if (left == right && CodeMirror.isWordChar(next))
79 return CodeMirror.Pass;
80 else if (cm.getLine(cur.line).length == cur.ch || closingBrackets.inde xOf(next) >= 0 || SPACE_CHAR_REGEX.test(next))
81 curType = "both";
82 else
83 return CodeMirror.Pass;
84 if (!type) type = curType;
85 else if (type != curType) return CodeMirror.Pass;
86 }
87
88 cm.operation(function() {
89 if (type == "skip") {
90 cm.execCommand("goCharRight");
91 } else if (type == "skipThree") {
92 for (var i = 0; i < 3; i++)
93 cm.execCommand("goCharRight");
94 } else if (type == "surround") {
95 var sels = cm.getSelections();
96 for (var i = 0; i < sels.length; i++)
97 sels[i] = left + sels[i] + right;
98 cm.replaceSelections(sels, "around");
99 } else if (type == "both") {
100 cm.replaceSelection(left + right, null);
101 cm.execCommand("goCharLeft");
102 } else if (type == "addFour") {
103 cm.replaceSelection(left + left + left + left, "before");
104 cm.execCommand("goCharRight");
105 }
106 });
107 };
108 if (left != right) map["'" + right + "'"] = function(cm) {
109 var ranges = cm.listSelections();
110 for (var i = 0; i < ranges.length; i++) {
111 var range = ranges[i];
112 if (!range.empty() ||
113 cm.getRange(range.head, Pos(range.head.line, range.head.ch + 1)) ! = right)
114 return CodeMirror.Pass;
115 }
116 cm.execCommand("goCharRight");
117 };
118 })(pairs.charAt(i), pairs.charAt(i + 1));
119 return map;
120 } 194 }
121 195 });
122 function buildExplodeHandler(pairs) {
123 return function(cm) {
124 if (cm.getOption("disableInput")) return CodeMirror.Pass;
125 var ranges = cm.listSelections();
126 for (var i = 0; i < ranges.length; i++) {
127 if (!ranges[i].empty()) return CodeMirror.Pass;
128 var around = charsAround(cm, ranges[i].head);
129 if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
130 }
131 cm.operation(function() {
132 cm.replaceSelection("\n\n", null);
133 cm.execCommand("goCharLeft");
134 ranges = cm.listSelections();
135 for (var i = 0; i < ranges.length; i++) {
136 var line = ranges[i].head.line;
137 cm.indentLine(line, null, true);
138 cm.indentLine(line + 1, null, true);
139 }
140 });
141 };
142 }
143 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698