in src-noconflict/worker-html.js [3711:6017]
function TreeBuilder() {
this.tokenizer = null;
this.errorHandler = null;
this.scriptingEnabled = false;
this.document = null;
this.head = null;
this.form = null;
this.openElements = new ElementStack();
this.activeFormattingElements = [];
this.insertionMode = null;
this.insertionModeName = "";
this.originalInsertionMode = "";
this.inQuirksMode = false; // TODO quirks mode
this.compatMode = "no quirks";
this.framesetOk = true;
this.redirectAttachToFosterParent = false;
this.selfClosingFlagAcknowledged = false;
this.context = "";
this.pendingTableCharacters = [];
this.shouldSkipLeadingNewline = false;
var tree = this;
var modes = this.insertionModes = {};
modes.base = {
end_tag_handlers: {"-default": 'endTagOther'},
start_tag_handlers: {"-default": 'startTagOther'},
processEOF: function() {
tree.generateImpliedEndTags();
if (tree.openElements.length > 2) {
tree.parseError('expected-closing-tag-but-got-eof');
} else if (tree.openElements.length == 2 &&
tree.openElements.item(1).localName != 'body') {
tree.parseError('expected-closing-tag-but-got-eof');
} else if (tree.context && tree.openElements.length > 1) {
}
},
processComment: function(data) {
tree.insertComment(data, tree.currentStackItem().node);
},
processDoctype: function(name, publicId, systemId, forceQuirks) {
tree.parseError('unexpected-doctype');
},
processStartTag: function(name, attributes, selfClosing) {
if (this[this.start_tag_handlers[name]]) {
this[this.start_tag_handlers[name]](name, attributes, selfClosing);
} else if (this[this.start_tag_handlers["-default"]]) {
this[this.start_tag_handlers["-default"]](name, attributes, selfClosing);
} else {
throw(new Error("No handler found for "+name));
}
},
processEndTag: function(name) {
if (this[this.end_tag_handlers[name]]) {
this[this.end_tag_handlers[name]](name);
} else if (this[this.end_tag_handlers["-default"]]) {
this[this.end_tag_handlers["-default"]](name);
} else {
throw(new Error("No handler found for "+name));
}
},
startTagHtml: function(name, attributes) {
modes.inBody.startTagHtml(name, attributes);
}
};
modes.initial = Object.create(modes.base);
modes.initial.processEOF = function() {
tree.parseError("expected-doctype-but-got-eof");
this.anythingElse();
tree.insertionMode.processEOF();
};
modes.initial.processComment = function(data) {
tree.insertComment(data, tree.document);
};
modes.initial.processDoctype = function(name, publicId, systemId, forceQuirks) {
tree.insertDoctype(name || '', publicId || '', systemId || '');
if (forceQuirks || name != 'html' || (publicId != null && ([
"+//silmaril//dtd html pro v0r11 19970101//",
"-//advasoft ltd//dtd html 3.0 aswedit + extensions//",
"-//as//dtd html 3.0 aswedit + extensions//",
"-//ietf//dtd html 2.0 level 1//",
"-//ietf//dtd html 2.0 level 2//",
"-//ietf//dtd html 2.0 strict level 1//",
"-//ietf//dtd html 2.0 strict level 2//",
"-//ietf//dtd html 2.0 strict//",
"-//ietf//dtd html 2.0//",
"-//ietf//dtd html 2.1e//",
"-//ietf//dtd html 3.0//",
"-//ietf//dtd html 3.0//",
"-//ietf//dtd html 3.2 final//",
"-//ietf//dtd html 3.2//",
"-//ietf//dtd html 3//",
"-//ietf//dtd html level 0//",
"-//ietf//dtd html level 0//",
"-//ietf//dtd html level 1//",
"-//ietf//dtd html level 1//",
"-//ietf//dtd html level 2//",
"-//ietf//dtd html level 2//",
"-//ietf//dtd html level 3//",
"-//ietf//dtd html level 3//",
"-//ietf//dtd html strict level 0//",
"-//ietf//dtd html strict level 0//",
"-//ietf//dtd html strict level 1//",
"-//ietf//dtd html strict level 1//",
"-//ietf//dtd html strict level 2//",
"-//ietf//dtd html strict level 2//",
"-//ietf//dtd html strict level 3//",
"-//ietf//dtd html strict level 3//",
"-//ietf//dtd html strict//",
"-//ietf//dtd html strict//",
"-//ietf//dtd html strict//",
"-//ietf//dtd html//",
"-//ietf//dtd html//",
"-//ietf//dtd html//",
"-//metrius//dtd metrius presentational//",
"-//microsoft//dtd internet explorer 2.0 html strict//",
"-//microsoft//dtd internet explorer 2.0 html//",
"-//microsoft//dtd internet explorer 2.0 tables//",
"-//microsoft//dtd internet explorer 3.0 html strict//",
"-//microsoft//dtd internet explorer 3.0 html//",
"-//microsoft//dtd internet explorer 3.0 tables//",
"-//netscape comm. corp.//dtd html//",
"-//netscape comm. corp.//dtd strict html//",
"-//o'reilly and associates//dtd html 2.0//",
"-//o'reilly and associates//dtd html extended 1.0//",
"-//spyglass//dtd html 2.0 extended//",
"-//sq//dtd html 2.0 hotmetal + extensions//",
"-//sun microsystems corp.//dtd hotjava html//",
"-//sun microsystems corp.//dtd hotjava strict html//",
"-//w3c//dtd html 3 1995-03-24//",
"-//w3c//dtd html 3.2 draft//",
"-//w3c//dtd html 3.2 final//",
"-//w3c//dtd html 3.2//",
"-//w3c//dtd html 3.2s draft//",
"-//w3c//dtd html 4.0 frameset//",
"-//w3c//dtd html 4.0 transitional//",
"-//w3c//dtd html experimental 19960712//",
"-//w3c//dtd html experimental 970421//",
"-//w3c//dtd w3 html//",
"-//w3o//dtd w3 html 3.0//",
"-//webtechs//dtd mozilla html 2.0//",
"-//webtechs//dtd mozilla html//",
"html"
].some(publicIdStartsWith)
|| [
"-//w3o//dtd w3 html strict 3.0//en//",
"-/w3c/dtd html 4.0 transitional/en",
"html"
].indexOf(publicId.toLowerCase()) > -1
|| (systemId == null && [
"-//w3c//dtd html 4.01 transitional//",
"-//w3c//dtd html 4.01 frameset//"
].some(publicIdStartsWith)))
)
|| (systemId != null && (systemId.toLowerCase() == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"))
) {
tree.compatMode = "quirks";
tree.parseError("quirky-doctype");
} else if (publicId != null && ([
"-//w3c//dtd xhtml 1.0 transitional//",
"-//w3c//dtd xhtml 1.0 frameset//"
].some(publicIdStartsWith)
|| (systemId != null && [
"-//w3c//dtd html 4.01 transitional//",
"-//w3c//dtd html 4.01 frameset//"
].indexOf(publicId.toLowerCase()) > -1))
) {
tree.compatMode = "limited quirks";
tree.parseError("almost-standards-doctype");
} else {
if ((publicId == "-//W3C//DTD HTML 4.0//EN" && (systemId == null || systemId == "http://www.w3.org/TR/REC-html40/strict.dtd"))
|| (publicId == "-//W3C//DTD HTML 4.01//EN" && (systemId == null || systemId == "http://www.w3.org/TR/html4/strict.dtd"))
|| (publicId == "-//W3C//DTD XHTML 1.0 Strict//EN" && (systemId == "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"))
|| (publicId == "-//W3C//DTD XHTML 1.1//EN" && (systemId == "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"))
) {
} else if (!((systemId == null || systemId == "about:legacy-compat") && publicId == null)) {
tree.parseError("unknown-doctype");
}
}
tree.setInsertionMode('beforeHTML');
function publicIdStartsWith(string) {
return publicId.toLowerCase().indexOf(string) === 0;
}
};
modes.initial.processCharacters = function(buffer) {
buffer.skipLeadingWhitespace();
if (!buffer.length)
return;
tree.parseError('expected-doctype-but-got-chars');
this.anythingElse();
tree.insertionMode.processCharacters(buffer);
};
modes.initial.processStartTag = function(name, attributes, selfClosing) {
tree.parseError('expected-doctype-but-got-start-tag', {name: name});
this.anythingElse();
tree.insertionMode.processStartTag(name, attributes, selfClosing);
};
modes.initial.processEndTag = function(name) {
tree.parseError('expected-doctype-but-got-end-tag', {name: name});
this.anythingElse();
tree.insertionMode.processEndTag(name);
};
modes.initial.anythingElse = function() {
tree.compatMode = 'quirks';
tree.setInsertionMode('beforeHTML');
};
modes.beforeHTML = Object.create(modes.base);
modes.beforeHTML.start_tag_handlers = {
html: 'startTagHtml',
'-default': 'startTagOther'
};
modes.beforeHTML.processEOF = function() {
this.anythingElse();
tree.insertionMode.processEOF();
};
modes.beforeHTML.processComment = function(data) {
tree.insertComment(data, tree.document);
};
modes.beforeHTML.processCharacters = function(buffer) {
buffer.skipLeadingWhitespace();
if (!buffer.length)
return;
this.anythingElse();
tree.insertionMode.processCharacters(buffer);
};
modes.beforeHTML.startTagHtml = function(name, attributes, selfClosing) {
tree.insertHtmlElement(attributes);
tree.setInsertionMode('beforeHead');
};
modes.beforeHTML.startTagOther = function(name, attributes, selfClosing) {
this.anythingElse();
tree.insertionMode.processStartTag(name, attributes, selfClosing);
};
modes.beforeHTML.processEndTag = function(name) {
this.anythingElse();
tree.insertionMode.processEndTag(name);
};
modes.beforeHTML.anythingElse = function() {
tree.insertHtmlElement();
tree.setInsertionMode('beforeHead');
};
modes.afterAfterBody = Object.create(modes.base);
modes.afterAfterBody.start_tag_handlers = {
html: 'startTagHtml',
'-default': 'startTagOther'
};
modes.afterAfterBody.processComment = function(data) {
tree.insertComment(data, tree.document);
};
modes.afterAfterBody.processDoctype = function(data) {
modes.inBody.processDoctype(data);
};
modes.afterAfterBody.startTagHtml = function(data, attributes) {
modes.inBody.startTagHtml(data, attributes);
};
modes.afterAfterBody.startTagOther = function(name, attributes, selfClosing) {
tree.parseError('unexpected-start-tag', {name: name});
tree.setInsertionMode('inBody');
tree.insertionMode.processStartTag(name, attributes, selfClosing);
};
modes.afterAfterBody.endTagOther = function(name) {
tree.parseError('unexpected-end-tag', {name: name});
tree.setInsertionMode('inBody');
tree.insertionMode.processEndTag(name);
};
modes.afterAfterBody.processCharacters = function(data) {
if (!isAllWhitespace(data.characters)) {
tree.parseError('unexpected-char-after-body');
tree.setInsertionMode('inBody');
return tree.insertionMode.processCharacters(data);
}
modes.inBody.processCharacters(data);
};
modes.afterBody = Object.create(modes.base);
modes.afterBody.end_tag_handlers = {
html: 'endTagHtml',
'-default': 'endTagOther'
};
modes.afterBody.processComment = function(data) {
tree.insertComment(data, tree.openElements.rootNode);
};
modes.afterBody.processCharacters = function(data) {
if (!isAllWhitespace(data.characters)) {
tree.parseError('unexpected-char-after-body');
tree.setInsertionMode('inBody');
return tree.insertionMode.processCharacters(data);
}
modes.inBody.processCharacters(data);
};
modes.afterBody.processStartTag = function(name, attributes, selfClosing) {
tree.parseError('unexpected-start-tag-after-body', {name: name});
tree.setInsertionMode('inBody');
tree.insertionMode.processStartTag(name, attributes, selfClosing);
};
modes.afterBody.endTagHtml = function(name) {
if (tree.context) {
tree.parseError('end-html-in-innerhtml');
} else {
tree.setInsertionMode('afterAfterBody');
}
};
modes.afterBody.endTagOther = function(name) {
tree.parseError('unexpected-end-tag-after-body', {name: name});
tree.setInsertionMode('inBody');
tree.insertionMode.processEndTag(name);
};
modes.afterFrameset = Object.create(modes.base);
modes.afterFrameset.start_tag_handlers = {
html: 'startTagHtml',
noframes: 'startTagNoframes',
'-default': 'startTagOther'
};
modes.afterFrameset.end_tag_handlers = {
html: 'endTagHtml',
'-default': 'endTagOther'
};
modes.afterFrameset.processCharacters = function(buffer) {
var characters = buffer.takeRemaining();
var whitespace = "";
for (var i = 0; i < characters.length; i++) {
var ch = characters[i];
if (isWhitespace(ch))
whitespace += ch;
}
if (whitespace) {
tree.insertText(whitespace);
}
if (whitespace.length < characters.length)
tree.parseError('expected-eof-but-got-char');
};
modes.afterFrameset.startTagNoframes = function(name, attributes) {
modes.inHead.processStartTag(name, attributes);
};
modes.afterFrameset.startTagOther = function(name, attributes) {
tree.parseError("unexpected-start-tag-after-frameset", {name: name});
};
modes.afterFrameset.endTagHtml = function(name) {
tree.setInsertionMode('afterAfterFrameset');
};
modes.afterFrameset.endTagOther = function(name) {
tree.parseError("unexpected-end-tag-after-frameset", {name: name});
};
modes.beforeHead = Object.create(modes.base);
modes.beforeHead.start_tag_handlers = {
html: 'startTagHtml',
head: 'startTagHead',
'-default': 'startTagOther'
};
modes.beforeHead.end_tag_handlers = {
html: 'endTagImplyHead',
head: 'endTagImplyHead',
body: 'endTagImplyHead',
br: 'endTagImplyHead',
'-default': 'endTagOther'
};
modes.beforeHead.processEOF = function() {
this.startTagHead('head', []);
tree.insertionMode.processEOF();
};
modes.beforeHead.processCharacters = function(buffer) {
buffer.skipLeadingWhitespace();
if (!buffer.length)
return;
this.startTagHead('head', []);
tree.insertionMode.processCharacters(buffer);
};
modes.beforeHead.startTagHead = function(name, attributes) {
tree.insertHeadElement(attributes);
tree.setInsertionMode('inHead');
};
modes.beforeHead.startTagOther = function(name, attributes, selfClosing) {
this.startTagHead('head', []);
tree.insertionMode.processStartTag(name, attributes, selfClosing);
};
modes.beforeHead.endTagImplyHead = function(name) {
this.startTagHead('head', []);
tree.insertionMode.processEndTag(name);
};
modes.beforeHead.endTagOther = function(name) {
tree.parseError('end-tag-after-implied-root', {name: name});
};
modes.inHead = Object.create(modes.base);
modes.inHead.start_tag_handlers = {
html: 'startTagHtml',
head: 'startTagHead',
title: 'startTagTitle',
script: 'startTagScript',
style: 'startTagNoFramesStyle',
noscript: 'startTagNoScript',
noframes: 'startTagNoFramesStyle',
base: 'startTagBaseBasefontBgsoundLink',
basefont: 'startTagBaseBasefontBgsoundLink',
bgsound: 'startTagBaseBasefontBgsoundLink',
link: 'startTagBaseBasefontBgsoundLink',
meta: 'startTagMeta',
"-default": 'startTagOther'
};
modes.inHead.end_tag_handlers = {
head: 'endTagHead',
html: 'endTagHtmlBodyBr',
body: 'endTagHtmlBodyBr',
br: 'endTagHtmlBodyBr',
"-default": 'endTagOther'
};
modes.inHead.processEOF = function() {
var name = tree.currentStackItem().localName;
if (['title', 'style', 'script'].indexOf(name) != -1) {
tree.parseError("expected-named-closing-tag-but-got-eof", {name: name});
tree.popElement();
}
this.anythingElse();
tree.insertionMode.processEOF();
};
modes.inHead.processCharacters = function(buffer) {
var leadingWhitespace = buffer.takeLeadingWhitespace();
if (leadingWhitespace)
tree.insertText(leadingWhitespace);
if (!buffer.length)
return;
this.anythingElse();
tree.insertionMode.processCharacters(buffer);
};
modes.inHead.startTagHtml = function(name, attributes) {
modes.inBody.processStartTag(name, attributes);
};
modes.inHead.startTagHead = function(name, attributes) {
tree.parseError('two-heads-are-not-better-than-one');
};
modes.inHead.startTagTitle = function(name, attributes) {
tree.processGenericRCDATAStartTag(name, attributes);
};
modes.inHead.startTagNoScript = function(name, attributes) {
if (tree.scriptingEnabled)
return tree.processGenericRawTextStartTag(name, attributes);
tree.insertElement(name, attributes);
tree.setInsertionMode('inHeadNoscript');
};
modes.inHead.startTagNoFramesStyle = function(name, attributes) {
tree.processGenericRawTextStartTag(name, attributes);
};
modes.inHead.startTagScript = function(name, attributes) {
tree.insertElement(name, attributes);
tree.tokenizer.setState(Tokenizer.SCRIPT_DATA);
tree.originalInsertionMode = tree.insertionModeName;
tree.setInsertionMode('text');
};
modes.inHead.startTagBaseBasefontBgsoundLink = function(name, attributes) {
tree.insertSelfClosingElement(name, attributes);
};
modes.inHead.startTagMeta = function(name, attributes) {
tree.insertSelfClosingElement(name, attributes);
};
modes.inHead.startTagOther = function(name, attributes, selfClosing) {
this.anythingElse();
tree.insertionMode.processStartTag(name, attributes, selfClosing);
};
modes.inHead.endTagHead = function(name) {
if (tree.openElements.item(tree.openElements.length - 1).localName == 'head') {
tree.openElements.pop();
} else {
tree.parseError('unexpected-end-tag', {name: 'head'});
}
tree.setInsertionMode('afterHead');
};
modes.inHead.endTagHtmlBodyBr = function(name) {
this.anythingElse();
tree.insertionMode.processEndTag(name);
};
modes.inHead.endTagOther = function(name) {
tree.parseError('unexpected-end-tag', {name: name});
};
modes.inHead.anythingElse = function() {
this.endTagHead('head');
};
modes.afterHead = Object.create(modes.base);
modes.afterHead.start_tag_handlers = {
html: 'startTagHtml',
head: 'startTagHead',
body: 'startTagBody',
frameset: 'startTagFrameset',
base: 'startTagFromHead',
link: 'startTagFromHead',
meta: 'startTagFromHead',
script: 'startTagFromHead',
style: 'startTagFromHead',
title: 'startTagFromHead',
"-default": 'startTagOther'
};
modes.afterHead.end_tag_handlers = {
body: 'endTagBodyHtmlBr',
html: 'endTagBodyHtmlBr',
br: 'endTagBodyHtmlBr',
"-default": 'endTagOther'
};
modes.afterHead.processEOF = function() {
this.anythingElse();
tree.insertionMode.processEOF();
};
modes.afterHead.processCharacters = function(buffer) {
var leadingWhitespace = buffer.takeLeadingWhitespace();
if (leadingWhitespace)
tree.insertText(leadingWhitespace);
if (!buffer.length)
return;
this.anythingElse();
tree.insertionMode.processCharacters(buffer);
};
modes.afterHead.startTagHtml = function(name, attributes) {
modes.inBody.processStartTag(name, attributes);
};
modes.afterHead.startTagBody = function(name, attributes) {
tree.framesetOk = false;
tree.insertBodyElement(attributes);
tree.setInsertionMode('inBody');
};
modes.afterHead.startTagFrameset = function(name, attributes) {
tree.insertElement(name, attributes);
tree.setInsertionMode('inFrameset');
};
modes.afterHead.startTagFromHead = function(name, attributes, selfClosing) {
tree.parseError("unexpected-start-tag-out-of-my-head", {name: name});
tree.openElements.push(tree.head);
modes.inHead.processStartTag(name, attributes, selfClosing);
tree.openElements.remove(tree.head);
};
modes.afterHead.startTagHead = function(name, attributes, selfClosing) {
tree.parseError('unexpected-start-tag', {name: name});
};
modes.afterHead.startTagOther = function(name, attributes, selfClosing) {
this.anythingElse();
tree.insertionMode.processStartTag(name, attributes, selfClosing);
};
modes.afterHead.endTagBodyHtmlBr = function(name) {
this.anythingElse();
tree.insertionMode.processEndTag(name);
};
modes.afterHead.endTagOther = function(name) {
tree.parseError('unexpected-end-tag', {name: name});
};
modes.afterHead.anythingElse = function() {
tree.insertBodyElement([]);
tree.setInsertionMode('inBody');
tree.framesetOk = true;
}
modes.inBody = Object.create(modes.base);
modes.inBody.start_tag_handlers = {
html: 'startTagHtml',
head: 'startTagMisplaced',
base: 'startTagProcessInHead',
basefont: 'startTagProcessInHead',
bgsound: 'startTagProcessInHead',
link: 'startTagProcessInHead',
meta: 'startTagProcessInHead',
noframes: 'startTagProcessInHead',
script: 'startTagProcessInHead',
style: 'startTagProcessInHead',
title: 'startTagProcessInHead',
body: 'startTagBody',
form: 'startTagForm',
plaintext: 'startTagPlaintext',
a: 'startTagA',
button: 'startTagButton',
xmp: 'startTagXmp',
table: 'startTagTable',
hr: 'startTagHr',
image: 'startTagImage',
input: 'startTagInput',
textarea: 'startTagTextarea',
select: 'startTagSelect',
isindex: 'startTagIsindex',
applet: 'startTagAppletMarqueeObject',
marquee: 'startTagAppletMarqueeObject',
object: 'startTagAppletMarqueeObject',
li: 'startTagListItem',
dd: 'startTagListItem',
dt: 'startTagListItem',
address: 'startTagCloseP',
article: 'startTagCloseP',
aside: 'startTagCloseP',
blockquote: 'startTagCloseP',
center: 'startTagCloseP',
details: 'startTagCloseP',
dir: 'startTagCloseP',
div: 'startTagCloseP',
dl: 'startTagCloseP',
fieldset: 'startTagCloseP',
figcaption: 'startTagCloseP',
figure: 'startTagCloseP',
footer: 'startTagCloseP',
header: 'startTagCloseP',
hgroup: 'startTagCloseP',
main: 'startTagCloseP',
menu: 'startTagCloseP',
nav: 'startTagCloseP',
ol: 'startTagCloseP',
p: 'startTagCloseP',
section: 'startTagCloseP',
summary: 'startTagCloseP',
ul: 'startTagCloseP',
listing: 'startTagPreListing',
pre: 'startTagPreListing',
b: 'startTagFormatting',
big: 'startTagFormatting',
code: 'startTagFormatting',
em: 'startTagFormatting',
font: 'startTagFormatting',
i: 'startTagFormatting',
s: 'startTagFormatting',
small: 'startTagFormatting',
strike: 'startTagFormatting',
strong: 'startTagFormatting',
tt: 'startTagFormatting',
u: 'startTagFormatting',
nobr: 'startTagNobr',
area: 'startTagVoidFormatting',
br: 'startTagVoidFormatting',
embed: 'startTagVoidFormatting',
img: 'startTagVoidFormatting',
keygen: 'startTagVoidFormatting',
wbr: 'startTagVoidFormatting',
param: 'startTagParamSourceTrack',
source: 'startTagParamSourceTrack',
track: 'startTagParamSourceTrack',
iframe: 'startTagIFrame',
noembed: 'startTagRawText',
noscript: 'startTagRawText',
h1: 'startTagHeading',
h2: 'startTagHeading',
h3: 'startTagHeading',
h4: 'startTagHeading',
h5: 'startTagHeading',
h6: 'startTagHeading',
caption: 'startTagMisplaced',
col: 'startTagMisplaced',
colgroup: 'startTagMisplaced',
frame: 'startTagMisplaced',
frameset: 'startTagFrameset',
tbody: 'startTagMisplaced',
td: 'startTagMisplaced',
tfoot: 'startTagMisplaced',
th: 'startTagMisplaced',
thead: 'startTagMisplaced',
tr: 'startTagMisplaced',
option: 'startTagOptionOptgroup',
optgroup: 'startTagOptionOptgroup',
math: 'startTagMath',
svg: 'startTagSVG',
rt: 'startTagRpRt',
rp: 'startTagRpRt',
"-default": 'startTagOther'
};
modes.inBody.end_tag_handlers = {
p: 'endTagP',
body: 'endTagBody',
html: 'endTagHtml',
address: 'endTagBlock',
article: 'endTagBlock',
aside: 'endTagBlock',
blockquote: 'endTagBlock',
button: 'endTagBlock',
center: 'endTagBlock',
details: 'endTagBlock',
dir: 'endTagBlock',
div: 'endTagBlock',
dl: 'endTagBlock',
fieldset: 'endTagBlock',
figcaption: 'endTagBlock',
figure: 'endTagBlock',
footer: 'endTagBlock',
header: 'endTagBlock',
hgroup: 'endTagBlock',
listing: 'endTagBlock',
main: 'endTagBlock',
menu: 'endTagBlock',
nav: 'endTagBlock',
ol: 'endTagBlock',
pre: 'endTagBlock',
section: 'endTagBlock',
summary: 'endTagBlock',
ul: 'endTagBlock',
form: 'endTagForm',
applet: 'endTagAppletMarqueeObject',
marquee: 'endTagAppletMarqueeObject',
object: 'endTagAppletMarqueeObject',
dd: 'endTagListItem',
dt: 'endTagListItem',
li: 'endTagListItem',
h1: 'endTagHeading',
h2: 'endTagHeading',
h3: 'endTagHeading',
h4: 'endTagHeading',
h5: 'endTagHeading',
h6: 'endTagHeading',
a: 'endTagFormatting',
b: 'endTagFormatting',
big: 'endTagFormatting',
code: 'endTagFormatting',
em: 'endTagFormatting',
font: 'endTagFormatting',
i: 'endTagFormatting',
nobr: 'endTagFormatting',
s: 'endTagFormatting',
small: 'endTagFormatting',
strike: 'endTagFormatting',
strong: 'endTagFormatting',
tt: 'endTagFormatting',
u: 'endTagFormatting',
br: 'endTagBr',
"-default": 'endTagOther'
};
modes.inBody.processCharacters = function(buffer) {
if (tree.shouldSkipLeadingNewline) {
tree.shouldSkipLeadingNewline = false;
buffer.skipAtMostOneLeadingNewline();
}
tree.reconstructActiveFormattingElements();
var characters = buffer.takeRemaining();
characters = characters.replace(/\u0000/g, function(match, index){
tree.parseError("invalid-codepoint");
return '';
});
if (!characters)
return;
tree.insertText(characters);
if (tree.framesetOk && !isAllWhitespaceOrReplacementCharacters(characters))
tree.framesetOk = false;
};
modes.inBody.startTagHtml = function(name, attributes) {
tree.parseError('non-html-root');
tree.addAttributesToElement(tree.openElements.rootNode, attributes);
};
modes.inBody.startTagProcessInHead = function(name, attributes) {
modes.inHead.processStartTag(name, attributes);
};
modes.inBody.startTagBody = function(name, attributes) {
tree.parseError('unexpected-start-tag', {name: 'body'});
if (tree.openElements.length == 1 ||
tree.openElements.item(1).localName != 'body') {
assert.ok(tree.context);
} else {
tree.framesetOk = false;
tree.addAttributesToElement(tree.openElements.bodyElement, attributes);
}
};
modes.inBody.startTagFrameset = function(name, attributes) {
tree.parseError('unexpected-start-tag', {name: 'frameset'});
if (tree.openElements.length == 1 ||
tree.openElements.item(1).localName != 'body') {
assert.ok(tree.context);
} else if (tree.framesetOk) {
tree.detachFromParent(tree.openElements.bodyElement);
while (tree.openElements.length > 1)
tree.openElements.pop();
tree.insertElement(name, attributes);
tree.setInsertionMode('inFrameset');
}
};
modes.inBody.startTagCloseP = function(name, attributes) {
if (tree.openElements.inButtonScope('p'))
this.endTagP('p');
tree.insertElement(name, attributes);
};
modes.inBody.startTagPreListing = function(name, attributes) {
if (tree.openElements.inButtonScope('p'))
this.endTagP('p');
tree.insertElement(name, attributes);
tree.framesetOk = false;
tree.shouldSkipLeadingNewline = true;
};
modes.inBody.startTagForm = function(name, attributes) {
if (tree.form) {
tree.parseError('unexpected-start-tag', {name: name});
} else {
if (tree.openElements.inButtonScope('p'))
this.endTagP('p');
tree.insertElement(name, attributes);
tree.form = tree.currentStackItem();
}
};
modes.inBody.startTagRpRt = function(name, attributes) {
if (tree.openElements.inScope('ruby')) {
tree.generateImpliedEndTags();
if (tree.currentStackItem().localName != 'ruby') {
tree.parseError('unexpected-start-tag', {name: name});
}
}
tree.insertElement(name, attributes);
};
modes.inBody.startTagListItem = function(name, attributes) {
var stopNames = {li: ['li'], dd: ['dd', 'dt'], dt: ['dd', 'dt']};
var stopName = stopNames[name];
var els = tree.openElements;
for (var i = els.length - 1; i >= 0; i--) {
var node = els.item(i);
if (stopName.indexOf(node.localName) != -1) {
tree.insertionMode.processEndTag(node.localName);
break;
}
if (node.isSpecial() && node.localName !== 'p' && node.localName !== 'address' && node.localName !== 'div')
break;
}
if (tree.openElements.inButtonScope('p'))
this.endTagP('p');
tree.insertElement(name, attributes);
tree.framesetOk = false;
};
modes.inBody.startTagPlaintext = function(name, attributes) {
if (tree.openElements.inButtonScope('p'))
this.endTagP('p');
tree.insertElement(name, attributes);
tree.tokenizer.setState(Tokenizer.PLAINTEXT);
};
modes.inBody.startTagHeading = function(name, attributes) {
if (tree.openElements.inButtonScope('p'))
this.endTagP('p');
if (tree.currentStackItem().isNumberedHeader()) {
tree.parseError('unexpected-start-tag', {name: name});
tree.popElement();
}
tree.insertElement(name, attributes);
};
modes.inBody.startTagA = function(name, attributes) {
var activeA = tree.elementInActiveFormattingElements('a');
if (activeA) {
tree.parseError("unexpected-start-tag-implies-end-tag", {startName: "a", endName: "a"});
tree.adoptionAgencyEndTag('a');
if (tree.openElements.contains(activeA))
tree.openElements.remove(activeA);
tree.removeElementFromActiveFormattingElements(activeA);
}
tree.reconstructActiveFormattingElements();
tree.insertFormattingElement(name, attributes);
};
modes.inBody.startTagFormatting = function(name, attributes) {
tree.reconstructActiveFormattingElements();
tree.insertFormattingElement(name, attributes);
};
modes.inBody.startTagNobr = function(name, attributes) {
tree.reconstructActiveFormattingElements();
if (tree.openElements.inScope('nobr')) {
tree.parseError("unexpected-start-tag-implies-end-tag", {startName: 'nobr', endName: 'nobr'});
this.processEndTag('nobr');
tree.reconstructActiveFormattingElements();
}
tree.insertFormattingElement(name, attributes);
};
modes.inBody.startTagButton = function(name, attributes) {
if (tree.openElements.inScope('button')) {
tree.parseError('unexpected-start-tag-implies-end-tag', {startName: 'button', endName: 'button'});
this.processEndTag('button');
tree.insertionMode.processStartTag(name, attributes);
} else {
tree.framesetOk = false;
tree.reconstructActiveFormattingElements();
tree.insertElement(name, attributes);
}
};
modes.inBody.startTagAppletMarqueeObject = function(name, attributes) {
tree.reconstructActiveFormattingElements();
tree.insertElement(name, attributes);
tree.activeFormattingElements.push(Marker);
tree.framesetOk = false;
};
modes.inBody.endTagAppletMarqueeObject = function(name) {
if (!tree.openElements.inScope(name)) {
tree.parseError("unexpected-end-tag", {name: name});
} else {
tree.generateImpliedEndTags();
if (tree.currentStackItem().localName != name) {
tree.parseError('end-tag-too-early', {name: name});
}
tree.openElements.popUntilPopped(name);
tree.clearActiveFormattingElements();
}
};
modes.inBody.startTagXmp = function(name, attributes) {
if (tree.openElements.inButtonScope('p'))
this.processEndTag('p');
tree.reconstructActiveFormattingElements();
tree.processGenericRawTextStartTag(name, attributes);
tree.framesetOk = false;
};
modes.inBody.startTagTable = function(name, attributes) {
if (tree.compatMode !== "quirks")
if (tree.openElements.inButtonScope('p'))
this.processEndTag('p');
tree.insertElement(name, attributes);
tree.setInsertionMode('inTable');
tree.framesetOk = false;
};
modes.inBody.startTagVoidFormatting = function(name, attributes) {
tree.reconstructActiveFormattingElements();
tree.insertSelfClosingElement(name, attributes);
tree.framesetOk = false;
};
modes.inBody.startTagParamSourceTrack = function(name, attributes) {
tree.insertSelfClosingElement(name, attributes);
};
modes.inBody.startTagHr = function(name, attributes) {
if (tree.openElements.inButtonScope('p'))
this.endTagP('p');
tree.insertSelfClosingElement(name, attributes);
tree.framesetOk = false;
};
modes.inBody.startTagImage = function(name, attributes) {
tree.parseError('unexpected-start-tag-treated-as', {originalName: 'image', newName: 'img'});
this.processStartTag('img', attributes);
};
modes.inBody.startTagInput = function(name, attributes) {
var currentFramesetOk = tree.framesetOk;
this.startTagVoidFormatting(name, attributes);
for (var key in attributes) {
if (attributes[key].nodeName == 'type') {
if (attributes[key].nodeValue.toLowerCase() == 'hidden')
tree.framesetOk = currentFramesetOk;
break;
}
}
};
modes.inBody.startTagIsindex = function(name, attributes) {
tree.parseError('deprecated-tag', {name: 'isindex'});
tree.selfClosingFlagAcknowledged = true;
if (tree.form)
return;
var formAttributes = [];
var inputAttributes = [];
var prompt = "This is a searchable index. Enter search keywords: ";
for (var key in attributes) {
switch (attributes[key].nodeName) {
case 'action':
formAttributes.push({nodeName: 'action',
nodeValue: attributes[key].nodeValue});
break;
case 'prompt':
prompt = attributes[key].nodeValue;
break;
case 'name':
break;
default:
inputAttributes.push({nodeName: attributes[key].nodeName,
nodeValue: attributes[key].nodeValue});
}
}
inputAttributes.push({nodeName: 'name', nodeValue: 'isindex'});
this.processStartTag('form', formAttributes);
this.processStartTag('hr');
this.processStartTag('label');
this.processCharacters(new CharacterBuffer(prompt));
this.processStartTag('input', inputAttributes);
this.processEndTag('label');
this.processStartTag('hr');
this.processEndTag('form');
};
modes.inBody.startTagTextarea = function(name, attributes) {
tree.insertElement(name, attributes);
tree.tokenizer.setState(Tokenizer.RCDATA);
tree.originalInsertionMode = tree.insertionModeName;
tree.shouldSkipLeadingNewline = true;
tree.framesetOk = false;
tree.setInsertionMode('text');
};
modes.inBody.startTagIFrame = function(name, attributes) {
tree.framesetOk = false;
this.startTagRawText(name, attributes);
};
modes.inBody.startTagRawText = function(name, attributes) {
tree.processGenericRawTextStartTag(name, attributes);
};
modes.inBody.startTagSelect = function(name, attributes) {
tree.reconstructActiveFormattingElements();
tree.insertElement(name, attributes);
tree.framesetOk = false;
var insertionModeName = tree.insertionModeName;
if (insertionModeName == 'inTable' ||
insertionModeName == 'inCaption' ||
insertionModeName == 'inColumnGroup' ||
insertionModeName == 'inTableBody' ||
insertionModeName == 'inRow' ||
insertionModeName == 'inCell') {
tree.setInsertionMode('inSelectInTable');
} else {
tree.setInsertionMode('inSelect');
}
};
modes.inBody.startTagMisplaced = function(name, attributes) {
tree.parseError('unexpected-start-tag-ignored', {name: name});
};
modes.inBody.endTagMisplaced = function(name) {
tree.parseError("unexpected-end-tag", {name: name});
};
modes.inBody.endTagBr = function(name) {
tree.parseError("unexpected-end-tag-treated-as", {originalName: "br", newName: "br element"});
tree.reconstructActiveFormattingElements();
tree.insertElement(name, []);
tree.popElement();
};
modes.inBody.startTagOptionOptgroup = function(name, attributes) {
if (tree.currentStackItem().localName == 'option')
tree.popElement();
tree.reconstructActiveFormattingElements();
tree.insertElement(name, attributes);
};
modes.inBody.startTagOther = function(name, attributes) {
tree.reconstructActiveFormattingElements();
tree.insertElement(name, attributes);
};
modes.inBody.endTagOther = function(name) {
var node;
for (var i = tree.openElements.length - 1; i > 0; i--) {
node = tree.openElements.item(i);
if (node.localName == name) {
tree.generateImpliedEndTags(name);
if (tree.currentStackItem().localName != name)
tree.parseError('unexpected-end-tag', {name: name});
tree.openElements.remove_openElements_until(function(x) {return x === node;});
break;
}
if (node.isSpecial()) {
tree.parseError('unexpected-end-tag', {name: name});
break;
}
}
};
modes.inBody.startTagMath = function(name, attributes, selfClosing) {
tree.reconstructActiveFormattingElements();
attributes = tree.adjustMathMLAttributes(attributes);
attributes = tree.adjustForeignAttributes(attributes);
tree.insertForeignElement(name, attributes, "http://www.w3.org/1998/Math/MathML", selfClosing);
};
modes.inBody.startTagSVG = function(name, attributes, selfClosing) {
tree.reconstructActiveFormattingElements();
attributes = tree.adjustSVGAttributes(attributes);
attributes = tree.adjustForeignAttributes(attributes);
tree.insertForeignElement(name, attributes, "http://www.w3.org/2000/svg", selfClosing);
};
modes.inBody.endTagP = function(name) {
if (!tree.openElements.inButtonScope('p')) {
tree.parseError('unexpected-end-tag', {name: 'p'});
this.startTagCloseP('p', []);
this.endTagP('p');
} else {
tree.generateImpliedEndTags('p');
if (tree.currentStackItem().localName != 'p')
tree.parseError('unexpected-implied-end-tag', {name: 'p'});
tree.openElements.popUntilPopped(name);
}
};
modes.inBody.endTagBody = function(name) {
if (!tree.openElements.inScope('body')) {
tree.parseError('unexpected-end-tag', {name: name});
return;
}
if (tree.currentStackItem().localName != 'body') {
tree.parseError('expected-one-end-tag-but-got-another', {
expectedName: tree.currentStackItem().localName,
gotName: name
});
}
tree.setInsertionMode('afterBody');
};
modes.inBody.endTagHtml = function(name) {
if (!tree.openElements.inScope('body')) {
tree.parseError('unexpected-end-tag', {name: name});
return;
}
if (tree.currentStackItem().localName != 'body') {
tree.parseError('expected-one-end-tag-but-got-another', {
expectedName: tree.currentStackItem().localName,
gotName: name
});
}
tree.setInsertionMode('afterBody');
tree.insertionMode.processEndTag(name);
};
modes.inBody.endTagBlock = function(name) {
if (!tree.openElements.inScope(name)) {
tree.parseError('unexpected-end-tag', {name: name});
} else {
tree.generateImpliedEndTags();
if (tree.currentStackItem().localName != name) {
tree.parseError('end-tag-too-early', {name: name});
}
tree.openElements.popUntilPopped(name);
}
};
modes.inBody.endTagForm = function(name) {
var node = tree.form;
tree.form = null;
if (!node || !tree.openElements.inScope(name)) {
tree.parseError('unexpected-end-tag', {name: name});
} else {
tree.generateImpliedEndTags();
if (tree.currentStackItem() != node) {
tree.parseError('end-tag-too-early-ignored', {name: 'form'});
}
tree.openElements.remove(node);
}
};
modes.inBody.endTagListItem = function(name) {
if (!tree.openElements.inListItemScope(name)) {
tree.parseError('unexpected-end-tag', {name: name});
} else {
tree.generateImpliedEndTags(name);
if (tree.currentStackItem().localName != name)
tree.parseError('end-tag-too-early', {name: name});
tree.openElements.popUntilPopped(name);
}
};
modes.inBody.endTagHeading = function(name) {
if (!tree.openElements.hasNumberedHeaderElementInScope()) {
tree.parseError('unexpected-end-tag', {name: name});
return;
}
tree.generateImpliedEndTags();
if (tree.currentStackItem().localName != name)
tree.parseError('end-tag-too-early', {name: name});
tree.openElements.remove_openElements_until(function(e) {
return e.isNumberedHeader();
});
};
modes.inBody.endTagFormatting = function(name, attributes) {
if (!tree.adoptionAgencyEndTag(name))
this.endTagOther(name, attributes);
};
modes.inCaption = Object.create(modes.base);
modes.inCaption.start_tag_handlers = {
html: 'startTagHtml',
caption: 'startTagTableElement',
col: 'startTagTableElement',
colgroup: 'startTagTableElement',
tbody: 'startTagTableElement',
td: 'startTagTableElement',
tfoot: 'startTagTableElement',
thead: 'startTagTableElement',
tr: 'startTagTableElement',
'-default': 'startTagOther'
};
modes.inCaption.end_tag_handlers = {
caption: 'endTagCaption',
table: 'endTagTable',
body: 'endTagIgnore',
col: 'endTagIgnore',
colgroup: 'endTagIgnore',
html: 'endTagIgnore',
tbody: 'endTagIgnore',
td: 'endTagIgnore',
tfood: 'endTagIgnore',
thead: 'endTagIgnore',
tr: 'endTagIgnore',
'-default': 'endTagOther'
};
modes.inCaption.processCharacters = function(data) {
modes.inBody.processCharacters(data);
};
modes.inCaption.startTagTableElement = function(name, attributes) {
tree.parseError('unexpected-end-tag', {name: name});
var ignoreEndTag = !tree.openElements.inTableScope('caption');
tree.insertionMode.processEndTag('caption');
if (!ignoreEndTag) tree.insertionMode.processStartTag(name, attributes);
};
modes.inCaption.startTagOther = function(name, attributes, selfClosing) {
modes.inBody.processStartTag(name, attributes, selfClosing);
};
modes.inCaption.endTagCaption = function(name) {
if (!tree.openElements.inTableScope('caption')) {
assert.ok(tree.context);
tree.parseError('unexpected-end-tag', {name: name});
} else {
tree.generateImpliedEndTags();
if (tree.currentStackItem().localName != 'caption') {
tree.parseError('expected-one-end-tag-but-got-another', {
gotName: "caption",
expectedName: tree.currentStackItem().localName
});
}
tree.openElements.popUntilPopped('caption');
tree.clearActiveFormattingElements();
tree.setInsertionMode('inTable');
}
};
modes.inCaption.endTagTable = function(name) {
tree.parseError("unexpected-end-table-in-caption");
var ignoreEndTag = !tree.openElements.inTableScope('caption');
tree.insertionMode.processEndTag('caption');
if (!ignoreEndTag) tree.insertionMode.processEndTag(name);
};
modes.inCaption.endTagIgnore = function(name) {
tree.parseError('unexpected-end-tag', {name: name});
};
modes.inCaption.endTagOther = function(name) {
modes.inBody.processEndTag(name);
};
modes.inCell = Object.create(modes.base);
modes.inCell.start_tag_handlers = {
html: 'startTagHtml',
caption: 'startTagTableOther',
col: 'startTagTableOther',
colgroup: 'startTagTableOther',
tbody: 'startTagTableOther',
td: 'startTagTableOther',
tfoot: 'startTagTableOther',
th: 'startTagTableOther',
thead: 'startTagTableOther',
tr: 'startTagTableOther',
'-default': 'startTagOther'
};
modes.inCell.end_tag_handlers = {
td: 'endTagTableCell',
th: 'endTagTableCell',
body: 'endTagIgnore',
caption: 'endTagIgnore',
col: 'endTagIgnore',
colgroup: 'endTagIgnore',
html: 'endTagIgnore',
table: 'endTagImply',
tbody: 'endTagImply',
tfoot: 'endTagImply',
thead: 'endTagImply',
tr: 'endTagImply',
'-default': 'endTagOther'
};
modes.inCell.processCharacters = function(data) {
modes.inBody.processCharacters(data);
};
modes.inCell.startTagTableOther = function(name, attributes, selfClosing) {
if (tree.openElements.inTableScope('td') || tree.openElements.inTableScope('th')) {
this.closeCell();
tree.insertionMode.processStartTag(name, attributes, selfClosing);
} else {
tree.parseError('unexpected-start-tag', {name: name});
}
};
modes.inCell.startTagOther = function(name, attributes, selfClosing) {
modes.inBody.processStartTag(name, attributes, selfClosing);
};
modes.inCell.endTagTableCell = function(name) {
if (tree.openElements.inTableScope(name)) {
tree.generateImpliedEndTags(name);
if (tree.currentStackItem().localName != name.toLowerCase()) {
tree.parseError('unexpected-cell-end-tag', {name: name});
tree.openElements.popUntilPopped(name);
} else {
tree.popElement();
}
tree.clearActiveFormattingElements();
tree.setInsertionMode('inRow');
} else {
tree.parseError('unexpected-end-tag', {name: name});
}
};
modes.inCell.endTagIgnore = function(name) {
tree.parseError('unexpected-end-tag', {name: name});
};
modes.inCell.endTagImply = function(name) {
if (tree.openElements.inTableScope(name)) {
this.closeCell();
tree.insertionMode.processEndTag(name);
} else {
tree.parseError('unexpected-end-tag', {name: name});
}
};
modes.inCell.endTagOther = function(name) {
modes.inBody.processEndTag(name);
};
modes.inCell.closeCell = function() {
if (tree.openElements.inTableScope('td')) {
this.endTagTableCell('td');
} else if (tree.openElements.inTableScope('th')) {
this.endTagTableCell('th');
}
};
modes.inColumnGroup = Object.create(modes.base);
modes.inColumnGroup.start_tag_handlers = {
html: 'startTagHtml',
col: 'startTagCol',
'-default': 'startTagOther'
};
modes.inColumnGroup.end_tag_handlers = {
colgroup: 'endTagColgroup',
col: 'endTagCol',
'-default': 'endTagOther'
};
modes.inColumnGroup.ignoreEndTagColgroup = function() {
return tree.currentStackItem().localName == 'html';
};
modes.inColumnGroup.processCharacters = function(buffer) {
var leadingWhitespace = buffer.takeLeadingWhitespace();
if (leadingWhitespace)
tree.insertText(leadingWhitespace);
if (!buffer.length)
return;
var ignoreEndTag = this.ignoreEndTagColgroup();
this.endTagColgroup('colgroup');
if (!ignoreEndTag) tree.insertionMode.processCharacters(buffer);
};
modes.inColumnGroup.startTagCol = function(name, attributes) {
tree.insertSelfClosingElement(name, attributes);
};
modes.inColumnGroup.startTagOther = function(name, attributes, selfClosing) {
var ignoreEndTag = this.ignoreEndTagColgroup();
this.endTagColgroup('colgroup');
if (!ignoreEndTag) tree.insertionMode.processStartTag(name, attributes, selfClosing);
};
modes.inColumnGroup.endTagColgroup = function(name) {
if (this.ignoreEndTagColgroup()) {
assert.ok(tree.context);
tree.parseError('unexpected-end-tag', {name: name});
} else {
tree.popElement();
tree.setInsertionMode('inTable');
}
};
modes.inColumnGroup.endTagCol = function(name) {
tree.parseError("no-end-tag", {name: 'col'});
};
modes.inColumnGroup.endTagOther = function(name) {
var ignoreEndTag = this.ignoreEndTagColgroup();
this.endTagColgroup('colgroup');
if (!ignoreEndTag) tree.insertionMode.processEndTag(name) ;
};
modes.inForeignContent = Object.create(modes.base);
modes.inForeignContent.processStartTag = function(name, attributes, selfClosing) {
if (['b', 'big', 'blockquote', 'body', 'br', 'center', 'code', 'dd', 'div', 'dl', 'dt', 'em', 'embed', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'i', 'img', 'li', 'listing', 'menu', 'meta', 'nobr', 'ol', 'p', 'pre', 'ruby', 's', 'small', 'span', 'strong', 'strike', 'sub', 'sup', 'table', 'tt', 'u', 'ul', 'var'].indexOf(name) != -1
|| (name == 'font' && attributes.some(function(attr){ return ['color', 'face', 'size'].indexOf(attr.nodeName) >= 0 }))) {
tree.parseError('unexpected-html-element-in-foreign-content', {name: name});
while (tree.currentStackItem().isForeign()
&& !tree.currentStackItem().isHtmlIntegrationPoint()
&& !tree.currentStackItem().isMathMLTextIntegrationPoint()) {
tree.openElements.pop();
}
tree.insertionMode.processStartTag(name, attributes, selfClosing);
return;
}
if (tree.currentStackItem().namespaceURI == "http://www.w3.org/1998/Math/MathML") {
attributes = tree.adjustMathMLAttributes(attributes);
}
if (tree.currentStackItem().namespaceURI == "http://www.w3.org/2000/svg") {
name = tree.adjustSVGTagNameCase(name);
attributes = tree.adjustSVGAttributes(attributes);
}
attributes = tree.adjustForeignAttributes(attributes);
tree.insertForeignElement(name, attributes, tree.currentStackItem().namespaceURI, selfClosing);
};
modes.inForeignContent.processEndTag = function(name) {
var node = tree.currentStackItem();
var index = tree.openElements.length - 1;
if (node.localName.toLowerCase() != name)
tree.parseError("unexpected-end-tag", {name: name});
while (true) {
if (index === 0)
break;
if (node.localName.toLowerCase() == name) {
while (tree.openElements.pop() != node);
break;
}
index -= 1;
node = tree.openElements.item(index);
if (node.isForeign()) {
continue;
} else {
tree.insertionMode.processEndTag(name);
break;
}
}
};
modes.inForeignContent.processCharacters = function(buffer) {
var characters = buffer.takeRemaining();
characters = characters.replace(/\u0000/g, function(match, index){
tree.parseError('invalid-codepoint');
return '\uFFFD';
});
if (tree.framesetOk && !isAllWhitespaceOrReplacementCharacters(characters))
tree.framesetOk = false;
tree.insertText(characters);
};
modes.inHeadNoscript = Object.create(modes.base);
modes.inHeadNoscript.start_tag_handlers = {
html: 'startTagHtml',
basefont: 'startTagBasefontBgsoundLinkMetaNoframesStyle',
bgsound: 'startTagBasefontBgsoundLinkMetaNoframesStyle',
link: 'startTagBasefontBgsoundLinkMetaNoframesStyle',
meta: 'startTagBasefontBgsoundLinkMetaNoframesStyle',
noframes: 'startTagBasefontBgsoundLinkMetaNoframesStyle',
style: 'startTagBasefontBgsoundLinkMetaNoframesStyle',
head: 'startTagHeadNoscript',
noscript: 'startTagHeadNoscript',
"-default": 'startTagOther'
};
modes.inHeadNoscript.end_tag_handlers = {
noscript: 'endTagNoscript',
br: 'endTagBr',
'-default': 'endTagOther'
};
modes.inHeadNoscript.processCharacters = function(buffer) {
var leadingWhitespace = buffer.takeLeadingWhitespace();
if (leadingWhitespace)
tree.insertText(leadingWhitespace);
if (!buffer.length)
return;
tree.parseError("unexpected-char-in-frameset");
this.anythingElse();
tree.insertionMode.processCharacters(buffer);
};
modes.inHeadNoscript.processComment = function(data) {
modes.inHead.processComment(data);
};
modes.inHeadNoscript.startTagBasefontBgsoundLinkMetaNoframesStyle = function(name, attributes) {
modes.inHead.processStartTag(name, attributes);
};
modes.inHeadNoscript.startTagHeadNoscript = function(name, attributes) {
tree.parseError("unexpected-start-tag-in-frameset", {name: name});
};
modes.inHeadNoscript.startTagOther = function(name, attributes) {
tree.parseError("unexpected-start-tag-in-frameset", {name: name});
this.anythingElse();
tree.insertionMode.processStartTag(name, attributes);
};
modes.inHeadNoscript.endTagBr = function(name, attributes) {
tree.parseError("unexpected-end-tag-in-frameset", {name: name});
this.anythingElse();
tree.insertionMode.processEndTag(name, attributes);
};
modes.inHeadNoscript.endTagNoscript = function(name, attributes) {
tree.popElement();
tree.setInsertionMode('inHead');
};
modes.inHeadNoscript.endTagOther = function(name, attributes) {
tree.parseError("unexpected-end-tag-in-frameset", {name: name});
};
modes.inHeadNoscript.anythingElse = function() {
tree.popElement();
tree.setInsertionMode('inHead');
};
modes.inFrameset = Object.create(modes.base);
modes.inFrameset.start_tag_handlers = {
html: 'startTagHtml',
frameset: 'startTagFrameset',
frame: 'startTagFrame',
noframes: 'startTagNoframes',
"-default": 'startTagOther'
};
modes.inFrameset.end_tag_handlers = {
frameset: 'endTagFrameset',
noframes: 'endTagNoframes',
'-default': 'endTagOther'
};
modes.inFrameset.processCharacters = function(data) {
tree.parseError("unexpected-char-in-frameset");
};
modes.inFrameset.startTagFrameset = function(name, attributes) {
tree.insertElement(name, attributes);
};
modes.inFrameset.startTagFrame = function(name, attributes) {
tree.insertSelfClosingElement(name, attributes);
};
modes.inFrameset.startTagNoframes = function(name, attributes) {
modes.inBody.processStartTag(name, attributes);
};
modes.inFrameset.startTagOther = function(name, attributes) {
tree.parseError("unexpected-start-tag-in-frameset", {name: name});
};
modes.inFrameset.endTagFrameset = function(name, attributes) {
if (tree.currentStackItem().localName == 'html') {
tree.parseError("unexpected-frameset-in-frameset-innerhtml");
} else {
tree.popElement();
}
if (!tree.context && tree.currentStackItem().localName != 'frameset') {
tree.setInsertionMode('afterFrameset');
}
};
modes.inFrameset.endTagNoframes = function(name) {
modes.inBody.processEndTag(name);
};
modes.inFrameset.endTagOther = function(name) {
tree.parseError("unexpected-end-tag-in-frameset", {name: name});
};
modes.inTable = Object.create(modes.base);
modes.inTable.start_tag_handlers = {
html: 'startTagHtml',
caption: 'startTagCaption',
colgroup: 'startTagColgroup',
col: 'startTagCol',
table: 'startTagTable',
tbody: 'startTagRowGroup',
tfoot: 'startTagRowGroup',
thead: 'startTagRowGroup',
td: 'startTagImplyTbody',
th: 'startTagImplyTbody',
tr: 'startTagImplyTbody',
style: 'startTagStyleScript',
script: 'startTagStyleScript',
input: 'startTagInput',
form: 'startTagForm',
'-default': 'startTagOther'
};
modes.inTable.end_tag_handlers = {
table: 'endTagTable',
body: 'endTagIgnore',
caption: 'endTagIgnore',
col: 'endTagIgnore',
colgroup: 'endTagIgnore',
html: 'endTagIgnore',
tbody: 'endTagIgnore',
td: 'endTagIgnore',
tfoot: 'endTagIgnore',
th: 'endTagIgnore',
thead: 'endTagIgnore',
tr: 'endTagIgnore',
'-default': 'endTagOther'
};
modes.inTable.processCharacters = function(data) {
if (tree.currentStackItem().isFosterParenting()) {
var originalInsertionMode = tree.insertionModeName;
tree.setInsertionMode('inTableText');
tree.originalInsertionMode = originalInsertionMode;
tree.insertionMode.processCharacters(data);
} else {
tree.redirectAttachToFosterParent = true;
modes.inBody.processCharacters(data);
tree.redirectAttachToFosterParent = false;
}
};
modes.inTable.startTagCaption = function(name, attributes) {
tree.openElements.popUntilTableScopeMarker();
tree.activeFormattingElements.push(Marker);
tree.insertElement(name, attributes);
tree.setInsertionMode('inCaption');
};
modes.inTable.startTagColgroup = function(name, attributes) {
tree.openElements.popUntilTableScopeMarker();
tree.insertElement(name, attributes);
tree.setInsertionMode('inColumnGroup');
};
modes.inTable.startTagCol = function(name, attributes) {
this.startTagColgroup('colgroup', []);
tree.insertionMode.processStartTag(name, attributes);
};
modes.inTable.startTagRowGroup = function(name, attributes) {
tree.openElements.popUntilTableScopeMarker();
tree.insertElement(name, attributes);
tree.setInsertionMode('inTableBody');
};
modes.inTable.startTagImplyTbody = function(name, attributes) {
this.startTagRowGroup('tbody', []);
tree.insertionMode.processStartTag(name, attributes);
};
modes.inTable.startTagTable = function(name, attributes) {
tree.parseError("unexpected-start-tag-implies-end-tag",
{startName: "table", endName: "table"});
tree.insertionMode.processEndTag('table');
if (!tree.context) tree.insertionMode.processStartTag(name, attributes);
};
modes.inTable.startTagStyleScript = function(name, attributes) {
modes.inHead.processStartTag(name, attributes);
};
modes.inTable.startTagInput = function(name, attributes) {
for (var key in attributes) {
if (attributes[key].nodeName.toLowerCase() == 'type') {
if (attributes[key].nodeValue.toLowerCase() == 'hidden') {
tree.parseError("unexpected-hidden-input-in-table");
tree.insertElement(name, attributes);
tree.openElements.pop();
return;
}
break;
}
}
this.startTagOther(name, attributes);
};
modes.inTable.startTagForm = function(name, attributes) {
tree.parseError("unexpected-form-in-table");
if (!tree.form) {
tree.insertElement(name, attributes);
tree.form = tree.currentStackItem();
tree.openElements.pop();
}
};
modes.inTable.startTagOther = function(name, attributes, selfClosing) {
tree.parseError("unexpected-start-tag-implies-table-voodoo", {name: name});
tree.redirectAttachToFosterParent = true;
modes.inBody.processStartTag(name, attributes, selfClosing);
tree.redirectAttachToFosterParent = false;
};
modes.inTable.endTagTable = function(name) {
if (tree.openElements.inTableScope(name)) {
tree.generateImpliedEndTags();
if (tree.currentStackItem().localName != name) {
tree.parseError("end-tag-too-early-named", {gotName: 'table', expectedName: tree.currentStackItem().localName});
}
tree.openElements.popUntilPopped('table');
tree.resetInsertionMode();
} else {
assert.ok(tree.context);
tree.parseError('unexpected-end-tag', {name: name});
}
};
modes.inTable.endTagIgnore = function(name) {
tree.parseError("unexpected-end-tag", {name: name});
};
modes.inTable.endTagOther = function(name) {
tree.parseError("unexpected-end-tag-implies-table-voodoo", {name: name});
tree.redirectAttachToFosterParent = true;
modes.inBody.processEndTag(name);
tree.redirectAttachToFosterParent = false;
};
modes.inTableText = Object.create(modes.base);
modes.inTableText.flushCharacters = function() {
var characters = tree.pendingTableCharacters.join('');
if (!isAllWhitespace(characters)) {
tree.redirectAttachToFosterParent = true;
tree.reconstructActiveFormattingElements();
tree.insertText(characters);
tree.framesetOk = false;
tree.redirectAttachToFosterParent = false;
} else {
tree.insertText(characters);
}
tree.pendingTableCharacters = [];
};
modes.inTableText.processComment = function(data) {
this.flushCharacters();
tree.setInsertionMode(tree.originalInsertionMode);
tree.insertionMode.processComment(data);
};
modes.inTableText.processEOF = function(data) {
this.flushCharacters();
tree.setInsertionMode(tree.originalInsertionMode);
tree.insertionMode.processEOF();
};
modes.inTableText.processCharacters = function(buffer) {
var characters = buffer.takeRemaining();
characters = characters.replace(/\u0000/g, function(match, index){
tree.parseError("invalid-codepoint");
return '';
});
if (!characters)
return;
tree.pendingTableCharacters.push(characters);
};
modes.inTableText.processStartTag = function(name, attributes, selfClosing) {
this.flushCharacters();
tree.setInsertionMode(tree.originalInsertionMode);
tree.insertionMode.processStartTag(name, attributes, selfClosing);
};
modes.inTableText.processEndTag = function(name, attributes) {
this.flushCharacters();
tree.setInsertionMode(tree.originalInsertionMode);
tree.insertionMode.processEndTag(name, attributes);
};
modes.inTableBody = Object.create(modes.base);
modes.inTableBody.start_tag_handlers = {
html: 'startTagHtml',
tr: 'startTagTr',
td: 'startTagTableCell',
th: 'startTagTableCell',
caption: 'startTagTableOther',
col: 'startTagTableOther',
colgroup: 'startTagTableOther',
tbody: 'startTagTableOther',
tfoot: 'startTagTableOther',
thead: 'startTagTableOther',
'-default': 'startTagOther'
};
modes.inTableBody.end_tag_handlers = {
table: 'endTagTable',
tbody: 'endTagTableRowGroup',
tfoot: 'endTagTableRowGroup',
thead: 'endTagTableRowGroup',
body: 'endTagIgnore',
caption: 'endTagIgnore',
col: 'endTagIgnore',
colgroup: 'endTagIgnore',
html: 'endTagIgnore',
td: 'endTagIgnore',
th: 'endTagIgnore',
tr: 'endTagIgnore',
'-default': 'endTagOther'
};
modes.inTableBody.processCharacters = function(data) {
modes.inTable.processCharacters(data);
};
modes.inTableBody.startTagTr = function(name, attributes) {
tree.openElements.popUntilTableBodyScopeMarker();
tree.insertElement(name, attributes);
tree.setInsertionMode('inRow');
};
modes.inTableBody.startTagTableCell = function(name, attributes) {
tree.parseError("unexpected-cell-in-table-body", {name: name});
this.startTagTr('tr', []);
tree.insertionMode.processStartTag(name, attributes);
};
modes.inTableBody.startTagTableOther = function(name, attributes) {
if (tree.openElements.inTableScope('tbody') || tree.openElements.inTableScope('thead') || tree.openElements.inTableScope('tfoot')) {
tree.openElements.popUntilTableBodyScopeMarker();
this.endTagTableRowGroup(tree.currentStackItem().localName);
tree.insertionMode.processStartTag(name, attributes);
} else {
tree.parseError('unexpected-start-tag', {name: name});
}
};
modes.inTableBody.startTagOther = function(name, attributes) {
modes.inTable.processStartTag(name, attributes);
};
modes.inTableBody.endTagTableRowGroup = function(name) {
if (tree.openElements.inTableScope(name)) {
tree.openElements.popUntilTableBodyScopeMarker();
tree.popElement();
tree.setInsertionMode('inTable');
} else {
tree.parseError('unexpected-end-tag-in-table-body', {name: name});
}
};
modes.inTableBody.endTagTable = function(name) {
if (tree.openElements.inTableScope('tbody') || tree.openElements.inTableScope('thead') || tree.openElements.inTableScope('tfoot')) {
tree.openElements.popUntilTableBodyScopeMarker();
this.endTagTableRowGroup(tree.currentStackItem().localName);
tree.insertionMode.processEndTag(name);
} else {
tree.parseError('unexpected-end-tag', {name: name});
}
};
modes.inTableBody.endTagIgnore = function(name) {
tree.parseError("unexpected-end-tag-in-table-body", {name: name});
};
modes.inTableBody.endTagOther = function(name) {
modes.inTable.processEndTag(name);
};
modes.inSelect = Object.create(modes.base);
modes.inSelect.start_tag_handlers = {
html: 'startTagHtml',
option: 'startTagOption',
optgroup: 'startTagOptgroup',
select: 'startTagSelect',
input: 'startTagInput',
keygen: 'startTagInput',
textarea: 'startTagInput',
script: 'startTagScript',
'-default': 'startTagOther'
};
modes.inSelect.end_tag_handlers = {
option: 'endTagOption',
optgroup: 'endTagOptgroup',
select: 'endTagSelect',
caption: 'endTagTableElements',
table: 'endTagTableElements',
tbody: 'endTagTableElements',
tfoot: 'endTagTableElements',
thead: 'endTagTableElements',
tr: 'endTagTableElements',
td: 'endTagTableElements',
th: 'endTagTableElements',
'-default': 'endTagOther'
};
modes.inSelect.processCharacters = function(buffer) {
var data = buffer.takeRemaining();
data = data.replace(/\u0000/g, function(match, index){
tree.parseError("invalid-codepoint");
return '';
});
if (!data)
return;
tree.insertText(data);
};
modes.inSelect.startTagOption = function(name, attributes) {
if (tree.currentStackItem().localName == 'option')
tree.popElement();
tree.insertElement(name, attributes);
};
modes.inSelect.startTagOptgroup = function(name, attributes) {
if (tree.currentStackItem().localName == 'option')
tree.popElement();
if (tree.currentStackItem().localName == 'optgroup')
tree.popElement();
tree.insertElement(name, attributes);
};
modes.inSelect.endTagOption = function(name) {
if (tree.currentStackItem().localName !== 'option') {
tree.parseError('unexpected-end-tag-in-select', {name: name});
return;
}
tree.popElement();
};
modes.inSelect.endTagOptgroup = function(name) {
if (tree.currentStackItem().localName == 'option' && tree.openElements.item(tree.openElements.length - 2).localName == 'optgroup') {
tree.popElement();
}
if (tree.currentStackItem().localName == 'optgroup') {
tree.popElement();
} else {
tree.parseError('unexpected-end-tag-in-select', {name: 'optgroup'});
}
};
modes.inSelect.startTagSelect = function(name) {
tree.parseError("unexpected-select-in-select");
this.endTagSelect('select');
};
modes.inSelect.endTagSelect = function(name) {
if (tree.openElements.inTableScope('select')) {
tree.openElements.popUntilPopped('select');
tree.resetInsertionMode();
} else {
tree.parseError('unexpected-end-tag', {name: name});
}
};
modes.inSelect.startTagInput = function(name, attributes) {
tree.parseError("unexpected-input-in-select");
if (tree.openElements.inSelectScope('select')) {
this.endTagSelect('select');
tree.insertionMode.processStartTag(name, attributes);
}
};
modes.inSelect.startTagScript = function(name, attributes) {
modes.inHead.processStartTag(name, attributes);
};
modes.inSelect.endTagTableElements = function(name) {
tree.parseError('unexpected-end-tag-in-select', {name: name});
if (tree.openElements.inTableScope(name)) {
this.endTagSelect('select');
tree.insertionMode.processEndTag(name);
}
};
modes.inSelect.startTagOther = function(name, attributes) {
tree.parseError("unexpected-start-tag-in-select", {name: name});
};
modes.inSelect.endTagOther = function(name) {
tree.parseError('unexpected-end-tag-in-select', {name: name});
};
modes.inSelectInTable = Object.create(modes.base);
modes.inSelectInTable.start_tag_handlers = {
caption: 'startTagTable',
table: 'startTagTable',
tbody: 'startTagTable',
tfoot: 'startTagTable',
thead: 'startTagTable',
tr: 'startTagTable',
td: 'startTagTable',
th: 'startTagTable',
'-default': 'startTagOther'
};
modes.inSelectInTable.end_tag_handlers = {
caption: 'endTagTable',
table: 'endTagTable',
tbody: 'endTagTable',
tfoot: 'endTagTable',
thead: 'endTagTable',
tr: 'endTagTable',
td: 'endTagTable',
th: 'endTagTable',
'-default': 'endTagOther'
};
modes.inSelectInTable.processCharacters = function(data) {
modes.inSelect.processCharacters(data);
};
modes.inSelectInTable.startTagTable = function(name, attributes) {
tree.parseError("unexpected-table-element-start-tag-in-select-in-table", {name: name});
this.endTagOther("select");
tree.insertionMode.processStartTag(name, attributes);
};
modes.inSelectInTable.startTagOther = function(name, attributes, selfClosing) {
modes.inSelect.processStartTag(name, attributes, selfClosing);
};
modes.inSelectInTable.endTagTable = function(name) {
tree.parseError("unexpected-table-element-end-tag-in-select-in-table", {name: name});
if (tree.openElements.inTableScope(name)) {
this.endTagOther("select");
tree.insertionMode.processEndTag(name);
}
};
modes.inSelectInTable.endTagOther = function(name) {
modes.inSelect.processEndTag(name);
};
modes.inRow = Object.create(modes.base);
modes.inRow.start_tag_handlers = {
html: 'startTagHtml',
td: 'startTagTableCell',
th: 'startTagTableCell',
caption: 'startTagTableOther',
col: 'startTagTableOther',
colgroup: 'startTagTableOther',
tbody: 'startTagTableOther',
tfoot: 'startTagTableOther',
thead: 'startTagTableOther',
tr: 'startTagTableOther',
'-default': 'startTagOther'
};
modes.inRow.end_tag_handlers = {
tr: 'endTagTr',
table: 'endTagTable',
tbody: 'endTagTableRowGroup',
tfoot: 'endTagTableRowGroup',
thead: 'endTagTableRowGroup',
body: 'endTagIgnore',
caption: 'endTagIgnore',
col: 'endTagIgnore',
colgroup: 'endTagIgnore',
html: 'endTagIgnore',
td: 'endTagIgnore',
th: 'endTagIgnore',
'-default': 'endTagOther'
};
modes.inRow.processCharacters = function(data) {
modes.inTable.processCharacters(data);
};
modes.inRow.startTagTableCell = function(name, attributes) {
tree.openElements.popUntilTableRowScopeMarker();
tree.insertElement(name, attributes);
tree.setInsertionMode('inCell');
tree.activeFormattingElements.push(Marker);
};
modes.inRow.startTagTableOther = function(name, attributes) {
var ignoreEndTag = this.ignoreEndTagTr();
this.endTagTr('tr');
if (!ignoreEndTag) tree.insertionMode.processStartTag(name, attributes);
};
modes.inRow.startTagOther = function(name, attributes, selfClosing) {
modes.inTable.processStartTag(name, attributes, selfClosing);
};
modes.inRow.endTagTr = function(name) {
if (this.ignoreEndTagTr()) {
assert.ok(tree.context);
tree.parseError('unexpected-end-tag', {name: name});
} else {
tree.openElements.popUntilTableRowScopeMarker();
tree.popElement();
tree.setInsertionMode('inTableBody');
}
};
modes.inRow.endTagTable = function(name) {
var ignoreEndTag = this.ignoreEndTagTr();
this.endTagTr('tr');
if (!ignoreEndTag) tree.insertionMode.processEndTag(name);
};
modes.inRow.endTagTableRowGroup = function(name) {
if (tree.openElements.inTableScope(name)) {
this.endTagTr('tr');
tree.insertionMode.processEndTag(name);
} else {
tree.parseError('unexpected-end-tag', {name: name});
}
};
modes.inRow.endTagIgnore = function(name) {
tree.parseError("unexpected-end-tag-in-table-row", {name: name});
};
modes.inRow.endTagOther = function(name) {
modes.inTable.processEndTag(name);
};
modes.inRow.ignoreEndTagTr = function() {
return !tree.openElements.inTableScope('tr');
};
modes.afterAfterFrameset = Object.create(modes.base);
modes.afterAfterFrameset.start_tag_handlers = {
html: 'startTagHtml',
noframes: 'startTagNoFrames',
'-default': 'startTagOther'
};
modes.afterAfterFrameset.processEOF = function() {};
modes.afterAfterFrameset.processComment = function(data) {
tree.insertComment(data, tree.document);
};
modes.afterAfterFrameset.processCharacters = function(buffer) {
var characters = buffer.takeRemaining();
var whitespace = "";
for (var i = 0; i < characters.length; i++) {
var ch = characters[i];
if (isWhitespace(ch))
whitespace += ch;
}
if (whitespace) {
tree.reconstructActiveFormattingElements();
tree.insertText(whitespace);
}
if (whitespace.length < characters.length)
tree.parseError('expected-eof-but-got-char');
};
modes.afterAfterFrameset.startTagNoFrames = function(name, attributes) {
modes.inHead.processStartTag(name, attributes);
};
modes.afterAfterFrameset.startTagOther = function(name, attributes, selfClosing) {
tree.parseError('expected-eof-but-got-start-tag', {name: name});
};
modes.afterAfterFrameset.processEndTag = function(name, attributes) {
tree.parseError('expected-eof-but-got-end-tag', {name: name});
};
modes.text = Object.create(modes.base);
modes.text.start_tag_handlers = {
'-default': 'startTagOther'
};
modes.text.end_tag_handlers = {
script: 'endTagScript',
'-default': 'endTagOther'
};
modes.text.processCharacters = function(buffer) {
if (tree.shouldSkipLeadingNewline) {
tree.shouldSkipLeadingNewline = false;
buffer.skipAtMostOneLeadingNewline();
}
var data = buffer.takeRemaining();
if (!data)
return;
tree.insertText(data);
};
modes.text.processEOF = function() {
tree.parseError("expected-named-closing-tag-but-got-eof",
{name: tree.currentStackItem().localName});
tree.openElements.pop();
tree.setInsertionMode(tree.originalInsertionMode);
tree.insertionMode.processEOF();
};
modes.text.startTagOther = function(name) {
throw "Tried to process start tag " + name + " in RCDATA/RAWTEXT mode";
};
modes.text.endTagScript = function(name) {
var node = tree.openElements.pop();
assert.ok(node.localName == 'script');
tree.setInsertionMode(tree.originalInsertionMode);
};
modes.text.endTagOther = function(name) {
tree.openElements.pop();
tree.setInsertionMode(tree.originalInsertionMode);
};
}