Nav apraksta
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

mode-xml.js 22KB

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