mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
b8b5190bc6
Currently, some of the things on the playground must be changed directly on the master branch while other things require checking out the gh-pages branch and making the modifications there. Even when changes need to be made on the master branch, all changes that are not direcly in owl itself need to be copied by hand to the gh-pages branch. This commit moves all files that exist on the gh-pages branch to the master branch in the docs folder, this change will require configuring the github page to use the docs folder instead of a separate branch, but will make maintenance of the github page and playground easier going forward.
821 lines
24 KiB
JavaScript
821 lines
24 KiB
JavaScript
ace.define(
|
|
"ace/mode/xml_highlight_rules",
|
|
[
|
|
"require",
|
|
"exports",
|
|
"module",
|
|
"ace/lib/oop",
|
|
"ace/mode/text_highlight_rules"
|
|
],
|
|
function(require, exports, module) {
|
|
"use strict";
|
|
|
|
var oop = require("../lib/oop");
|
|
var TextHighlightRules = require("./text_highlight_rules")
|
|
.TextHighlightRules;
|
|
|
|
var XmlHighlightRules = function(normalize) {
|
|
var tagRegex = "[_:a-zA-Z\xc0-\uffff][-_:.a-zA-Z0-9\xc0-\uffff]*";
|
|
|
|
this.$rules = {
|
|
start: [
|
|
{
|
|
token: "string.cdata.xml",
|
|
regex: "<\\!\\[CDATA\\[",
|
|
next: "cdata"
|
|
},
|
|
{
|
|
token: ["punctuation.instruction.xml", "keyword.instruction.xml"],
|
|
regex: "(<\\?)(" + tagRegex + ")",
|
|
next: "processing_instruction"
|
|
},
|
|
{ token: "comment.start.xml", regex: "<\\!--", next: "comment" },
|
|
{
|
|
token: ["xml-pe.doctype.xml", "xml-pe.doctype.xml"],
|
|
regex: "(<\\!)(DOCTYPE)(?=[\\s])",
|
|
next: "doctype",
|
|
caseInsensitive: true
|
|
},
|
|
{ include: "tag" },
|
|
{ token: "text.end-tag-open.xml", regex: "</" },
|
|
{ token: "text.tag-open.xml", regex: "<" },
|
|
{ include: "reference" },
|
|
{ defaultToken: "text.xml" }
|
|
],
|
|
|
|
processing_instruction: [
|
|
{
|
|
token: "entity.other.attribute-name.decl-attribute-name.xml",
|
|
regex: tagRegex
|
|
},
|
|
{
|
|
token: "keyword.operator.decl-attribute-equals.xml",
|
|
regex: "="
|
|
},
|
|
{
|
|
include: "whitespace"
|
|
},
|
|
{
|
|
include: "string"
|
|
},
|
|
{
|
|
token: "punctuation.xml-decl.xml",
|
|
regex: "\\?>",
|
|
next: "start"
|
|
}
|
|
],
|
|
|
|
doctype: [
|
|
{ include: "whitespace" },
|
|
{ include: "string" },
|
|
{ token: "xml-pe.doctype.xml", regex: ">", next: "start" },
|
|
{ token: "xml-pe.xml", regex: "[-_a-zA-Z0-9:]+" },
|
|
{ token: "punctuation.int-subset", regex: "\\[", push: "int_subset" }
|
|
],
|
|
|
|
int_subset: [
|
|
{
|
|
token: "text.xml",
|
|
regex: "\\s+"
|
|
},
|
|
{
|
|
token: "punctuation.int-subset.xml",
|
|
regex: "]",
|
|
next: "pop"
|
|
},
|
|
{
|
|
token: ["punctuation.markup-decl.xml", "keyword.markup-decl.xml"],
|
|
regex: "(<\\!)(" + tagRegex + ")",
|
|
push: [
|
|
{
|
|
token: "text",
|
|
regex: "\\s+"
|
|
},
|
|
{
|
|
token: "punctuation.markup-decl.xml",
|
|
regex: ">",
|
|
next: "pop"
|
|
},
|
|
{ include: "string" }
|
|
]
|
|
}
|
|
],
|
|
|
|
cdata: [
|
|
{ token: "string.cdata.xml", regex: "\\]\\]>", next: "start" },
|
|
{ token: "text.xml", regex: "\\s+" },
|
|
{ token: "text.xml", regex: "(?:[^\\]]|\\](?!\\]>))+" }
|
|
],
|
|
|
|
comment: [
|
|
{ token: "comment.end.xml", regex: "-->", next: "start" },
|
|
{ defaultToken: "comment.xml" }
|
|
],
|
|
|
|
reference: [
|
|
{
|
|
token: "constant.language.escape.reference.xml",
|
|
regex: "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"
|
|
}
|
|
],
|
|
|
|
attr_reference: [
|
|
{
|
|
token: "constant.language.escape.reference.attribute-value.xml",
|
|
regex: "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"
|
|
}
|
|
],
|
|
|
|
tag: [
|
|
{
|
|
token: [
|
|
"meta.tag.punctuation.tag-open.xml",
|
|
"meta.tag.punctuation.end-tag-open.xml",
|
|
"meta.tag.tag-name.xml"
|
|
],
|
|
regex: "(?:(<)|(</))((?:" + tagRegex + ":)?" + tagRegex + ")",
|
|
next: [
|
|
{ include: "attributes" },
|
|
{
|
|
token: "meta.tag.punctuation.tag-close.xml",
|
|
regex: "/?>",
|
|
next: "start"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
|
|
tag_whitespace: [{ token: "text.tag-whitespace.xml", regex: "\\s+" }],
|
|
whitespace: [{ token: "text.whitespace.xml", regex: "\\s+" }],
|
|
string: [
|
|
{
|
|
token: "string.xml",
|
|
regex: "'",
|
|
push: [
|
|
{ token: "string.xml", regex: "'", next: "pop" },
|
|
{ defaultToken: "string.xml" }
|
|
]
|
|
},
|
|
{
|
|
token: "string.xml",
|
|
regex: '"',
|
|
push: [
|
|
{ token: "string.xml", regex: '"', next: "pop" },
|
|
{ defaultToken: "string.xml" }
|
|
]
|
|
}
|
|
],
|
|
|
|
attributes: [
|
|
{
|
|
token: "entity.other.attribute-name.xml",
|
|
regex: tagRegex
|
|
},
|
|
{
|
|
token: "keyword.operator.attribute-equals.xml",
|
|
regex: "="
|
|
},
|
|
{
|
|
include: "tag_whitespace"
|
|
},
|
|
{
|
|
include: "attribute_value"
|
|
}
|
|
],
|
|
|
|
attribute_value: [
|
|
{
|
|
token: "string.attribute-value.xml",
|
|
regex: "'",
|
|
push: [
|
|
{ token: "string.attribute-value.xml", regex: "'", next: "pop" },
|
|
{ include: "attr_reference" },
|
|
{ defaultToken: "string.attribute-value.xml" }
|
|
]
|
|
},
|
|
{
|
|
token: "string.attribute-value.xml",
|
|
regex: '"',
|
|
push: [
|
|
{ token: "string.attribute-value.xml", regex: '"', next: "pop" },
|
|
{ include: "attr_reference" },
|
|
{ defaultToken: "string.attribute-value.xml" }
|
|
]
|
|
}
|
|
]
|
|
};
|
|
|
|
if (this.constructor === XmlHighlightRules) this.normalizeRules();
|
|
};
|
|
|
|
(function() {
|
|
this.embedTagRules = function(HighlightRules, prefix, tag) {
|
|
this.$rules.tag.unshift({
|
|
token: [
|
|
"meta.tag.punctuation.tag-open.xml",
|
|
"meta.tag." + tag + ".tag-name.xml"
|
|
],
|
|
regex: "(<)(" + tag + "(?=\\s|>|$))",
|
|
next: [
|
|
{ include: "attributes" },
|
|
{
|
|
token: "meta.tag.punctuation.tag-close.xml",
|
|
regex: "/?>",
|
|
next: prefix + "start"
|
|
}
|
|
]
|
|
});
|
|
|
|
this.$rules[tag + "-end"] = [
|
|
{ include: "attributes" },
|
|
{
|
|
token: "meta.tag.punctuation.tag-close.xml",
|
|
regex: "/?>",
|
|
next: "start",
|
|
onMatch: function(value, currentState, stack) {
|
|
stack.splice(0);
|
|
return this.token;
|
|
}
|
|
}
|
|
];
|
|
|
|
this.embedRules(HighlightRules, prefix, [
|
|
{
|
|
token: [
|
|
"meta.tag.punctuation.end-tag-open.xml",
|
|
"meta.tag." + tag + ".tag-name.xml"
|
|
],
|
|
regex: "(</)(" + tag + "(?=\\s|>|$))",
|
|
next: tag + "-end"
|
|
},
|
|
{
|
|
token: "string.cdata.xml",
|
|
regex: "<\\!\\[CDATA\\["
|
|
},
|
|
{
|
|
token: "string.cdata.xml",
|
|
regex: "\\]\\]>"
|
|
}
|
|
]);
|
|
};
|
|
}.call(TextHighlightRules.prototype));
|
|
|
|
oop.inherits(XmlHighlightRules, TextHighlightRules);
|
|
|
|
exports.XmlHighlightRules = XmlHighlightRules;
|
|
}
|
|
);
|
|
|
|
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) {
|
|
"use strict";
|
|
|
|
var oop = require("../../lib/oop");
|
|
var Behaviour = require("../behaviour").Behaviour;
|
|
var TokenIterator = require("../../token_iterator").TokenIterator;
|
|
var lang = require("../../lib/lang");
|
|
|
|
function is(token, type) {
|
|
return token && token.type.lastIndexOf(type + ".xml") > -1;
|
|
}
|
|
|
|
var XmlBehaviour = function() {
|
|
this.add("string_dquotes", "insertion", function(
|
|
state,
|
|
action,
|
|
editor,
|
|
session,
|
|
text
|
|
) {
|
|
if (text == '"' || text == "'") {
|
|
var quote = text;
|
|
var selected = session.doc.getTextRange(editor.getSelectionRange());
|
|
if (
|
|
selected !== "" &&
|
|
selected !== "'" &&
|
|
selected != '"' &&
|
|
editor.getWrapBehavioursEnabled()
|
|
) {
|
|
return {
|
|
text: quote + selected + quote,
|
|
selection: false
|
|
};
|
|
}
|
|
|
|
var cursor = editor.getCursorPosition();
|
|
var line = session.doc.getLine(cursor.row);
|
|
var rightChar = line.substring(cursor.column, cursor.column + 1);
|
|
var iterator = new TokenIterator(session, cursor.row, cursor.column);
|
|
var token = iterator.getCurrentToken();
|
|
|
|
if (
|
|
rightChar == quote &&
|
|
(is(token, "attribute-value") || is(token, "string"))
|
|
) {
|
|
return {
|
|
text: "",
|
|
selection: [1, 1]
|
|
};
|
|
}
|
|
|
|
if (!token) token = iterator.stepBackward();
|
|
|
|
if (!token) return;
|
|
|
|
while (is(token, "tag-whitespace") || is(token, "whitespace")) {
|
|
token = iterator.stepBackward();
|
|
}
|
|
var rightSpace = !rightChar || rightChar.match(/\s/);
|
|
if (
|
|
(is(token, "attribute-equals") &&
|
|
(rightSpace || rightChar == ">")) ||
|
|
(is(token, "decl-attribute-equals") &&
|
|
(rightSpace || rightChar == "?"))
|
|
) {
|
|
return {
|
|
text: quote + quote,
|
|
selection: [1, 1]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
|
|
this.add("string_dquotes", "deletion", function(
|
|
state,
|
|
action,
|
|
editor,
|
|
session,
|
|
range
|
|
) {
|
|
var selected = session.doc.getTextRange(range);
|
|
if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
|
|
var line = session.doc.getLine(range.start.row);
|
|
var rightChar = line.substring(
|
|
range.start.column + 1,
|
|
range.start.column + 2
|
|
);
|
|
if (rightChar == selected) {
|
|
range.end.column++;
|
|
return range;
|
|
}
|
|
}
|
|
});
|
|
|
|
this.add("autoclosing", "insertion", function(
|
|
state,
|
|
action,
|
|
editor,
|
|
session,
|
|
text
|
|
) {
|
|
if (text == ">") {
|
|
var position = editor.getSelectionRange().start;
|
|
var iterator = new TokenIterator(
|
|
session,
|
|
position.row,
|
|
position.column
|
|
);
|
|
var token = iterator.getCurrentToken() || iterator.stepBackward();
|
|
if (
|
|
!token ||
|
|
!(
|
|
is(token, "tag-name") ||
|
|
is(token, "tag-whitespace") ||
|
|
is(token, "attribute-name") ||
|
|
is(token, "attribute-equals") ||
|
|
is(token, "attribute-value")
|
|
)
|
|
)
|
|
return;
|
|
if (is(token, "reference.attribute-value")) return;
|
|
if (is(token, "attribute-value")) {
|
|
var tokenEndColumn =
|
|
iterator.getCurrentTokenColumn() + token.value.length;
|
|
if (position.column < tokenEndColumn) return;
|
|
if (position.column == tokenEndColumn) {
|
|
var nextToken = iterator.stepForward();
|
|
if (nextToken && is(nextToken, "attribute-value")) return;
|
|
iterator.stepBackward();
|
|
}
|
|
}
|
|
|
|
if (
|
|
/^\s*>/.test(session.getLine(position.row).slice(position.column))
|
|
)
|
|
return;
|
|
while (!is(token, "tag-name")) {
|
|
token = iterator.stepBackward();
|
|
if (token.value == "<") {
|
|
token = iterator.stepForward();
|
|
break;
|
|
}
|
|
}
|
|
|
|
var tokenRow = iterator.getCurrentTokenRow();
|
|
var tokenColumn = iterator.getCurrentTokenColumn();
|
|
if (is(iterator.stepBackward(), "end-tag-open")) return;
|
|
|
|
var element = token.value;
|
|
if (tokenRow == position.row)
|
|
element = element.substring(0, position.column - tokenColumn);
|
|
|
|
if (this.voidElements.hasOwnProperty(element.toLowerCase())) return;
|
|
|
|
return {
|
|
text: ">" + "</" + element + ">",
|
|
selection: [1, 1]
|
|
};
|
|
}
|
|
});
|
|
|
|
this.add("autoindent", "insertion", function(
|
|
state,
|
|
action,
|
|
editor,
|
|
session,
|
|
text
|
|
) {
|
|
if (text == "\n") {
|
|
var cursor = editor.getCursorPosition();
|
|
var line = session.getLine(cursor.row);
|
|
var iterator = new TokenIterator(session, cursor.row, cursor.column);
|
|
var token = iterator.getCurrentToken();
|
|
|
|
if (token && token.type.indexOf("tag-close") !== -1) {
|
|
if (token.value == "/>") return;
|
|
while (token && token.type.indexOf("tag-name") === -1) {
|
|
token = iterator.stepBackward();
|
|
}
|
|
|
|
if (!token) {
|
|
return;
|
|
}
|
|
|
|
var tag = token.value;
|
|
var row = iterator.getCurrentTokenRow();
|
|
token = iterator.stepBackward();
|
|
if (!token || token.type.indexOf("end-tag") !== -1) {
|
|
return;
|
|
}
|
|
|
|
if (this.voidElements && !this.voidElements[tag]) {
|
|
var nextToken = session.getTokenAt(cursor.row, cursor.column + 1);
|
|
var line = session.getLine(row);
|
|
var nextIndent = this.$getIndent(line);
|
|
var indent = nextIndent + session.getTabString();
|
|
|
|
if (nextToken && nextToken.value === "</") {
|
|
return {
|
|
text: "\n" + indent + "\n" + nextIndent,
|
|
selection: [1, indent.length, 1, indent.length]
|
|
};
|
|
} else {
|
|
return {
|
|
text: "\n" + indent
|
|
};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
oop.inherits(XmlBehaviour, Behaviour);
|
|
|
|
exports.XmlBehaviour = XmlBehaviour;
|
|
}
|
|
);
|
|
|
|
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) {
|
|
"use strict";
|
|
|
|
var oop = require("../../lib/oop");
|
|
var lang = require("../../lib/lang");
|
|
var Range = require("../../range").Range;
|
|
var BaseFoldMode = require("./fold_mode").FoldMode;
|
|
var TokenIterator = require("../../token_iterator").TokenIterator;
|
|
|
|
var FoldMode = (exports.FoldMode = function(voidElements, optionalEndTags) {
|
|
BaseFoldMode.call(this);
|
|
this.voidElements = voidElements || {};
|
|
this.optionalEndTags = oop.mixin({}, this.voidElements);
|
|
if (optionalEndTags) oop.mixin(this.optionalEndTags, optionalEndTags);
|
|
});
|
|
oop.inherits(FoldMode, BaseFoldMode);
|
|
|
|
var Tag = function() {
|
|
this.tagName = "";
|
|
this.closing = false;
|
|
this.selfClosing = false;
|
|
this.start = { row: 0, column: 0 };
|
|
this.end = { row: 0, column: 0 };
|
|
};
|
|
|
|
function is(token, type) {
|
|
return token.type.lastIndexOf(type + ".xml") > -1;
|
|
}
|
|
|
|
(function() {
|
|
this.getFoldWidget = function(session, foldStyle, row) {
|
|
var tag = this._getFirstTagInLine(session, row);
|
|
|
|
if (!tag) return this.getCommentFoldWidget(session, row);
|
|
|
|
if (tag.closing || (!tag.tagName && tag.selfClosing))
|
|
return foldStyle == "markbeginend" ? "end" : "";
|
|
|
|
if (
|
|
!tag.tagName ||
|
|
tag.selfClosing ||
|
|
this.voidElements.hasOwnProperty(tag.tagName.toLowerCase())
|
|
)
|
|
return "";
|
|
|
|
if (this._findEndTagInLine(session, row, tag.tagName, tag.end.column))
|
|
return "";
|
|
|
|
return "start";
|
|
};
|
|
|
|
this.getCommentFoldWidget = function(session, row) {
|
|
if (
|
|
/comment/.test(session.getState(row)) &&
|
|
/<!-/.test(session.getLine(row))
|
|
)
|
|
return "start";
|
|
return "";
|
|
};
|
|
this._getFirstTagInLine = function(session, row) {
|
|
var tokens = session.getTokens(row);
|
|
var tag = new Tag();
|
|
|
|
for (var i = 0; i < tokens.length; i++) {
|
|
var token = tokens[i];
|
|
if (is(token, "tag-open")) {
|
|
tag.end.column = tag.start.column + token.value.length;
|
|
tag.closing = is(token, "end-tag-open");
|
|
token = tokens[++i];
|
|
if (!token) return null;
|
|
tag.tagName = token.value;
|
|
tag.end.column += token.value.length;
|
|
for (i++; i < tokens.length; i++) {
|
|
token = tokens[i];
|
|
tag.end.column += token.value.length;
|
|
if (is(token, "tag-close")) {
|
|
tag.selfClosing = token.value == "/>";
|
|
break;
|
|
}
|
|
}
|
|
return tag;
|
|
} else if (is(token, "tag-close")) {
|
|
tag.selfClosing = token.value == "/>";
|
|
return tag;
|
|
}
|
|
tag.start.column += token.value.length;
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
this._findEndTagInLine = function(session, row, tagName, startColumn) {
|
|
var tokens = session.getTokens(row);
|
|
var column = 0;
|
|
for (var i = 0; i < tokens.length; i++) {
|
|
var token = tokens[i];
|
|
column += token.value.length;
|
|
if (column < startColumn) continue;
|
|
if (is(token, "end-tag-open")) {
|
|
token = tokens[i + 1];
|
|
if (token && token.value == tagName) return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
this._readTagForward = function(iterator) {
|
|
var token = iterator.getCurrentToken();
|
|
if (!token) return null;
|
|
|
|
var tag = new Tag();
|
|
do {
|
|
if (is(token, "tag-open")) {
|
|
tag.closing = is(token, "end-tag-open");
|
|
tag.start.row = iterator.getCurrentTokenRow();
|
|
tag.start.column = iterator.getCurrentTokenColumn();
|
|
} else if (is(token, "tag-name")) {
|
|
tag.tagName = token.value;
|
|
} else if (is(token, "tag-close")) {
|
|
tag.selfClosing = token.value == "/>";
|
|
tag.end.row = iterator.getCurrentTokenRow();
|
|
tag.end.column =
|
|
iterator.getCurrentTokenColumn() + token.value.length;
|
|
iterator.stepForward();
|
|
return tag;
|
|
}
|
|
} while ((token = iterator.stepForward()));
|
|
|
|
return null;
|
|
};
|
|
|
|
this._readTagBackward = function(iterator) {
|
|
var token = iterator.getCurrentToken();
|
|
if (!token) return null;
|
|
|
|
var tag = new Tag();
|
|
do {
|
|
if (is(token, "tag-open")) {
|
|
tag.closing = is(token, "end-tag-open");
|
|
tag.start.row = iterator.getCurrentTokenRow();
|
|
tag.start.column = iterator.getCurrentTokenColumn();
|
|
iterator.stepBackward();
|
|
return tag;
|
|
} else if (is(token, "tag-name")) {
|
|
tag.tagName = token.value;
|
|
} else if (is(token, "tag-close")) {
|
|
tag.selfClosing = token.value == "/>";
|
|
tag.end.row = iterator.getCurrentTokenRow();
|
|
tag.end.column =
|
|
iterator.getCurrentTokenColumn() + token.value.length;
|
|
}
|
|
} while ((token = iterator.stepBackward()));
|
|
|
|
return null;
|
|
};
|
|
|
|
this._pop = function(stack, tag) {
|
|
while (stack.length) {
|
|
var top = stack[stack.length - 1];
|
|
if (!tag || top.tagName == tag.tagName) {
|
|
return stack.pop();
|
|
} else if (this.optionalEndTags.hasOwnProperty(top.tagName)) {
|
|
stack.pop();
|
|
continue;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
};
|
|
|
|
this.getFoldWidgetRange = function(session, foldStyle, row) {
|
|
var firstTag = this._getFirstTagInLine(session, row);
|
|
|
|
if (!firstTag) {
|
|
return (
|
|
this.getCommentFoldWidget(session, row) &&
|
|
session.getCommentFoldRange(row, session.getLine(row).length)
|
|
);
|
|
}
|
|
|
|
var isBackward = firstTag.closing || firstTag.selfClosing;
|
|
var stack = [];
|
|
var tag;
|
|
|
|
if (!isBackward) {
|
|
var iterator = new TokenIterator(session, row, firstTag.start.column);
|
|
var start = {
|
|
row: row,
|
|
column: firstTag.start.column + firstTag.tagName.length + 2
|
|
};
|
|
if (firstTag.start.row == firstTag.end.row)
|
|
start.column = firstTag.end.column;
|
|
while ((tag = this._readTagForward(iterator))) {
|
|
if (tag.selfClosing) {
|
|
if (!stack.length) {
|
|
tag.start.column += tag.tagName.length + 2;
|
|
tag.end.column -= 2;
|
|
return Range.fromPoints(tag.start, tag.end);
|
|
} else continue;
|
|
}
|
|
|
|
if (tag.closing) {
|
|
this._pop(stack, tag);
|
|
if (stack.length == 0) return Range.fromPoints(start, tag.start);
|
|
} else {
|
|
stack.push(tag);
|
|
}
|
|
}
|
|
} else {
|
|
var iterator = new TokenIterator(session, row, firstTag.end.column);
|
|
var end = {
|
|
row: row,
|
|
column: firstTag.start.column
|
|
};
|
|
|
|
while ((tag = this._readTagBackward(iterator))) {
|
|
if (tag.selfClosing) {
|
|
if (!stack.length) {
|
|
tag.start.column += tag.tagName.length + 2;
|
|
tag.end.column -= 2;
|
|
return Range.fromPoints(tag.start, tag.end);
|
|
} else continue;
|
|
}
|
|
|
|
if (!tag.closing) {
|
|
this._pop(stack, tag);
|
|
if (stack.length == 0) {
|
|
tag.start.column += tag.tagName.length + 2;
|
|
if (
|
|
tag.start.row == tag.end.row &&
|
|
tag.start.column < tag.end.column
|
|
)
|
|
tag.start.column = tag.end.column;
|
|
return Range.fromPoints(tag.start, end);
|
|
}
|
|
} else {
|
|
stack.push(tag);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}.call(FoldMode.prototype));
|
|
}
|
|
);
|
|
|
|
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",
|
|
"ace/worker/worker_client"
|
|
],
|
|
function(require, exports, module) {
|
|
"use strict";
|
|
|
|
var oop = require("../lib/oop");
|
|
var lang = require("../lib/lang");
|
|
var TextMode = require("./text").Mode;
|
|
var XmlHighlightRules = require("./xml_highlight_rules").XmlHighlightRules;
|
|
var XmlBehaviour = require("./behaviour/xml").XmlBehaviour;
|
|
var XmlFoldMode = require("./folding/xml").FoldMode;
|
|
var WorkerClient = require("../worker/worker_client").WorkerClient;
|
|
|
|
var Mode = function() {
|
|
this.HighlightRules = XmlHighlightRules;
|
|
this.$behaviour = new XmlBehaviour();
|
|
this.foldingRules = new XmlFoldMode();
|
|
};
|
|
|
|
oop.inherits(Mode, TextMode);
|
|
|
|
(function() {
|
|
this.voidElements = lang.arrayToMap([]);
|
|
|
|
this.blockComment = { start: "<!--", end: "-->" };
|
|
|
|
this.createWorker = function(session) {
|
|
var worker = new WorkerClient(["ace"], "ace/mode/xml_worker", "Worker");
|
|
worker.attachToDocument(session.getDocument());
|
|
|
|
worker.on("error", function(e) {
|
|
session.setAnnotations(e.data);
|
|
});
|
|
|
|
worker.on("terminate", function() {
|
|
session.clearAnnotations();
|
|
});
|
|
|
|
return worker;
|
|
};
|
|
|
|
this.$id = "ace/mode/xml";
|
|
}.call(Mode.prototype));
|
|
|
|
exports.Mode = Mode;
|
|
}
|
|
);
|
|
(function() {
|
|
ace.require(["ace/mode/xml"], function(m) {
|
|
if (typeof module == "object" && typeof exports == "object" && module) {
|
|
module.exports = m;
|
|
}
|
|
});
|
|
})();
|