]> git.r.bdr.sh - rbdr/dotfiles/blob - atom/packages/pretty-json/node_modules/jsonminify/report/assets/scripts/vendor/codemirror/util/closetag.js
Remove mc config
[rbdr/dotfiles] / atom / packages / pretty-json / node_modules / jsonminify / report / assets / scripts / vendor / codemirror / util / closetag.js
1 /**
2 * Tag-closer extension for CodeMirror.
3 *
4 * This extension adds an "autoCloseTags" option that can be set to
5 * either true to get the default behavior, or an object to further
6 * configure its behavior.
7 *
8 * These are supported options:
9 *
10 * `whenClosing` (default true)
11 * Whether to autoclose when the '/' of a closing tag is typed.
12 * `whenOpening` (default true)
13 * Whether to autoclose the tag when the final '>' of an opening
14 * tag is typed.
15 * `dontCloseTags` (default is empty tags for HTML, none for XML)
16 * An array of tag names that should not be autoclosed.
17 * `indentTags` (default is block tags for HTML, none for XML)
18 * An array of tag names that should, when opened, cause a
19 * blank line to be added inside the tag, and the blank line and
20 * closing line to be indented.
21 *
22 * See demos/closetag.html for a usage example.
23 */
24
25 (function() {
26 CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) {
27 if (val && (old == CodeMirror.Init || !old)) {
28 var map = {name: "autoCloseTags"};
29 if (typeof val != "object" || val.whenClosing)
30 map["'/'"] = function(cm) { autoCloseTag(cm, '/'); };
31 if (typeof val != "object" || val.whenOpening)
32 map["'>'"] = function(cm) { autoCloseTag(cm, '>'); };
33 cm.addKeyMap(map);
34 } else if (!val && (old != CodeMirror.Init && old)) {
35 cm.removeKeyMap("autoCloseTags");
36 }
37 });
38
39 var htmlDontClose = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param",
40 "source", "track", "wbr"];
41 var htmlIndent = ["applet", "blockquote", "body", "button", "div", "dl", "fieldset", "form", "frameset", "h1", "h2", "h3", "h4",
42 "h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"];
43
44 function autoCloseTag(cm, ch) {
45 var pos = cm.getCursor(), tok = cm.getTokenAt(pos);
46 var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
47 if (inner.mode.name != "xml") throw CodeMirror.Pass;
48
49 var opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html";
50 var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose);
51 var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent);
52
53 if (ch == ">" && state.tagName) {
54 var tagName = state.tagName;
55 if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
56 var lowerTagName = tagName.toLowerCase();
57 // Don't process the '>' at the end of an end-tag or self-closing tag
58 if (tok.type == "tag" && state.type == "closeTag" ||
59 /\/\s*$/.test(tok.string) ||
60 dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1)
61 throw CodeMirror.Pass;
62
63 var doIndent = indentTags && indexOf(indentTags, lowerTagName) > -1;
64 cm.replaceSelection(">" + (doIndent ? "\n\n" : "") + "</" + tagName + ">",
65 doIndent ? {line: pos.line + 1, ch: 0} : {line: pos.line, ch: pos.ch + 1});
66 if (doIndent) {
67 cm.indentLine(pos.line + 1);
68 cm.indentLine(pos.line + 2);
69 }
70 return;
71 } else if (ch == "/" && tok.type == "tag" && tok.string == "<") {
72 var tagName = state.context && state.context.tagName;
73 if (tagName) cm.replaceSelection("/" + tagName + ">", "end");
74 return;
75 }
76 throw CodeMirror.Pass;
77 }
78
79 function indexOf(collection, elt) {
80 if (collection.indexOf) return collection.indexOf(elt);
81 for (var i = 0, e = collection.length; i < e; ++i)
82 if (collection[i] == elt) return i;
83 return -1;
84 }
85 })();