]>
git.r.bdr.sh - rbdr/dotfiles/blob - atom/packages/pretty-json/node_modules/jsonminify/report/assets/scripts/vendor/codemirror/util/closetag.js
7320c171847b51eac5d3373ec827a07877abd92e
2 * Tag-closer extension for CodeMirror.
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.
8 * These are supported options:
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
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.
22 * See demos/closetag.html for a usage example.
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
, '>'); };
34 } else if (!val
&& (old
!= CodeMirror
.Init
&& old
)) {
35 cm
.removeKeyMap("autoCloseTags");
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"];
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
;
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
);
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
;
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});
67 cm
.indentLine(pos
.line
+ 1);
68 cm
.indentLine(pos
.line
+ 2);
71 } else if (ch
== "/" && tok
.type
== "tag" && tok
.string
== "<") {
72 var tagName
= state
.context
&& state
.context
.tagName
;
73 if (tagName
) cm
.replaceSelection("/" + tagName
+ ">", "end");
76 throw CodeMirror
.Pass
;
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
;