/[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.10 by wakaba, Sun Apr 27 10:34:18 2008 UTC revision 1.12 by wakaba, Sun Apr 27 11:21:09 2008 UTC
# Line 79  Line 79 
79      this.input = i;      this.input = i;
80      this.scriptsExecutedAfterParsing = [];      this.scriptsExecutedAfterParsing = [];
81      this.scriptsExecutedSoon = [];      this.scriptsExecutedSoon = [];
82        this.scriptsExecutedAsynchronously = [];
83    } // Parser    } // Parser
84    
85    Parser.prototype.getNextToken = function () {    Parser.prototype.getNextToken = function () {
# Line 335  Line 336 
336    
337      // "When a script completes loading" rules start applying.      // "When a script completes loading" rules start applying.
338    
339      // List of scripts that will execute as soon as possible      while (this.scriptsExecutedSoon.length > 0 ||
340      for (var i = 0; i < this.scriptsExecutedSoon.length; i++) {             this.scriptsExecutedAsynchronously.length > 0) {
341        var e = this.scriptsExecutedSoon[i];        // Handle "list of scripts that will execute as soon as possible".
342          while (this.scriptsExecutedSoon.length > 0) {
343            var e = this.scriptsExecutedSoon.shift ();
344      
345            // If it has completed loading
346            log ('Execute an external script not inserted by parser...');
347            executeScript (this.doc, e);
348    
349            // NOTE: It MAY be executed before the end of the parsing, according
350            // to the spec.
351            this.hasAsyncScript = true;
352          }
353    
354          // Handle "list of scripts that will execute asynchronously".
355          while (this.scriptsExecutedAsynchronously.length > 0) {
356            var e = this.scriptsExecutedAsynchronously.shift ();
357    
358            // Step 1.
359            // We assume that all scripts have been loaded at this time.
360      
361            // Step 2.
362            log ('Execute an asynchronous script...');
363            executeScript (this.doc, e);
364    
365            // Step 3.
366            //
367    
368            // Step 4.
369            //
370    
371        // If it has completed loading          this.hasAsyncScript = true;
372        log ('Execute an external script not inserted by parser...');        }
       executeScript (this.doc, e);  
   
       // NOTE: It MAY be executed before the end of the parsing, according  
       // to the spec.  
       this.hasAsyncScript = true;  
373      }      }
374    
     // TODO: Handles  
     // "list of scripts that will execute asynchronously"  
   
375      // Handle "list of scripts that will execute when the document has finished      // Handle "list of scripts that will execute when the document has finished
376      // parsing".      // parsing".
377      var list = this.scriptsExecutedAfterParsing;      var list = this.scriptsExecutedAfterParsing;
# Line 444  Line 465 
465          p.scriptsExecutedAfterParsing.push (e);          p.scriptsExecutedAfterParsing.push (e);
466          log ('Running a script: aborted (defer)');          log ('Running a script: aborted (defer)');
467        } else if (e.async && e.src != null) {        } else if (e.async && e.src != null) {
468          // TODO          p.scriptsExecutedAsynchronously.push (e);
469        } else if (e.async && e.src == null          log ('Running a script: aborted (async src)');
470                   /* && list of scripts that will execute asynchronously is not empty */) {        } else if (e.async && e.src == null &&
471          // TODO                   p.scriptsExecutedAsynchronously.length > 0) {
472            p.scriptsExecutedAsynchronously.push (e);
473            log ('Running a script: aborted (async)');
474            // ISSUE: What is the difference with the case above?
475        } else if (e.src != null && e.manakaiParserInserted) {        } else if (e.src != null && e.manakaiParserInserted) {
476          if (p.scriptExecutedWhenParserResumes) {          if (p.scriptExecutedWhenParserResumes) {
477            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.');
# Line 504  Line 528 
528        var m;        var m;
529        if (m = uri.match (/^javascript:\s*(?:'([^']*)'|"([^"]+)")\s*$/i)) {        if (m = uri.match (/^javascript:\s*(?:'([^']*)'|"([^"]+)")\s*$/i)) {
530          if (m[1]) {          if (m[1]) {
531            return m[1].replace (/\\u([0-9A-F]{4})/g, function (s, v) {            return unescapeJSLiteral (m[1]);
             return String.fromCharCode (parseInt ('0x' + v));  
           });  
532          } else if (m[2]) {          } else if (m[2]) {
533            return m[2].replace (/\\u([0-9A-F]{4})/g, function (s, v) {            return unescapeJSLiteral (m[2]);
             return String.fromCharCode (parseInt ('0x' + v));  
           });  
534          } else {          } else {
535            return null;            return null;
536          }          }
# Line 531  Line 551 
551          matched = true;          matched = true;
552          var args = [];          var args = [];
553          t.replace (/('[^']*'|"[^"]*")/g, function (s, v) {          t.replace (/('[^']*'|"[^"]*")/g, function (s, v) {
554            args.push (v.substring (1, v.length - 1));            args.push (unescapeJSLiteral (v.substring (1, v.length - 1)));
555            return '';            return '';
556          });          });
557          doc.write.apply (doc, args);          doc.write.apply (doc, args);
# Line 540  Line 560 
560        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*/,        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*/,
561        function (s, t, u) {        function (s, t, u) {
562          matched = true;          matched = true;
563          var args = [t ? t : u];          var args = [unescapeJSLiteral (t ? t : u)];
564          doc._insertExternalScript.apply (doc, args);          doc._insertExternalScript.apply (doc, args);
565          return '';          return '';
566        });        });
# Line 552  Line 572 
572      }      }
573    } // parseAndRunScript    } // parseAndRunScript
574    
575      function unescapeJSLiteral (s) {
576        return s.replace (/\\u([0-9A-Fa-f]{4})/g, function (t, v) {
577          return String.fromCharCode (parseInt ('0x' + v));
578        });
579      } // unescapeJSLiteral
580    
581    function JSText (data) {    function JSText (data) {
582      this.data = data;      this.data = data;
583    } // JSText    } // JSText
# Line 788  Note that strings may be delimited by <c Line 814  Note that strings may be delimited by <c
814  <code>src</code> attribute of the <code>script</code> element.  In addition,  <code>src</code> attribute of the <code>script</code> element.  In addition,
815  the <abbr title="Uniform Resource Identifiers">URI</abbr> must be conform to  the <abbr title="Uniform Resource Identifiers">URI</abbr> must be conform to
816  the regular expression <code>^javascript:\s*(?:"[^"]*"|'[^']*')\s*$</code>.  the regular expression <code>^javascript:\s*(?:"[^"]*"|'[^']*')\s*$</code>.
817  <li>Only supports <code>\u<var>HHHH</var></code> escapes only in  <li>Only supports <code>\u<var>HHHH</var></code> escapes in JavaScript
818  <code>javascript:</code> URI.  string literals.
819    <li>Does not handle <i>stop parsing</i> phase correctly if the document is
820    replaced by <code>document.open ()</code> call.  In other word, delayed
821    (deferred or asynchronous) script executions and event firings might be
822    treated in a wrong way if a <code>document.open ()</code> invocation
823    is implicitly done by <code>document.write ()</code> in a delayed script.
824  </ul>  </ul>
825    
826  <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
827  not support JavaScript 1.5.  not support JavaScript 1.5.
828    
829    <!-- TODO: |src| attribute value should refer the value at the time
830    when it is inserted into the document, not the value when the script is
831    executed.  Currently it does not matter, since we don't allow dynamic
832    modification to the |src| content/DOM attribute value yet. -->
833    
834  <!-- TODO: license -->  <!-- TODO: license -->
835    
836  </body>  </body>

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24