PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / 2.8.23.4
Pods – Custom Content Types and Fields v2.8.23.4
2.7.31.4 2.8.23.5 2.9.19.5 3.0.10.5 3.1.4.3 3.2.8.4 3.3.9.2 2.8.23.4 2.9.19.4 3.0.10.4 3.1.4.2 3.2.8.3 3.3.9.1 trunk 1.14.8 2.7.31.3 2.8.23.3 2.9.19.3 3.0.10.3 3.1.4.1 3.2.0 3.2.1 3.2.1.1 3.2.2 3.2.4 3.2.5 3.2.6 3.2.7 3.2.7.1 3.2.8 3.2.8.1 3.2.8.2 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9
pods / ui / js / codemirror / mode / xml / xml.js
pods / ui / js / codemirror / mode / xml Last commit date
xml.js 2 weeks ago
xml.js
385 lines
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 "use strict";
13
14 CodeMirror.defineMode("xml", function(config, parserConfig) {
15 var indentUnit = config.indentUnit;
16 var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
17 var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag;
18 if (multilineTagIndentPastTag == null) multilineTagIndentPastTag = true;
19
20 var Kludges = parserConfig.htmlMode ? {
21 autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
22 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
23 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
24 'track': true, 'wbr': true, 'menuitem': true},
25 implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
26 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
27 'th': true, 'tr': true},
28 contextGrabbers: {
29 'dd': {'dd': true, 'dt': true},
30 'dt': {'dd': true, 'dt': true},
31 'li': {'li': true},
32 'option': {'option': true, 'optgroup': true},
33 'optgroup': {'optgroup': true},
34 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
35 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
36 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
37 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
38 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
39 'rp': {'rp': true, 'rt': true},
40 'rt': {'rp': true, 'rt': true},
41 'tbody': {'tbody': true, 'tfoot': true},
42 'td': {'td': true, 'th': true},
43 'tfoot': {'tbody': true},
44 'th': {'td': true, 'th': true},
45 'thead': {'tbody': true, 'tfoot': true},
46 'tr': {'tr': true}
47 },
48 doNotIndent: {"pre": true},
49 allowUnquoted: true,
50 allowMissing: true,
51 caseFold: true
52 } : {
53 autoSelfClosers: {},
54 implicitlyClosed: {},
55 contextGrabbers: {},
56 doNotIndent: {},
57 allowUnquoted: false,
58 allowMissing: false,
59 caseFold: false
60 };
61 var alignCDATA = parserConfig.alignCDATA;
62
63 // Return variables for tokenizers
64 var type, setStyle;
65
66 function inText(stream, state) {
67 function chain(parser) {
68 state.tokenize = parser;
69 return parser(stream, state);
70 }
71
72 var ch = stream.next();
73 if (ch == "<") {
74 if (stream.eat("!")) {
75 if (stream.eat("[")) {
76 if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
77 else return null;
78 } else if (stream.match("--")) {
79 return chain(inBlock("comment", "-->"));
80 } else if (stream.match("DOCTYPE", true, true)) {
81 stream.eatWhile(/[\w\._\-]/);
82 return chain(doctype(1));
83 } else {
84 return null;
85 }
86 } else if (stream.eat("?")) {
87 stream.eatWhile(/[\w\._\-]/);
88 state.tokenize = inBlock("meta", "?>");
89 return "meta";
90 } else {
91 type = stream.eat("/") ? "closeTag" : "openTag";
92 state.tokenize = inTag;
93 return "tag bracket";
94 }
95 } else if (ch == "&") {
96 var ok;
97 if (stream.eat("#")) {
98 if (stream.eat("x")) {
99 ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
100 } else {
101 ok = stream.eatWhile(/[\d]/) && stream.eat(";");
102 }
103 } else {
104 ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
105 }
106 return ok ? "atom" : "error";
107 } else {
108 stream.eatWhile(/[^&<]/);
109 return null;
110 }
111 }
112
113 function inTag(stream, state) {
114 var ch = stream.next();
115 if (ch == ">" || (ch == "/" && stream.eat(">"))) {
116 state.tokenize = inText;
117 type = ch == ">" ? "endTag" : "selfcloseTag";
118 return "tag bracket";
119 } else if (ch == "=") {
120 type = "equals";
121 return null;
122 } else if (ch == "<") {
123 state.tokenize = inText;
124 state.state = baseState;
125 state.tagName = state.tagStart = null;
126 var next = state.tokenize(stream, state);
127 return next ? next + " tag error" : "tag error";
128 } else if (/[\'\"]/.test(ch)) {
129 state.tokenize = inAttribute(ch);
130 state.stringStartCol = stream.column();
131 return state.tokenize(stream, state);
132 } else {
133 stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
134 return "word";
135 }
136 }
137
138 function inAttribute(quote) {
139 var closure = function(stream, state) {
140 while (!stream.eol()) {
141 if (stream.next() == quote) {
142 state.tokenize = inTag;
143 break;
144 }
145 }
146 return "string";
147 };
148 closure.isInAttribute = true;
149 return closure;
150 }
151
152 function inBlock(style, terminator) {
153 return function(stream, state) {
154 while (!stream.eol()) {
155 if (stream.match(terminator)) {
156 state.tokenize = inText;
157 break;
158 }
159 stream.next();
160 }
161 return style;
162 };
163 }
164 function doctype(depth) {
165 return function(stream, state) {
166 var ch;
167 while ((ch = stream.next()) != null) {
168 if (ch == "<") {
169 state.tokenize = doctype(depth + 1);
170 return state.tokenize(stream, state);
171 } else if (ch == ">") {
172 if (depth == 1) {
173 state.tokenize = inText;
174 break;
175 } else {
176 state.tokenize = doctype(depth - 1);
177 return state.tokenize(stream, state);
178 }
179 }
180 }
181 return "meta";
182 };
183 }
184
185 function Context(state, tagName, startOfLine) {
186 this.prev = state.context;
187 this.tagName = tagName;
188 this.indent = state.indented;
189 this.startOfLine = startOfLine;
190 if (Kludges.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
191 this.noIndent = true;
192 }
193 function popContext(state) {
194 if (state.context) state.context = state.context.prev;
195 }
196 function maybePopContext(state, nextTagName) {
197 var parentTagName;
198 while (true) {
199 if (!state.context) {
200 return;
201 }
202 parentTagName = state.context.tagName;
203 if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
204 !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
205 return;
206 }
207 popContext(state);
208 }
209 }
210
211 function baseState(type, stream, state) {
212 if (type == "openTag") {
213 state.tagStart = stream.column();
214 return tagNameState;
215 } else if (type == "closeTag") {
216 return closeTagNameState;
217 } else {
218 return baseState;
219 }
220 }
221 function tagNameState(type, stream, state) {
222 if (type == "word") {
223 state.tagName = stream.current();
224 setStyle = "tag";
225 return attrState;
226 } else {
227 setStyle = "error";
228 return tagNameState;
229 }
230 }
231 function closeTagNameState(type, stream, state) {
232 if (type == "word") {
233 var tagName = stream.current();
234 if (state.context && state.context.tagName != tagName &&
235 Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName))
236 popContext(state);
237 if (state.context && state.context.tagName == tagName) {
238 setStyle = "tag";
239 return closeState;
240 } else {
241 setStyle = "tag error";
242 return closeStateErr;
243 }
244 } else {
245 setStyle = "error";
246 return closeStateErr;
247 }
248 }
249
250 function closeState(type, _stream, state) {
251 if (type != "endTag") {
252 setStyle = "error";
253 return closeState;
254 }
255 popContext(state);
256 return baseState;
257 }
258 function closeStateErr(type, stream, state) {
259 setStyle = "error";
260 return closeState(type, stream, state);
261 }
262
263 function attrState(type, _stream, state) {
264 if (type == "word") {
265 setStyle = "attribute";
266 return attrEqState;
267 } else if (type == "endTag" || type == "selfcloseTag") {
268 var tagName = state.tagName, tagStart = state.tagStart;
269 state.tagName = state.tagStart = null;
270 if (type == "selfcloseTag" ||
271 Kludges.autoSelfClosers.hasOwnProperty(tagName)) {
272 maybePopContext(state, tagName);
273 } else {
274 maybePopContext(state, tagName);
275 state.context = new Context(state, tagName, tagStart == state.indented);
276 }
277 return baseState;
278 }
279 setStyle = "error";
280 return attrState;
281 }
282 function attrEqState(type, stream, state) {
283 if (type == "equals") return attrValueState;
284 if (!Kludges.allowMissing) setStyle = "error";
285 return attrState(type, stream, state);
286 }
287 function attrValueState(type, stream, state) {
288 if (type == "string") return attrContinuedState;
289 if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return attrState;}
290 setStyle = "error";
291 return attrState(type, stream, state);
292 }
293 function attrContinuedState(type, stream, state) {
294 if (type == "string") return attrContinuedState;
295 return attrState(type, stream, state);
296 }
297
298 return {
299 startState: function() {
300 return {tokenize: inText,
301 state: baseState,
302 indented: 0,
303 tagName: null, tagStart: null,
304 context: null};
305 },
306
307 token: function(stream, state) {
308 if (!state.tagName && stream.sol())
309 state.indented = stream.indentation();
310
311 if (stream.eatSpace()) return null;
312 type = null;
313 var style = state.tokenize(stream, state);
314 if ((style || type) && style != "comment") {
315 setStyle = null;
316 state.state = state.state(type || style, stream, state);
317 if (setStyle)
318 style = setStyle == "error" ? style + " error" : setStyle;
319 }
320 return style;
321 },
322
323 indent: function(state, textAfter, fullLine) {
324 var context = state.context;
325 // Indent multi-line strings (e.g. css).
326 if (state.tokenize.isInAttribute) {
327 if (state.tagStart == state.indented)
328 return state.stringStartCol + 1;
329 else
330 return state.indented + indentUnit;
331 }
332 if (context && context.noIndent) return CodeMirror.Pass;
333 if (state.tokenize != inTag && state.tokenize != inText)
334 return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
335 // Indent the starts of attribute names.
336 if (state.tagName) {
337 if (multilineTagIndentPastTag)
338 return state.tagStart + state.tagName.length + 2;
339 else
340 return state.tagStart + indentUnit * multilineTagIndentFactor;
341 }
342 if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
343 var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
344 if (tagAfter && tagAfter[1]) { // Closing tag spotted
345 while (context) {
346 if (context.tagName == tagAfter[2]) {
347 context = context.prev;
348 break;
349 } else if (Kludges.implicitlyClosed.hasOwnProperty(context.tagName)) {
350 context = context.prev;
351 } else {
352 break;
353 }
354 }
355 } else if (tagAfter) { // Opening tag spotted
356 while (context) {
357 var grabbers = Kludges.contextGrabbers[context.tagName];
358 if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
359 context = context.prev;
360 else
361 break;
362 }
363 }
364 while (context && !context.startOfLine)
365 context = context.prev;
366 if (context) return context.indent + indentUnit;
367 else return 0;
368 },
369
370 electricInput: /<\/[\s\w:]+>$/,
371 blockCommentStart: "<!--",
372 blockCommentEnd: "-->",
373
374 configuration: parserConfig.htmlMode ? "html" : "xml",
375 helperType: parserConfig.htmlMode ? "html" : "xml"
376 };
377 });
378
379 CodeMirror.defineMIME("text/xml", "xml");
380 CodeMirror.defineMIME("application/xml", "xml");
381 if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
382 CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
383
384 });
385