--- markup/html/scripting-parser/parser.html 2008/04/29 03:29:41 1.15
+++ markup/html/scripting-parser/parser.html 2008/04/29 04:07:18 1.16
@@ -83,6 +83,7 @@
doc = new JSDocument (this);
doc.manakaiIsHTML = true;
}
+ this.nextToken = [];
this.doc = doc;
this.openElements = [doc];
this.input = i;
@@ -92,6 +93,10 @@
} // Parser
Parser.prototype.getNextToken = function () {
+ if (this.nextToken.length) {
+ return this.nextToken.shift ();
+ }
+
var p = this;
var i = this.input;
if (this.parseMode == 'cdata') {
@@ -146,7 +151,7 @@
i.s = i.s.replace (/^<\/([^>]+)(?:>|$)/, function (s, e) {
if (p.insertionPoint < s.length ||
(p.insertionPoint <= s.length &&
- s.substring (s.length - 1, 1) != '>')) {
+ s.substring (s.length - 1, s.length) != '>')) {
token = {type: 'abort'};
return s;
}
@@ -158,7 +163,7 @@
i.s = i.s.replace (/^<([^>]+)(?:>|$)/, function (s, e) {
if (p.insertionPoint < s.length ||
(p.insertionPoint <= s.length &&
- s.substring (s.length - 1, 1) != '>')) {
+ s.substring (s.length - 1, s.length) != '>')) {
token = {type: 'abort'};
return s;
}
@@ -221,6 +226,24 @@
var token = this.getNextToken ();
log ('token: ' + token.type + ' "' + token.value + '"');
+ if (this.cdataEndTagRequired) {
+ // Generic CDATA parsing algorithm
+
+ if (token.type != 'abort') {
+ // 7.
+ if (token.type == 'end-tag' && token.value == this.endTagName) {
+ // 7.1. Ignores it.
+ //
+ } else {
+ // 7.2. Parse error.
+ log ('Parse error: no ' + this.endTagName + '>');
+ this.nextToken.unshift (token);
+ }
+ this.cdataEndTagRequired = false;
+ continue;
+ }
+ }
+
if (token.type == 'start-tag') {
if (token.value == 'script') {
// 1. Create an element for the token in the HTML namespace.
@@ -257,6 +280,7 @@
if (!(token.type == 'end-tag' && token.value == 'script')) {
// 7.2. This is a parse error.
log ('Parse error: no ' + 'script>');
+ this.nextToken.unshift (token);
// 7.3. Mark the script element as "already executed".
el.manakaiAlreadyExecuted = true;
@@ -348,11 +372,17 @@
// 6. Switched back to the PCDATA state.
this.parseMode = 'pcdata';
+ if (token.type == 'abort') {
+ this.cdataEndTagRequired = true;
+ break;
+ }
+
// 7.1. If the next token is not an end tag token with ...
if (!(token.type == 'end-tag' &&
token.value == this.endTagName)) {
// 7.2. This is a parse error.
log ('Parse error: no ' + this.endTagName + '>');
+ this.nextToken.unshift (token);
// 7.3. Mark the script element as "already executed".
el.manakaiAlreadyExecuted = true;
@@ -914,7 +944,7 @@