Parent Directory
|
Revision Log
|
Patch
| revision 1.9 by wakaba, Sun Apr 27 09:16:11 2008 UTC | revision 1.14 by wakaba, Tue Apr 29 02:50:00 2008 UTC | |
|---|---|---|
| # | Line 2 | Line 2 |
| 2 | <html lang=en> | <html lang=en> |
| 3 | <head> | <head> |
| 4 | <title>Live Scripting HTML Parser</title> | <title>Live Scripting HTML Parser</title> |
| 5 | <link rel=author href="http://suika.fam.cx/~wakaba/who?"> | |
| 6 | <link rel=license href="http://suika.fam.cx/c/gnu/gpl" | |
| 7 | title="GNU GPL2 or later"> | |
| 8 | <style> | <style> |
| 9 | h1, h2 { | h1 { |
| 10 | margin: 0; | |
| 11 | font-size: 150%; | |
| 12 | } | |
| 13 | h2 { | |
| 14 | margin: 0; | margin: 0; |
| 15 | font-size: 100%; | font-size: 100%; |
| 16 | } | } |
| 17 | p, pre { | p { |
| 18 | margin: 0; | margin: 0 1em; |
| 19 | } | } |
| 20 | textarea { | textarea { |
| 21 | width: 100%; | width: 100%; |
| # | Line 47 | Line 54 |
| 54 | var p = new Parser (new InputStream (v)); | var p = new Parser (new InputStream (v)); |
| 55 | var doc = p.doc; | var doc = p.doc; |
| 56 | p.parse (); | p.parse (); |
| 57 | ||
| 58 | log (dumpTree (doc, '')); | log (dumpTree (doc, '')); |
| 59 | ||
| 60 | if (p.hasAsyncScript) { | |
| 61 | log ('Some script codes are executed asynchronously; it means that the document might be rendered in different ways depending on the network condition and other factors'); | |
| 62 | } | |
| 63 | } | } |
| 64 | } // update2 | } // update2 |
| 65 | ||
| # | Line 73 | Line 85 |
| 85 | this.openElements = [doc]; | this.openElements = [doc]; |
| 86 | this.input = i; | this.input = i; |
| 87 | this.scriptsExecutedAfterParsing = []; | this.scriptsExecutedAfterParsing = []; |
| 88 | this.scriptsExecutedSoon = []; | |
| 89 | this.scriptsExecutedAsynchronously = []; | |
| 90 | } // Parser | } // Parser |
| 91 | ||
| 92 | Parser.prototype.getNextToken = function () { | Parser.prototype.getNextToken = function () { |
| 93 | var p = this; | var p = this; |
| 94 | var i = this.input; | var i = this.input; |
| 95 | if (this.parseMode == 'script') { | if (this.parseMode == 'cdata') { |
| 96 | var tagName = this.endTagName; | |
| 97 | var token; | var token; |
| 98 | if (p.insertionPoint <= 0) { | if (p.insertionPoint <= 0) { |
| 99 | return {type: 'abort'}; | return {type: 'abort'}; |
| # | Line 96 | Line 111 |
| 111 | return ''; | return ''; |
| 112 | }); | }); |
| 113 | if (token) return token; | if (token) return token; |
| 114 | i.s = i.s.replace (/^<\/[Ss][Cc][Rr][Ii][Pp][Tt]>/, function (s) { | var pattern = new RegExp ('^</' + tagName + '>', 'i'); |
| 115 | i.s = i.s.replace (pattern, function (s) { | |
| 116 | if (p.insertionPoint < s.length) { | if (p.insertionPoint < s.length) { |
| 117 | token = {type: 'abort'}; | token = {type: 'abort'}; |
| 118 | return s; | return s; |
| 119 | } | } |
| 120 | token = {type: 'end-tag', value: 'script'}; | token = {type: 'end-tag', value: tagName}; |
| 121 | p.insertionPoint -= s.length; | p.insertionPoint -= s.length; |
| 122 | return ''; | return ''; |
| 123 | }); | }); |
| 124 | if (token) return token; | if (token) return token; |
| 125 | var m; | var m; |
| 126 | if ((p.insertionPoint < '</script'.length) && | if ((p.insertionPoint < ('</' + tagName).length) && |
| 127 | (m = i.s.match (/^<\/([SCRIPTscript]+)/))) { | (m = i.s.match (/^<\/([A-Za-z]+)/))) { |
| 128 | var v = m[1].substring (0, p.insertionPoint).toLowerCase (); | var v = m[1].substring (0, p.insertionPoint).toLowerCase (); |
| 129 | if (v == 'script'.substring (0, p.insertionPoint - '</'.length)) { | if (v == tagName.substring (0, p.insertionPoint - '</'.length)) { |
| 130 | return {type: 'abort'}; | return {type: 'abort'}; |
| 131 | } | } |
| 132 | } | } |
| # | Line 215 | Line 231 |
| 231 | el.manakaiParserInserted = true; | el.manakaiParserInserted = true; |
| 232 | ||
| 233 | // 3. Switch the tokeniser's content model flag to the CDATA state. | // 3. Switch the tokeniser's content model flag to the CDATA state. |
| 234 | this.parseMode = 'script'; | this.parseMode = 'cdata'; |
| 235 | this.endTagName = 'script'; | |
| 236 | ||
| 237 | // 4.1. Collect all the character tokens. | // 4.1. Collect all the character tokens. |
| 238 | while (true) { | while (true) { |
| # | Line 229 | Line 246 |
| 246 | // 4.2. Until it returns a token that is not a character token, or | // 4.2. Until it returns a token that is not a character token, or |
| 247 | // until it stops tokenising. | // until it stops tokenising. |
| 248 | } else if (token.type == 'eof' || | } else if (token.type == 'eof' || |
| 249 | (token.type == 'end-tag' && token.value == 'script') || | token.type == 'end-tag' || |
| 250 | token.type == 'abort') { | token.type == 'abort') { |
| 251 | // 6. Switched back to the PCDATA state. | // 6. Switched back to the PCDATA state. |
| 252 | this.parseMode = 'pcdata'; | this.parseMode = 'pcdata'; |
| 253 | < |