blob: ba9756819336ff192f9f1036708ce6ab2defeb89 [file] [log] [blame]
Chinthakayala,Sheshashailavas(sc2914)8f6a6c42018-06-27 16:11:44 +00001define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) {
2"use strict";
3
4var oop = require("../lib/oop");
5var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
6
7var XmlHighlightRules = function(normalize) {
8 var tagRegex = "[_:a-zA-Z\xc0-\uffff][-_:.a-zA-Z0-9\xc0-\uffff]*";
9
10 this.$rules = {
11 start : [
12 {token : "string.cdata.xml", regex : "<\\!\\[CDATA\\[", next : "cdata"},
13 {
14 token : ["punctuation.instruction.xml", "keyword.instruction.xml"],
15 regex : "(<\\?)(" + tagRegex + ")", next : "processing_instruction"
16 },
17 {token : "comment.start.xml", regex : "<\\!--", next : "comment"},
18 {
19 token : ["xml-pe.doctype.xml", "xml-pe.doctype.xml"],
20 regex : "(<\\!)(DOCTYPE)(?=[\\s])", next : "doctype", caseInsensitive: true
21 },
22 {include : "tag"},
23 {token : "text.end-tag-open.xml", regex: "</"},
24 {token : "text.tag-open.xml", regex: "<"},
25 {include : "reference"},
26 {defaultToken : "text.xml"}
27 ],
28
29 processing_instruction : [{
30 token : "entity.other.attribute-name.decl-attribute-name.xml",
31 regex : tagRegex
32 }, {
33 token : "keyword.operator.decl-attribute-equals.xml",
34 regex : "="
35 }, {
36 include: "whitespace"
37 }, {
38 include: "string"
39 }, {
40 token : "punctuation.xml-decl.xml",
41 regex : "\\?>",
42 next : "start"
43 }],
44
45 doctype : [
46 {include : "whitespace"},
47 {include : "string"},
48 {token : "xml-pe.doctype.xml", regex : ">", next : "start"},
49 {token : "xml-pe.xml", regex : "[-_a-zA-Z0-9:]+"},
50 {token : "punctuation.int-subset", regex : "\\[", push : "int_subset"}
51 ],
52
53 int_subset : [{
54 token : "text.xml",
55 regex : "\\s+"
56 }, {
57 token: "punctuation.int-subset.xml",
58 regex: "]",
59 next: "pop"
60 }, {
61 token : ["punctuation.markup-decl.xml", "keyword.markup-decl.xml"],
62 regex : "(<\\!)(" + tagRegex + ")",
63 push : [{
64 token : "text",
65 regex : "\\s+"
66 },
67 {
68 token : "punctuation.markup-decl.xml",
69 regex : ">",
70 next : "pop"
71 },
72 {include : "string"}]
73 }],
74
75 cdata : [
76 {token : "string.cdata.xml", regex : "\\]\\]>", next : "start"},
77 {token : "text.xml", regex : "\\s+"},
78 {token : "text.xml", regex : "(?:[^\\]]|\\](?!\\]>))+"}
79 ],
80
81 comment : [
82 {token : "comment.end.xml", regex : "-->", next : "start"},
83 {defaultToken : "comment.xml"}
84 ],
85
86 reference : [{
87 token : "constant.language.escape.reference.xml",
88 regex : "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"
89 }],
90
91 attr_reference : [{
92 token : "constant.language.escape.reference.attribute-value.xml",
93 regex : "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"
94 }],
95
96 tag : [{
97 token : ["meta.tag.punctuation.tag-open.xml", "meta.tag.punctuation.end-tag-open.xml", "meta.tag.tag-name.xml"],
98 regex : "(?:(<)|(</))((?:" + tagRegex + ":)?" + tagRegex + ")",
99 next: [
100 {include : "attributes"},
101 {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next : "start"}
102 ]
103 }],
104
105 tag_whitespace : [
106 {token : "text.tag-whitespace.xml", regex : "\\s+"}
107 ],
108 whitespace : [
109 {token : "text.whitespace.xml", regex : "\\s+"}
110 ],
111 string: [{
112 token : "string.xml",
113 regex : "'",
114 push : [
115 {token : "string.xml", regex: "'", next: "pop"},
116 {defaultToken : "string.xml"}
117 ]
118 }, {
119 token : "string.xml",
120 regex : '"',
121 push : [
122 {token : "string.xml", regex: '"', next: "pop"},
123 {defaultToken : "string.xml"}
124 ]
125 }],
126
127 attributes: [{
128 token : "entity.other.attribute-name.xml",
129 regex : tagRegex
130 }, {
131 token : "keyword.operator.attribute-equals.xml",
132 regex : "="
133 }, {
134 include: "tag_whitespace"
135 }, {
136 include: "attribute_value"
137 }],
138
139 attribute_value: [{
140 token : "string.attribute-value.xml",
141 regex : "'",
142 push : [
143 {token : "string.attribute-value.xml", regex: "'", next: "pop"},
144 {include : "attr_reference"},
145 {defaultToken : "string.attribute-value.xml"}
146 ]
147 }, {
148 token : "string.attribute-value.xml",
149 regex : '"',
150 push : [
151 {token : "string.attribute-value.xml", regex: '"', next: "pop"},
152 {include : "attr_reference"},
153 {defaultToken : "string.attribute-value.xml"}
154 ]
155 }]
156 };
157
158 if (this.constructor === XmlHighlightRules)
159 this.normalizeRules();
160};
161
162
163(function() {
164
165 this.embedTagRules = function(HighlightRules, prefix, tag){
166 this.$rules.tag.unshift({
167 token : ["meta.tag.punctuation.tag-open.xml", "meta.tag." + tag + ".tag-name.xml"],
168 regex : "(<)(" + tag + "(?=\\s|>|$))",
169 next: [
170 {include : "attributes"},
171 {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next : prefix + "start"}
172 ]
173 });
174
175 this.$rules[tag + "-end"] = [
176 {include : "attributes"},
177 {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next: "start",
178 onMatch : function(value, currentState, stack) {
179 stack.splice(0);
180 return this.token;
181 }}
182 ];
183
184 this.embedRules(HighlightRules, prefix, [{
185 token: ["meta.tag.punctuation.end-tag-open.xml", "meta.tag." + tag + ".tag-name.xml"],
186 regex : "(</)(" + tag + "(?=\\s|>|$))",
187 next: tag + "-end"
188 }, {
189 token: "string.cdata.xml",
190 regex : "<\\!\\[CDATA\\["
191 }, {
192 token: "string.cdata.xml",
193 regex : "\\]\\]>"
194 }]);
195 };
196
197}).call(TextHighlightRules.prototype);
198
199oop.inherits(XmlHighlightRules, TextHighlightRules);
200
201exports.XmlHighlightRules = XmlHighlightRules;
202});
203
204define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(require, exports, module) {
205"use strict";
206
207var oop = require("../../lib/oop");
208var Behaviour = require("../behaviour").Behaviour;
209var TokenIterator = require("../../token_iterator").TokenIterator;
210var lang = require("../../lib/lang");
211
212function is(token, type) {
213 return token.type.lastIndexOf(type + ".xml") > -1;
214}
215
216var XmlBehaviour = function () {
217
218 this.add("string_dquotes", "insertion", function (state, action, editor, session, text) {
219 if (text == '"' || text == "'") {
220 var quote = text;
221 var selected = session.doc.getTextRange(editor.getSelectionRange());
222 if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) {
223 return {
224 text: quote + selected + quote,
225 selection: false
226 };
227 }
228
229 var cursor = editor.getCursorPosition();
230 var line = session.doc.getLine(cursor.row);
231 var rightChar = line.substring(cursor.column, cursor.column + 1);
232 var iterator = new TokenIterator(session, cursor.row, cursor.column);
233 var token = iterator.getCurrentToken();
234
235 if (rightChar == quote && (is(token, "attribute-value") || is(token, "string"))) {
236 return {
237 text: "",
238 selection: [1, 1]
239 };
240 }
241
242 if (!token)
243 token = iterator.stepBackward();
244
245 if (!token)
246 return;
247
248 while (is(token, "tag-whitespace") || is(token, "whitespace")) {
249 token = iterator.stepBackward();
250 }
251 var rightSpace = !rightChar || rightChar.match(/\s/);
252 if (is(token, "attribute-equals") && (rightSpace || rightChar == '>') || (is(token, "decl-attribute-equals") && (rightSpace || rightChar == '?'))) {
253 return {
254 text: quote + quote,
255 selection: [1, 1]
256 };
257 }
258 }
259 });
260
261 this.add("string_dquotes", "deletion", function(state, action, editor, session, range) {
262 var selected = session.doc.getTextRange(range);
263 if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
264 var line = session.doc.getLine(range.start.row);
265 var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
266 if (rightChar == selected) {
267 range.end.column++;
268 return range;
269 }
270 }
271 });
272
273 this.add("autoclosing", "insertion", function (state, action, editor, session, text) {
274 if (text == '>') {
275 var position = editor.getSelectionRange().start;
276 var iterator = new TokenIterator(session, position.row, position.column);
277 var token = iterator.getCurrentToken() || iterator.stepBackward();
278 if (!token || !(is(token, "tag-name") || is(token, "tag-whitespace") || is(token, "attribute-name") || is(token, "attribute-equals") || is(token, "attribute-value")))
279 return;
280 if (is(token, "reference.attribute-value"))
281 return;
282 if (is(token, "attribute-value")) {
283 var firstChar = token.value.charAt(0);
284 if (firstChar == '"' || firstChar == "'") {
285 var lastChar = token.value.charAt(token.value.length - 1);
286 var tokenEnd = iterator.getCurrentTokenColumn() + token.value.length;
287 if (tokenEnd > position.column || tokenEnd == position.column && firstChar != lastChar)
288 return;
289 }
290 }
291 while (!is(token, "tag-name")) {
292 token = iterator.stepBackward();
293 if (token.value == "<") {
294 token = iterator.stepForward();
295 break;
296 }
297 }
298
299 var tokenRow = iterator.getCurrentTokenRow();
300 var tokenColumn = iterator.getCurrentTokenColumn();
301 if (is(iterator.stepBackward(), "end-tag-open"))
302 return;
303
304 var element = token.value;
305 if (tokenRow == position.row)
306 element = element.substring(0, position.column - tokenColumn);
307
308 if (this.voidElements.hasOwnProperty(element.toLowerCase()))
309 return;
310
311 return {
312 text: ">" + "</" + element + ">",
313 selection: [1, 1]
314 };
315 }
316 });
317
318 this.add("autoindent", "insertion", function (state, action, editor, session, text) {
319 if (text == "\n") {
320 var cursor = editor.getCursorPosition();
321 var line = session.getLine(cursor.row);
322 var iterator = new TokenIterator(session, cursor.row, cursor.column);
323 var token = iterator.getCurrentToken();
324
325 if (token && token.type.indexOf("tag-close") !== -1) {
326 if (token.value == "/>")
327 return;
328 while (token && token.type.indexOf("tag-name") === -1) {
329 token = iterator.stepBackward();
330 }
331
332 if (!token) {
333 return;
334 }
335
336 var tag = token.value;
337 var row = iterator.getCurrentTokenRow();
338 token = iterator.stepBackward();
339 if (!token || token.type.indexOf("end-tag") !== -1) {
340 return;
341 }
342
343 if (this.voidElements && !this.voidElements[tag]) {
344 var nextToken = session.getTokenAt(cursor.row, cursor.column+1);
345 var line = session.getLine(row);
346 var nextIndent = this.$getIndent(line);
347 var indent = nextIndent + session.getTabString();
348
349 if (nextToken && nextToken.value === "</") {
350 return {
351 text: "\n" + indent + "\n" + nextIndent,
352 selection: [1, indent.length, 1, indent.length]
353 };
354 } else {
355 return {
356 text: "\n" + indent
357 };
358 }
359 }
360 }
361 }
362 });
363
364};
365
366oop.inherits(XmlBehaviour, Behaviour);
367
368exports.XmlBehaviour = XmlBehaviour;
369});
370
371define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"], function(require, exports, module) {
372"use strict";
373
374var oop = require("../../lib/oop");
375var lang = require("../../lib/lang");
376var Range = require("../../range").Range;
377var BaseFoldMode = require("./fold_mode").FoldMode;
378var TokenIterator = require("../../token_iterator").TokenIterator;
379
380var FoldMode = exports.FoldMode = function(voidElements, optionalEndTags) {
381 BaseFoldMode.call(this);
382 this.voidElements = voidElements || {};
383 this.optionalEndTags = oop.mixin({}, this.voidElements);
384 if (optionalEndTags)
385 oop.mixin(this.optionalEndTags, optionalEndTags);
386
387};
388oop.inherits(FoldMode, BaseFoldMode);
389
390var Tag = function() {
391 this.tagName = "";
392 this.closing = false;
393 this.selfClosing = false;
394 this.start = {row: 0, column: 0};
395 this.end = {row: 0, column: 0};
396};
397
398function is(token, type) {
399 return token.type.lastIndexOf(type + ".xml") > -1;
400}
401
402(function() {
403
404 this.getFoldWidget = function(session, foldStyle, row) {
405 var tag = this._getFirstTagInLine(session, row);
406
407 if (!tag)
408 return this.getCommentFoldWidget(session, row);
409
410 if (tag.closing || (!tag.tagName && tag.selfClosing))
411 return foldStyle == "markbeginend" ? "end" : "";
412
413 if (!tag.tagName || tag.selfClosing || this.voidElements.hasOwnProperty(tag.tagName.toLowerCase()))
414 return "";
415
416 if (this._findEndTagInLine(session, row, tag.tagName, tag.end.column))
417 return "";
418
419 return "start";
420 };
421
422 this.getCommentFoldWidget = function(session, row) {
423 if (/comment/.test(session.getState(row)) && /<!-/.test(session.getLine(row)))
424 return "start";
425 return "";
426 };
427 this._getFirstTagInLine = function(session, row) {
428 var tokens = session.getTokens(row);
429 var tag = new Tag();
430
431 for (var i = 0; i < tokens.length; i++) {
432 var token = tokens[i];
433 if (is(token, "tag-open")) {
434 tag.end.column = tag.start.column + token.value.length;
435 tag.closing = is(token, "end-tag-open");
436 token = tokens[++i];
437 if (!token)
438 return null;
439 tag.tagName = token.value;
440 tag.end.column += token.value.length;
441 for (i++; i < tokens.length; i++) {
442 token = tokens[i];
443 tag.end.column += token.value.length;
444 if (is(token, "tag-close")) {
445 tag.selfClosing = token.value == '/>';
446 break;
447 }
448 }
449 return tag;
450 } else if (is(token, "tag-close")) {
451 tag.selfClosing = token.value == '/>';
452 return tag;
453 }
454 tag.start.column += token.value.length;
455 }
456
457 return null;
458 };
459
460 this._findEndTagInLine = function(session, row, tagName, startColumn) {
461 var tokens = session.getTokens(row);
462 var column = 0;
463 for (var i = 0; i < tokens.length; i++) {
464 var token = tokens[i];
465 column += token.value.length;
466 if (column < startColumn)
467 continue;
468 if (is(token, "end-tag-open")) {
469 token = tokens[i + 1];
470 if (token && token.value == tagName)
471 return true;
472 }
473 }
474 return false;
475 };
476 this._readTagForward = function(iterator) {
477 var token = iterator.getCurrentToken();
478 if (!token)
479 return null;
480
481 var tag = new Tag();
482 do {
483 if (is(token, "tag-open")) {
484 tag.closing = is(token, "end-tag-open");
485 tag.start.row = iterator.getCurrentTokenRow();
486 tag.start.column = iterator.getCurrentTokenColumn();
487 } else if (is(token, "tag-name")) {
488 tag.tagName = token.value;
489 } else if (is(token, "tag-close")) {
490 tag.selfClosing = token.value == "/>";
491 tag.end.row = iterator.getCurrentTokenRow();
492 tag.end.column = iterator.getCurrentTokenColumn() + token.value.length;
493 iterator.stepForward();
494 return tag;
495 }
496 } while(token = iterator.stepForward());
497
498 return null;
499 };
500
501 this._readTagBackward = function(iterator) {
502 var token = iterator.getCurrentToken();
503 if (!token)
504 return null;
505
506 var tag = new Tag();
507 do {
508 if (is(token, "tag-open")) {
509 tag.closing = is(token, "end-tag-open");
510 tag.start.row = iterator.getCurrentTokenRow();
511 tag.start.column = iterator.getCurrentTokenColumn();
512 iterator.stepBackward();
513 return tag;
514 } else if (is(token, "tag-name")) {
515 tag.tagName = token.value;
516 } else if (is(token, "tag-close")) {
517 tag.selfClosing = token.value == "/>";
518 tag.end.row = iterator.getCurrentTokenRow();
519 tag.end.column = iterator.getCurrentTokenColumn() + token.value.length;
520 }
521 } while(token = iterator.stepBackward());
522
523 return null;
524 };
525
526 this._pop = function(stack, tag) {
527 while (stack.length) {
528
529 var top = stack[stack.length-1];
530 if (!tag || top.tagName == tag.tagName) {
531 return stack.pop();
532 }
533 else if (this.optionalEndTags.hasOwnProperty(top.tagName)) {
534 stack.pop();
535 continue;
536 } else {
537 return null;
538 }
539 }
540 };
541
542 this.getFoldWidgetRange = function(session, foldStyle, row) {
543 var firstTag = this._getFirstTagInLine(session, row);
544
545 if (!firstTag) {
546 return this.getCommentFoldWidget(session, row)
547 && session.getCommentFoldRange(row, session.getLine(row).length);
548 }
549
550 var isBackward = firstTag.closing || firstTag.selfClosing;
551 var stack = [];
552 var tag;
553
554 if (!isBackward) {
555 var iterator = new TokenIterator(session, row, firstTag.start.column);
556 var start = {
557 row: row,
558 column: firstTag.start.column + firstTag.tagName.length + 2
559 };
560 if (firstTag.start.row == firstTag.end.row)
561 start.column = firstTag.end.column;
562 while (tag = this._readTagForward(iterator)) {
563 if (tag.selfClosing) {
564 if (!stack.length) {
565 tag.start.column += tag.tagName.length + 2;
566 tag.end.column -= 2;
567 return Range.fromPoints(tag.start, tag.end);
568 } else
569 continue;
570 }
571
572 if (tag.closing) {
573 this._pop(stack, tag);
574 if (stack.length == 0)
575 return Range.fromPoints(start, tag.start);
576 }
577 else {
578 stack.push(tag);
579 }
580 }
581 }
582 else {
583 var iterator = new TokenIterator(session, row, firstTag.end.column);
584 var end = {
585 row: row,
586 column: firstTag.start.column
587 };
588
589 while (tag = this._readTagBackward(iterator)) {
590 if (tag.selfClosing) {
591 if (!stack.length) {
592 tag.start.column += tag.tagName.length + 2;
593 tag.end.column -= 2;
594 return Range.fromPoints(tag.start, tag.end);
595 } else
596 continue;
597 }
598
599 if (!tag.closing) {
600 this._pop(stack, tag);
601 if (stack.length == 0) {
602 tag.start.column += tag.tagName.length + 2;
603 if (tag.start.row == tag.end.row && tag.start.column < tag.end.column)
604 tag.start.column = tag.end.column;
605 return Range.fromPoints(tag.start, end);
606 }
607 }
608 else {
609 stack.push(tag);
610 }
611 }
612 }
613
614 };
615
616}).call(FoldMode.prototype);
617
618});
619
620define("ace/mode/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/xml_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/xml","ace/worker/worker_client"], function(require, exports, module) {
621"use strict";
622
623var oop = require("../lib/oop");
624var lang = require("../lib/lang");
625var TextMode = require("./text").Mode;
626var XmlHighlightRules = require("./xml_highlight_rules").XmlHighlightRules;
627var XmlBehaviour = require("./behaviour/xml").XmlBehaviour;
628var XmlFoldMode = require("./folding/xml").FoldMode;
629var WorkerClient = require("../worker/worker_client").WorkerClient;
630
631var Mode = function() {
632 this.HighlightRules = XmlHighlightRules;
633 this.$behaviour = new XmlBehaviour();
634 this.foldingRules = new XmlFoldMode();
635};
636
637oop.inherits(Mode, TextMode);
638
639(function() {
640
641 this.voidElements = lang.arrayToMap([]);
642
643 this.blockComment = {start: "<!--", end: "-->"};
644
645 this.createWorker = function(session) {
646 var worker = new WorkerClient(["ace"], "ace/mode/xml_worker", "Worker");
647 worker.attachToDocument(session.getDocument());
648
649 worker.on("error", function(e) {
650 session.setAnnotations(e.data);
651 });
652
653 worker.on("terminate", function() {
654 session.clearAnnotations();
655 });
656
657 return worker;
658 };
659
660 this.$id = "ace/mode/xml";
661}).call(Mode.prototype);
662
663exports.Mode = Mode;
664});