/[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.1 by wakaba, Sun Apr 20 06:07:24 2008 UTC revision 1.5 by wakaba, Fri Apr 25 11:40:56 2008 UTC
# Line 13  Line 13 
13    output {    output {
14      display: block;      display: block;
15      font-family: monospace;      font-family: monospace;
16      white-space: pre;      white-space: -moz-pre-wrap;
17        white-space: pre-wrap;
18    }    }
19  </style>  </style>
20  <script>  <script>
21    function update () {    function update () {
22      document.logElement.textContent = '';      document.logElement.textContent = '';
23      var p = new Parser ();      var p = new Parser (new InputStream (document.sourceElement.value));
24      p.parse (new InputStream (document.sourceElement.value));      var doc = p.doc;
25      log (dumpTree (p.doc, ''));      p.parse ();
26        log (dumpTree (doc, ''));
27    } // update    } // update
28    
29    function log (s) {    function log (s) {
# Line 32  Line 34 
34      this.s = s;      this.s = s;
35    } // InputStream    } // InputStream
36    
37    function Parser () {    function Parser (i, doc) {
38      this.parseMode = 'pcdata';      this.parseMode = 'pcdata';
39      this.doc = new JSDocument ();      if (!doc) {
40      this.openElements = [this.doc];        doc = new JSDocument (this);
41          doc.manakaiIsHTML = true;
42        }
43        this.doc = doc;
44        this.openElements = [doc];
45        this.in = i;
46        this.scriptsExecutedAfterParsing = [];
47    } // Parser    } // Parser
48    
49    Parser.prototype.getNextToken = function (i) {    Parser.prototype.getNextToken = function () {
50        var p = this;
51        var i = this.in;
52      if (this.parseMode == 'script') {      if (this.parseMode == 'script') {
53        var token;        var token;
54        i.s = i.s.replace (/^([\s\S]+?)<\/[Ss][Cc][Rr][Ii][Pp][Tt]>/,        if (p.insertionPoint <= 0) {
55            return {type: 'abort'};
56          }
57          i.s = i.s.replace (/^([^<]+)/,
58        function (s, t) {        function (s, t) {
59            if (0 < p.insertionPoint && p.insertionPoint < t.length) {
60              token = {type: 'char', value: t.substring (0, p.insertionPoint)};
61              var ip = p.insertionPoint;
62              p.insertionPoint = 0;
63              return t.substring (ip, t.length);
64            }
65          token = {type: 'char', value: t};          token = {type: 'char', value: t};
66          return '<' + '/script>';          p.insertionPoint -= t.length;
67            return '';
68        });        });
69        if (token) return token;        if (token) return token;
70        i.s = i.s.replace (/^<\/[Ss][Cc][Rr][Ii][Pp][Tt]>/, function () {        i.s = i.s.replace (/^<\/[Ss][Cc][Rr][Ii][Pp][Tt]>/, function (s) {
71            if (p.insertionPoint < s.length) {
72              token = {type: 'abort'};
73              return s;
74            }
75          token = {type: 'end-tag', value: 'script'};          token = {type: 'end-tag', value: 'script'};
76            p.insertionPoint -= s.length;
77            return '';
78          });
79          if (token) return token;
80          var m;
81          if ((p.insertionPoint < '</script'.length) &&
82              (m = i.s.match (/^<\/([SCRIPTscript]+)/))) {
83            var v = m[1].substring (0, p.insertionPoint).toLowerCase ();
84            if (v == 'script'.substring (0, p.insertionPoint - '</'.length)) {
85              return {type: 'abort'};
86            }
87          }
88          i.s = i.s.replace (/^</,
89          function (s) {
90            token = {type: 'char', value: s};
91            p.insertionPoint -= s.length;
92          return '';          return '';
93        });        });
94        if (token) return token;        if (token) return token;
# Line 56  Line 96 
96      }      }
97    
98      var token;      var token;
99      i.s = i.s.replace (/^<\/([^>]+)>/, function (s, e) {      i.s = i.s.replace (/^<\/([^>]+)(?:>|$)/, function (s, e) {
100          if (p.insertionPoint < s.length ||
101              (p.insertionPoint <= s.length &&
102               s.substring (s.length - 1, 1) != '>')) {
103            token = {type: 'abort'};
104            return s;
105          }
106        token = {type: 'end-tag', value: e.toLowerCase ()};        token = {type: 'end-tag', value: e.toLowerCase ()};
107          p.insertionPoint -= s.length;
108        return '';        return '';
109      });      });
110      if (token) return token;      if (token) return token;
111      i.s = i.s.replace (/^<([^>]+)>/, function (s, e) {      i.s = i.s.replace (/^<([^>]+)(?:>|$)/, function (s, e) {
112        token = {type: 'start-tag', value: e.toLowerCase ()};        if (p.insertionPoint < s.length ||
113              (p.insertionPoint <= s.length &&
114               s.substring (s.length - 1, 1) != '>')) {
115            token = {type: 'abort'};
116            return s;
117          }
118          var tagName;
119          var attrs = {};
120          e = e.replace (/^[\S]+/, function (v) {
121            tagName = v.toLowerCase ();
122            return '';
123          });
124          e = e.replace (/^\s*(\S+)\s*(?:=\s*"([^"]*)"|'([^']*)'|([^"']+))?/,
125          function (x, attrName, attrValue1, attrValue2, attrValue3) {
126            attrs[attrName] = attrValue1 || attrValue2 || attrValue3;
127            return '';
128          });
129          token = {type: 'start-tag', value: tagName, attrs: attrs};
130          p.insertionPoint -= s.length;
131        return '';        return '';
132      });      });
133      if (token) return token;      if (token) return token;
134        if (p.insertionPoint <= 0) {
135          return {type: 'abort'};
136        }
137      i.s = i.s.replace (/^[^<]+/, function (s) {      i.s = i.s.replace (/^[^<]+/, function (s) {