/[suikacvs]/markup/html/scripting-parser/parser.html
Suika

Diff of /markup/html/scripting-parser/parser.html

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.8 by wakaba, Sun Apr 27 08:56:34 2008 UTC revision 1.10 by wakaba, Sun Apr 27 10:34:18 2008 UTC
# Line 47  Line 47 
47        var p = new Parser (new InputStream (v));        var p = new Parser (new InputStream (v));
48        var doc = p.doc;        var doc = p.doc;
49        p.parse ();        p.parse ();
50          
51        log (dumpTree (doc, ''));        log (dumpTree (doc, ''));
52          
53          if (p.hasAsyncScript) {
54            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');
55          }
56      }      }
57    } // update2    } // update2
58    
# Line 73  Line 78 
78      this.openElements = [doc];      this.openElements = [doc];
79      this.input = i;      this.input = i;
80      this.scriptsExecutedAfterParsing = [];      this.scriptsExecutedAfterParsing = [];
81        this.scriptsExecutedSoon = [];
82    } // Parser    } // Parser
83    
84    Parser.prototype.getNextToken = function () {    Parser.prototype.getNextToken = function () {
# Line 150  Line 156 
156          tagName = v.toLowerCase ();          tagName = v.toLowerCase ();
157          return '';          return '';
158        });        });
159        e = e.replace (/^\s*([^\s=]+)\s*(?:=\s*(?:"([^"]*)"|'([^']*)'|([^"']+)))?/,        while (true) {
160        function (x, attrName, attrValue1, attrValue2, attrValue3) {          var m = false;
161          v = attrValue1 || attrValue2 || attrValue3;          e = e.replace (/^\s*([^\s=]+)\s*(?:=\s*(?:"([^"]*)"|'([^']*)'|([^"'\s]*)))?/,
162          v = v.replace (/"/g, '"').replace (/'/g, "'")          function (x, attrName, attrValue1, attrValue2, attrValue3) {
163              .replace (/&/g, '&');            v = attrValue1 || attrValue2 || attrValue3;
164          attrs[attrName.toLowerCase ()] = v;            v = v.replace (/"/g, '"').replace (/'/g, "'")
165          return '';                .replace (/&/g, '&');
166        });            attrs[attrName.toLowerCase ()] = v;
167              m = true;
168              return '';
169            });
170            if (!m) break;
171          }
172        if (e.length) {        if (e.length) {
173          log ('Broken start tag: "' + e + '"');          log ('Broken start tag: "' + e + '"');
174        }        }
# Line 324  Line 335 
335    
336      // "When a script completes loading" rules start applying.      // "When a script completes loading" rules start applying.
337    
338      // TODO: Handles "list of scripts that will execute as soon as possible"      // List of scripts that will execute as soon as possible
339      // and "list of scripts that will execute asynchronously"      for (var i = 0; i < this.scriptsExecutedSoon.length; i++) {
340          var e = this.scriptsExecutedSoon[i];
341    
342          // If it has completed loading
343          log ('Execute an external script not inserted by parser...');
344          executeScript (this.doc, e);
345    
346          // NOTE: It MAY be executed before the end of the parsing, according
347          // to the spec.
348          this.hasAsyncScript = true;
349        }
350    
351        // TODO: Handles
352        // "list of scripts that will execute asynchronously"
353    
354      // Handle "list of scripts that will execute when the document has finished      // Handle "list of scripts that will execute when the document has finished
355      // parsing".      // parsing".
# Line 429  Line 453 
453            log ('Error: There is a script that will execute as soon as the parser resumes.');            log ('Error: There is a script that will execute as soon as the parser resumes.');
454          }          }
455          p.scriptExecutedWhenParserResumes = e;          p.scriptExecutedWhenParserResumes = e;
456          log ('Running a script: aborted (src)');          log ('Running a script: aborted (src parser-inserted)');
457        } else if (e.src != null) {        } else if (e.src != null) {
458          // TODO          p.scriptsExecutedSoon.push (e);
459            log ('Running a script: aborted (src)');
460        } else {        } else {
461          executeScript (doc, e); // even if other scripts are already executing.          executeScript (doc, e); // even if other scripts are already executing.
462        }        }
# Line 479  Line 504 
504        var m;        var m;
505        if (m = uri.match (/^javascript:\s*(?:'([^']*)'|"([^"]+)")\s*$/i)) {        if (m = uri.match (/^javascript:\s*(?:'([^']*)'|"([^"]+)")\s*$/i)) {
506          if (m[1]) {          if (m[1]) {
507            return m[1];            return m[1].replace (/\\u([0-9A-F]{4})/g, function (s, v) {
508                return String.fromCharCode (parseInt ('0x' + v));
509              });
510          } else if (m[2]) {          } else if (m[2]) {
511            return m[2];            return m[2].replace (/\\u([0-9A-F]{4})/g, function (s, v) {
512                return String.fromCharCode (parseInt ('0x' + v));
513              });
514          } else {          } else {
515            return null;            return null;
516          }          }
# Line 508  Line 537 
537          doc.write.apply (doc, args);          doc.write.apply (doc, args);
538          return '';          return '';
539        });        });
540          s = s.replace (/^\s*var\s+s\s*=\s*document\.createElement\s*\(\s*['"]script['"]\s*\)\s*;\s*s\.src\s*=\s*(?:'(javascript:[^']*)'|"(javascript:[^"]*)")\s*;\s*document\.documentElement\.appendChild\s*\(\s*s\s*\)\s*;\s*/,
541          function (s, t, u) {
542            matched = true;
543            var args = [t ? t : u];
544            doc._insertExternalScript.apply (doc, args);
545            return '';
546          });
547        if (s == '') break;        if (s == '') break;
548        if (!matched) {        if (!matched) {
549          log ('Script parse error: "' + s + '"');          log ('Script parse error: "' + s + '"');
# Line 626  Line 662 
662      return;      return;
663    }; // document.write    }; // document.write
664    
665      JSDocument.prototype._insertExternalScript = function (uri) {
666        var s = new JSElement (this, 'script');
667        s.src = uri;
668        this.documentElement.appendChild (s);
669      }; // _insertExternalScript
670    
671      JSDocument.prototype.__defineGetter__ ('documentElement', function () {
672        var cn = this.childNodes;
673        for (var i = 0; i < cn.length; i++) {
674          if (cn[i] instanceof JSElement) {
675            return cn[i]
676          }
677        }
678        return null;
679      });
680    
681    JSElement.prototype.__defineGetter__ ('text', function () {    JSElement.prototype.__defineGetter__ ('text', function () {
682      var r = '';      var r = '';
683      for (var i = 0; i < this.childNodes.length; i++) {      for (var i = 0; i < this.childNodes.length; i++) {
# Line 644  Line 696 
696          r += '| ' + indent + node.localName + '\n';          r += '| ' + indent + node.localName + '\n';
697          if (node.async) r += '| ' + indent + '  async=""\n';          if (node.async) r += '| ' + indent + '  async=""\n';
698          if (node.defer) r += '| ' + indent + '  defer=""\n';          if (node.defer) r += '| ' + indent + '  defer=""\n';
699          if (node.src) r += '| ' + indent + '  src="' + node.src + '"\n';          if (node.src != null) {
700              r += '| ' + indent + '  src="' + node.src + '"\n';
701            }
702          r += dumpTree (node, indent + '  ');          r += dumpTree (node, indent + '  ');
703        } else if (node instanceof JSText) {        } else if (node instanceof JSText) {
704          r += '| ' + indent + '"' + node.data + '"\n';          r += '| ' + indent + '"' + node.data + '"\n';
# Line 693  document.write ('aaaaaaa&lt;/p>&lt;scrip Line 747  document.write ('aaaaaaa&lt;/p>&lt;scrip
747  &lt;p>  &lt;p>
748  </textarea>  </textarea>
749    
750  <h2>Log</h2>  <h2 id=log>Log</h2>
751  <p><output></output>  <p><output></output>
752    
753  <h2>Note</h2>  <h2 id=notes>Notes</h2>
754    
755  <p>This is a <em>simplified</em> implementation of  <p>This is a <em>simplified</em> implementation of
756  <a href="http://www.whatwg.org/specs/web-apps/current-work/#parsing">HTML5  <a href="http://www.whatwg.org/specs/web-apps/current-work/#parsing">HTML5
# Line 718  in <code>script</code> element. Line 772  in <code>script</code> element.
772  <li>Only supports <code>script</code> <code>type</code>  <li>Only supports <code>script</code> <code>type</code>
773  <code>text/javascript</code>.  <code>type</code> and <code>language</code>  <code>text/javascript</code>.  <code>type</code> and <code>language</code>
774  attributes are ignored.  attributes are ignored.
775  <li>Only supports <code>document.write</code>.  <li>Only supports limited statements.  It must consist of zero or more
776  The script code must be match to the regular expression  of statements looking similar to the following statements, possibly
777  <code>^\s*(?:document\.write\s*\(<var>v</var>\s*(?:,\s*<var>v</var>\s*)*\)\s*;\s*)*$</code>  introduced, followed, or separated by white space characters:
778  where <var>v</var> is <code>"[^"]*"|'[^']*'</code>.    <ul>
779      <li><code>document.write ("<var>string</var>", ["<var>string</var>", ...]);</code>.
780      <li><code>var s = document.createElement ("script");
781                s.src = "<var>string</var>";
782                document.documentElement.appendChild (s);</code>
783      </ul>
784    Note that strings may be delimited by <code>'</code>s instead of
785    <code>"</code>s.
786  <li>Only supports <code>javascript:</code>  <li>Only supports <code>javascript:</code>
787  <abbr title="Uniform Resourace Identifiers">URI</abbr> scheme in the  <abbr title="Uniform Resourace Identifiers">URI</abbr> scheme in the
788  <code>src</code> attribute of the <code>script</code> element.  In addition,  <code>src</code> attribute of the <code>script</code> element.  In addition,
789  the <abbr title="Uniform Resource Identifiers">URI</abbr> must be conform to  the <abbr title="Uniform Resource Identifiers">URI</abbr> must be conform to
790  the regular expression <code>^javascript:\s*(?:"[^"]*"|'[^']*')\s*$</code>.  the regular expression <code>^javascript:\s*(?:"[^"]*"|'[^']*')\s*$</code>.
791    <li>Only supports <code>\u<var>HHHH</var></code> escapes only in
792    <code>javascript:</code> URI.
793  </ul>  </ul>
794    
795  <p>For some reason, this parser does not work in browsers that do  <p>For some reason, this parser does not work in browsers that do
796  not support JavaScript 1.5.  not support JavaScript 1.5.
797    
798  <!-- TODO: multiple attributes are not supported yet -->  <!-- TODO: license -->
799    
800  </body>  </body>
801  </html>  </html>

Legend:
Removed from v.1.8  
changed lines
  Added in v.1.10

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24