Skip to content
Snippets Groups Projects
index.js 7.57 MiB
Newer Older
  • Learn to ignore specific revisions
  • Hugo SUBTIL's avatar
    Hugo SUBTIL committed
                closeText(parser)
                break
    
              case 'cdata':
                emitNode(parser, 'oncdata', parser.cdata)
                parser.cdata = ''
                break
    
              case 'script':
                emitNode(parser, 'onscript', parser.script)
                parser.script = ''
                break
    
              default:
                error(parser, 'Max buffer length exceeded: ' + buffers[i])
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
          maxActual = Math.max(maxActual, len)
        }
        // schedule the next check for the earliest possible buffer overrun.
        var m = sax.MAX_BUFFER_LENGTH - maxActual
        parser.bufferCheckPosition = m + parser.position
      }
    
      function clearBuffers (parser) {
        for (var i = 0, l = buffers.length; i < l; i++) {
          parser[buffers[i]] = ''
        }
      }
    
      function flushBuffers (parser) {
        closeText(parser)
        if (parser.cdata !== '') {
          emitNode(parser, 'oncdata', parser.cdata)
          parser.cdata = ''
        }
        if (parser.script !== '') {
          emitNode(parser, 'onscript', parser.script)
          parser.script = ''
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
        }
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      SAXParser.prototype = {
        end: function () { end(this) },
        write: write,
        resume: function () { this.error = null; return this },
        close: function () { return this.write(null) },
        flush: function () { flushBuffers(this) }
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      var Stream
      try {
        Stream = (__webpack_require__(82).Stream)
      } catch (ex) {
        Stream = function () {}
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      var streamWraps = sax.EVENTS.filter(function (ev) {
        return ev !== 'error' && ev !== 'end'
      })
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function createStream (strict, opt) {
        return new SAXStream(strict, opt)
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function SAXStream (strict, opt) {
        if (!(this instanceof SAXStream)) {
          return new SAXStream(strict, opt)
        }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        Stream.apply(this)
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        this._parser = new SAXParser(strict, opt)
        this.writable = true
        this.readable = true
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        var me = this
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        this._parser.onend = function () {
          me.emit('end')
        }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        this._parser.onerror = function (er) {
          me.emit('error', er)
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
          // if didn't throw, then means error was handled.
          // go ahead and clear error, so we can write again.
          me._parser.error = null
        }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        this._decoder = null
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        streamWraps.forEach(function (ev) {
          Object.defineProperty(me, 'on' + ev, {
            get: function () {
              return me._parser['on' + ev]
            },
            set: function (h) {
              if (!h) {
                me.removeAllListeners(ev)
                me._parser['on' + ev] = h
                return h
              }
              me.on(ev, h)
            },
            enumerable: true,
            configurable: false
          })
        })
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      SAXStream.prototype = Object.create(Stream.prototype, {
        constructor: {
          value: SAXStream
        }
      })
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      SAXStream.prototype.write = function (data) {
        if (typeof Buffer === 'function' &&
          typeof Buffer.isBuffer === 'function' &&
          Buffer.isBuffer(data)) {
          if (!this._decoder) {
    
            var SD = (__webpack_require__(945).StringDecoder)
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            this._decoder = new SD('utf8')
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
          }
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
          data = this._decoder.write(data)
        }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        this._parser.write(data.toString())
        this.emit('data', data)
        return true
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      SAXStream.prototype.end = function (chunk) {
        if (chunk && chunk.length) {
          this.write(chunk)
        }
        this._parser.end()
        return true
      }
    
      SAXStream.prototype.on = function (ev, handler) {
        var me = this
        if (!me._parser['on' + ev] && streamWraps.indexOf(ev) !== -1) {
          me._parser['on' + ev] = function () {
            var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments)
            args.splice(0, 0, ev)
            me.emit.apply(me, args)
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
          }
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        return Stream.prototype.on.call(me, ev, handler)
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      // this really needs to be replaced with character classes.
      // XML allows all manner of ridiculous numbers and digits.
      var CDATA = '[CDATA['
      var DOCTYPE = 'DOCTYPE'
      var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace'
      var XMLNS_NAMESPACE = 'http://www.w3.org/2000/xmlns/'
      var rootNS = { xml: XML_NAMESPACE, xmlns: XMLNS_NAMESPACE }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      // http://www.w3.org/TR/REC-xml/#NT-NameStartChar
      // This implementation works on strings, a single character at a time
      // as such, it cannot ever support astral-plane characters (10000-EFFFF)
      // without a significant breaking change to either this  parser, or the
      // JavaScript language.  Implementation of an emoji-capable xml parser
      // is left as an exercise for the reader.
      var nameStart = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      var nameBody = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      var entityStart = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/
      var entityBody = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function isWhitespace (c) {
        return c === ' ' || c === '\n' || c === '\r' || c === '\t'
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function isQuote (c) {
        return c === '"' || c === '\''
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function isAttribEnd (c) {
        return c === '>' || isWhitespace(c)
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function isMatch (regex, c) {
        return regex.test(c)
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function notMatch (regex, c) {
        return !isMatch(regex, c)
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      var S = 0
      sax.STATE = {
        BEGIN: S++, // leading byte order mark or whitespace
        BEGIN_WHITESPACE: S++, // leading whitespace
        TEXT: S++, // general stuff
        TEXT_ENTITY: S++, // &amp and such.
        OPEN_WAKA: S++, // <
        SGML_DECL: S++, // <!BLARG
        SGML_DECL_QUOTED: S++, // <!BLARG foo "bar
        DOCTYPE: S++, // <!DOCTYPE
        DOCTYPE_QUOTED: S++, // <!DOCTYPE "//blah
        DOCTYPE_DTD: S++, // <!DOCTYPE "//blah" [ ...
        DOCTYPE_DTD_QUOTED: S++, // <!DOCTYPE "//blah" [ "foo
        COMMENT_STARTING: S++, // <!-
        COMMENT: S++, // <!--
        COMMENT_ENDING: S++, // <!-- blah -
        COMMENT_ENDED: S++, // <!-- blah --
        CDATA: S++, // <![CDATA[ something
        CDATA_ENDING: S++, // ]
        CDATA_ENDING_2: S++, // ]]
        PROC_INST: S++, // <?hi
        PROC_INST_BODY: S++, // <?hi there
        PROC_INST_ENDING: S++, // <?hi "there" ?
        OPEN_TAG: S++, // <strong
        OPEN_TAG_SLASH: S++, // <strong /
        ATTRIB: S++, // <a
        ATTRIB_NAME: S++, // <a foo
        ATTRIB_NAME_SAW_WHITE: S++, // <a foo _
        ATTRIB_VALUE: S++, // <a foo=
        ATTRIB_VALUE_QUOTED: S++, // <a foo="bar
        ATTRIB_VALUE_CLOSED: S++, // <a foo="bar"
        ATTRIB_VALUE_UNQUOTED: S++, // <a foo=bar
        ATTRIB_VALUE_ENTITY_Q: S++, // <foo bar="&quot;"
        ATTRIB_VALUE_ENTITY_U: S++, // <foo bar=&quot
        CLOSE_TAG: S++, // </a
        CLOSE_TAG_SAW_WHITE: S++, // </a   >
        SCRIPT: S++, // <script> ...
        SCRIPT_ENDING: S++ // <script> ... <
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      sax.XML_ENTITIES = {
        'amp': '&',
        'gt': '>',
        'lt': '<',
        'quot': '"',
        'apos': "'"
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    222244 222245 222246 222247 222248 222249 222250 222251 222252 222253 222254 222255 222256 222257 222258 222259 222260 222261 222262 222263 222264 222265 222266 222267 222268 222269 222270 222271 222272 222273 222274 222275 222276 222277 222278 222279 222280 222281 222282 222283 222284 222285 222286 222287 222288 222289 222290 222291 222292 222293 222294 222295 222296 222297 222298 222299 222300 222301 222302 222303 222304 222305 222306 222307 222308 222309 222310 222311 222312 222313 222314 222315 222316 222317 222318 222319 222320 222321 222322 222323 222324 222325 222326 222327 222328 222329 222330 222331 222332 222333 222334 222335 222336 222337 222338 222339 222340 222341 222342 222343 222344 222345 222346 222347 222348 222349 222350 222351 222352 222353 222354 222355 222356 222357 222358 222359 222360 222361 222362 222363 222364 222365 222366 222367 222368 222369 222370 222371 222372 222373 222374 222375 222376 222377 222378 222379 222380 222381 222382 222383 222384 222385 222386 222387 222388 222389 222390 222391 222392 222393 222394 222395 222396 222397 222398 222399 222400 222401 222402 222403 222404 222405 222406 222407 222408 222409 222410 222411 222412 222413 222414 222415 222416 222417 222418 222419 222420 222421 222422 222423 222424 222425 222426 222427 222428 222429 222430 222431 222432 222433 222434 222435 222436 222437 222438 222439 222440 222441 222442 222443 222444 222445 222446 222447 222448 222449 222450 222451 222452 222453 222454 222455 222456 222457 222458 222459 222460 222461 222462 222463 222464 222465 222466 222467 222468 222469 222470 222471 222472 222473 222474 222475 222476 222477 222478 222479 222480 222481 222482 222483 222484 222485 222486 222487 222488 222489 222490 222491 222492 222493 222494 222495 222496 222497 222498
      sax.ENTITIES = {
        'amp': '&',
        'gt': '>',
        'lt': '<',
        'quot': '"',
        'apos': "'",
        'AElig': 198,
        'Aacute': 193,
        'Acirc': 194,
        'Agrave': 192,
        'Aring': 197,
        'Atilde': 195,
        'Auml': 196,
        'Ccedil': 199,
        'ETH': 208,
        'Eacute': 201,
        'Ecirc': 202,
        'Egrave': 200,
        'Euml': 203,
        'Iacute': 205,
        'Icirc': 206,
        'Igrave': 204,
        'Iuml': 207,
        'Ntilde': 209,
        'Oacute': 211,
        'Ocirc': 212,
        'Ograve': 210,
        'Oslash': 216,
        'Otilde': 213,
        'Ouml': 214,
        'THORN': 222,
        'Uacute': 218,
        'Ucirc': 219,
        'Ugrave': 217,
        'Uuml': 220,
        'Yacute': 221,
        'aacute': 225,
        'acirc': 226,
        'aelig': 230,
        'agrave': 224,
        'aring': 229,
        'atilde': 227,
        'auml': 228,
        'ccedil': 231,
        'eacute': 233,
        'ecirc': 234,
        'egrave': 232,
        'eth': 240,
        'euml': 235,
        'iacute': 237,
        'icirc': 238,
        'igrave': 236,
        'iuml': 239,
        'ntilde': 241,
        'oacute': 243,
        'ocirc': 244,
        'ograve': 242,
        'oslash': 248,
        'otilde': 245,
        'ouml': 246,
        'szlig': 223,
        'thorn': 254,
        'uacute': 250,
        'ucirc': 251,
        'ugrave': 249,
        'uuml': 252,
        'yacute': 253,
        'yuml': 255,
        'copy': 169,
        'reg': 174,
        'nbsp': 160,
        'iexcl': 161,
        'cent': 162,
        'pound': 163,
        'curren': 164,
        'yen': 165,
        'brvbar': 166,
        'sect': 167,
        'uml': 168,
        'ordf': 170,
        'laquo': 171,
        'not': 172,
        'shy': 173,
        'macr': 175,
        'deg': 176,
        'plusmn': 177,
        'sup1': 185,
        'sup2': 178,
        'sup3': 179,
        'acute': 180,
        'micro': 181,
        'para': 182,
        'middot': 183,
        'cedil': 184,
        'ordm': 186,
        'raquo': 187,
        'frac14': 188,
        'frac12': 189,
        'frac34': 190,
        'iquest': 191,
        'times': 215,
        'divide': 247,
        'OElig': 338,
        'oelig': 339,
        'Scaron': 352,
        'scaron': 353,
        'Yuml': 376,
        'fnof': 402,
        'circ': 710,
        'tilde': 732,
        'Alpha': 913,
        'Beta': 914,
        'Gamma': 915,
        'Delta': 916,
        'Epsilon': 917,
        'Zeta': 918,
        'Eta': 919,
        'Theta': 920,
        'Iota': 921,
        'Kappa': 922,
        'Lambda': 923,
        'Mu': 924,
        'Nu': 925,
        'Xi': 926,
        'Omicron': 927,
        'Pi': 928,
        'Rho': 929,
        'Sigma': 931,
        'Tau': 932,
        'Upsilon': 933,
        'Phi': 934,
        'Chi': 935,
        'Psi': 936,
        'Omega': 937,
        'alpha': 945,
        'beta': 946,
        'gamma': 947,
        'delta': 948,
        'epsilon': 949,
        'zeta': 950,
        'eta': 951,
        'theta': 952,
        'iota': 953,
        'kappa': 954,
        'lambda': 955,
        'mu': 956,
        'nu': 957,
        'xi': 958,
        'omicron': 959,
        'pi': 960,
        'rho': 961,
        'sigmaf': 962,
        'sigma': 963,
        'tau': 964,
        'upsilon': 965,
        'phi': 966,
        'chi': 967,
        'psi': 968,
        'omega': 969,
        'thetasym': 977,
        'upsih': 978,
        'piv': 982,
        'ensp': 8194,
        'emsp': 8195,
        'thinsp': 8201,
        'zwnj': 8204,
        'zwj': 8205,
        'lrm': 8206,
        'rlm': 8207,
        'ndash': 8211,
        'mdash': 8212,
        'lsquo': 8216,
        'rsquo': 8217,
        'sbquo': 8218,
        'ldquo': 8220,
        'rdquo': 8221,
        'bdquo': 8222,
        'dagger': 8224,
        'Dagger': 8225,
        'bull': 8226,
        'hellip': 8230,
        'permil': 8240,
        'prime': 8242,
        'Prime': 8243,
        'lsaquo': 8249,
        'rsaquo': 8250,
        'oline': 8254,
        'frasl': 8260,
        'euro': 8364,
        'image': 8465,
        'weierp': 8472,
        'real': 8476,
        'trade': 8482,
        'alefsym': 8501,
        'larr': 8592,
        'uarr': 8593,
        'rarr': 8594,
        'darr': 8595,
        'harr': 8596,
        'crarr': 8629,
        'lArr': 8656,
        'uArr': 8657,
        'rArr': 8658,
        'dArr': 8659,
        'hArr': 8660,
        'forall': 8704,
        'part': 8706,
        'exist': 8707,
        'empty': 8709,
        'nabla': 8711,
        'isin': 8712,
        'notin': 8713,
        'ni': 8715,
        'prod': 8719,
        'sum': 8721,
        'minus': 8722,
        'lowast': 8727,
        'radic': 8730,
        'prop': 8733,
        'infin': 8734,
        'ang': 8736,
        'and': 8743,
        'or': 8744,
        'cap': 8745,
        'cup': 8746,
        'int': 8747,
        'there4': 8756,
        'sim': 8764,
        'cong': 8773,
        'asymp': 8776,
        'ne': 8800,
        'equiv': 8801,
        'le': 8804,
        'ge': 8805,
        'sub': 8834,
        'sup': 8835,
        'nsub': 8836,
        'sube': 8838,
        'supe': 8839,
        'oplus': 8853,
        'otimes': 8855,
        'perp': 8869,
        'sdot': 8901,
        'lceil': 8968,
        'rceil': 8969,
        'lfloor': 8970,
        'rfloor': 8971,
        'lang': 9001,
        'rang': 9002,
        'loz': 9674,
        'spades': 9824,
        'clubs': 9827,
        'hearts': 9829,
        'diams': 9830
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      Object.keys(sax.ENTITIES).forEach(function (key) {
        var e = sax.ENTITIES[key]
        var s = typeof e === 'number' ? String.fromCharCode(e) : e
        sax.ENTITIES[key] = s
      })
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      for (var s in sax.STATE) {
        sax.STATE[sax.STATE[s]] = s
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      // shorthand
      S = sax.STATE
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function emit (parser, event, data) {
        parser[event] && parser[event](data)
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function emitNode (parser, nodeType, data) {
        if (parser.textNode) closeText(parser)
        emit(parser, nodeType, data)
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function closeText (parser) {
        parser.textNode = textopts(parser.opt, parser.textNode)
        if (parser.textNode) emit(parser, 'ontext', parser.textNode)
        parser.textNode = ''
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function textopts (opt, text) {
        if (opt.trim) text = text.trim()
        if (opt.normalize) text = text.replace(/\s+/g, ' ')
        return text
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function error (parser, er) {
        closeText(parser)
        if (parser.trackPosition) {
          er += '\nLine: ' + parser.line +
            '\nColumn: ' + parser.column +
            '\nChar: ' + parser.c
        }
        er = new Error(er)
        parser.error = er
        emit(parser, 'onerror', er)
        return parser
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function end (parser) {
        if (parser.sawRoot && !parser.closedRoot) strictFail(parser, 'Unclosed root tag')
        if ((parser.state !== S.BEGIN) &&
          (parser.state !== S.BEGIN_WHITESPACE) &&
          (parser.state !== S.TEXT)) {
          error(parser, 'Unexpected end')
        }
        closeText(parser)
        parser.c = ''
        parser.closed = true
        emit(parser, 'onend')
        SAXParser.call(parser, parser.strict, parser.opt)
        return parser
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function strictFail (parser, message) {
        if (typeof parser !== 'object' || !(parser instanceof SAXParser)) {
          throw new Error('bad call to strictFail')
        }
        if (parser.strict) {
          error(parser, message)
        }
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function newTag (parser) {
        if (!parser.strict) parser.tagName = parser.tagName[parser.looseCase]()
        var parent = parser.tags[parser.tags.length - 1] || parser
        var tag = parser.tag = { name: parser.tagName, attributes: {} }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        // will be overridden if tag contails an xmlns="foo" or xmlns:foo="bar"
        if (parser.opt.xmlns) {
          tag.ns = parent.ns
        }
        parser.attribList.length = 0
        emitNode(parser, 'onopentagstart', tag)
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function qname (name, attribute) {
        var i = name.indexOf(':')
        var qualName = i < 0 ? [ '', name ] : name.split(':')
        var prefix = qualName[0]
        var local = qualName[1]
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        // <x "xmlns"="http://foo">
        if (attribute && name === 'xmlns') {
          prefix = 'xmlns'
          local = ''
        }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        return { prefix: prefix, local: local }
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function attrib (parser) {
        if (!parser.strict) {
          parser.attribName = parser.attribName[parser.looseCase]()
        }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        if (parser.attribList.indexOf(parser.attribName) !== -1 ||
          parser.tag.attributes.hasOwnProperty(parser.attribName)) {
          parser.attribName = parser.attribValue = ''
          return
        }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        if (parser.opt.xmlns) {
          var qn = qname(parser.attribName, true)
          var prefix = qn.prefix
          var local = qn.local
    
          if (prefix === 'xmlns') {
            // namespace binding attribute. push the binding into scope
            if (local === 'xml' && parser.attribValue !== XML_NAMESPACE) {
              strictFail(parser,
                'xml: prefix must be bound to ' + XML_NAMESPACE + '\n' +
                'Actual: ' + parser.attribValue)
            } else if (local === 'xmlns' && parser.attribValue !== XMLNS_NAMESPACE) {
              strictFail(parser,
                'xmlns: prefix must be bound to ' + XMLNS_NAMESPACE + '\n' +
                'Actual: ' + parser.attribValue)
            } else {
              var tag = parser.tag
              var parent = parser.tags[parser.tags.length - 1] || parser
              if (tag.ns === parent.ns) {
                tag.ns = Object.create(parent.ns)
              }
              tag.ns[local] = parser.attribValue
            }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
          }
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
          // defer onattribute events until all attributes have been seen
          // so any new bindings can take effect. preserve attribute order
          // so deferred events can be emitted in document order
          parser.attribList.push([parser.attribName, parser.attribValue])
        } else {
          // in non-xmlns mode, we can emit the event right away
          parser.tag.attributes[parser.attribName] = parser.attribValue
          emitNode(parser, 'onattribute', {
            name: parser.attribName,
            value: parser.attribValue
          })
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        parser.attribName = parser.attribValue = ''
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function openTag (parser, selfClosing) {
        if (parser.opt.xmlns) {
          // emit namespace binding events
          var tag = parser.tag
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
          // add namespace info to tag
          var qn = qname(parser.tagName)
          tag.prefix = qn.prefix
          tag.local = qn.local
          tag.uri = tag.ns[qn.prefix] || ''
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
          if (tag.prefix && !tag.uri) {
            strictFail(parser, 'Unbound namespace prefix: ' +
              JSON.stringify(parser.tagName))
            tag.uri = qn.prefix
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
          var parent = parser.tags[parser.tags.length - 1] || parser
          if (tag.ns && parent.ns !== tag.ns) {
            Object.keys(tag.ns).forEach(function (p) {
              emitNode(parser, 'onopennamespace', {
                prefix: p,
                uri: tag.ns[p]
              })
            })
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
          // handle deferred onattribute events
          // Note: do not apply default ns to attributes:
          //   http://www.w3.org/TR/REC-xml-names/#defaulting
          for (var i = 0, l = parser.attribList.length; i < l; i++) {
            var nv = parser.attribList[i]
            var name = nv[0]
            var value = nv[1]
            var qualName = qname(name, true)
            var prefix = qualName.prefix
            var local = qualName.local
            var uri = prefix === '' ? '' : (tag.ns[prefix] || '')
            var a = {
              name: name,
              value: value,
              prefix: prefix,
              local: local,
              uri: uri
            }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            // if there's any attributes with an undefined namespace,
            // then fail on them now.
            if (prefix && prefix !== 'xmlns' && !uri) {
              strictFail(parser, 'Unbound namespace prefix: ' +
                JSON.stringify(prefix))
              a.uri = prefix
            }
            parser.tag.attributes[name] = a
            emitNode(parser, 'onattribute', a)
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
          }
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
          parser.attribList.length = 0
        }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        parser.tag.isSelfClosing = !!selfClosing
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        // process the tag
        parser.sawRoot = true
        parser.tags.push(parser.tag)
        emitNode(parser, 'onopentag', parser.tag)
        if (!selfClosing) {
          // special case for <script> in non-strict mode.
          if (!parser.noscript && parser.tagName.toLowerCase() === 'script') {
            parser.state = S.SCRIPT
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
          } else {
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            parser.state = S.TEXT
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
          }
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
          parser.tag = null
          parser.tagName = ''
        }
        parser.attribName = parser.attribValue = ''
        parser.attribList.length = 0
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function closeTag (parser) {
        if (!parser.tagName) {
          strictFail(parser, 'Weird empty close tag.')
          parser.textNode += '</>'
          parser.state = S.TEXT
          return
        }
    
        if (parser.script) {
          if (parser.tagName !== 'script') {
            parser.script += '</' + parser.tagName + '>'
            parser.tagName = ''
            parser.state = S.SCRIPT
            return
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
          }
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
          emitNode(parser, 'onscript', parser.script)
          parser.script = ''
        }
    
        // first make sure that the closing tag actually exists.
        // <a><b></c></b></a> will close everything, otherwise.
        var t = parser.tags.length
        var tagName = parser.tagName
        if (!parser.strict) {
          tagName = tagName[parser.looseCase]()
        }
        var closeTo = tagName
        while (t--) {
          var close = parser.tags[t]
          if (close.name !== closeTo) {
            // fail the first time in strict mode
            strictFail(parser, 'Unexpected close tag')
          } else {
            break
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
          }
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        }
    
        // didn't find it.  we already failed for strict, so just abort.
        if (t < 0) {
          strictFail(parser, 'Unmatched closing tag: ' + parser.tagName)
          parser.textNode += '</' + parser.tagName + '>'
          parser.state = S.TEXT
          return
        }
        parser.tagName = tagName
        var s = parser.tags.length
        while (s-- > t) {
          var tag = parser.tag = parser.tags.pop()
          parser.tagName = parser.tag.name
          emitNode(parser, 'onclosetag', parser.tagName)
    
          var x = {}
          for (var i in tag.ns) {
            x[i] = tag.ns[i]
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
          var parent = parser.tags[parser.tags.length - 1] || parser
          if (parser.opt.xmlns && tag.ns !== parent.ns) {
            // remove namespace bindings introduced by tag
            Object.keys(tag.ns).forEach(function (p) {
              var n = tag.ns[p]
              emitNode(parser, 'onclosenamespace', { prefix: p, uri: n })
            })
          }
        }
        if (t === 0) parser.closedRoot = true
        parser.tagName = parser.attribValue = parser.attribName = ''
        parser.attribList.length = 0
        parser.state = S.TEXT
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function parseEntity (parser) {
        var entity = parser.entity
        var entityLC = entity.toLowerCase()
        var num
        var numStr = ''
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        if (parser.ENTITIES[entity]) {
          return parser.ENTITIES[entity]
        }
        if (parser.ENTITIES[entityLC]) {
          return parser.ENTITIES[entityLC]
        }
        entity = entityLC
        if (entity.charAt(0) === '#') {
          if (entity.charAt(1) === 'x') {
            entity = entity.slice(2)
            num = parseInt(entity, 16)
            numStr = num.toString(16)
          } else {
            entity = entity.slice(1)
            num = parseInt(entity, 10)
            numStr = num.toString(10)
          }
        }
        entity = entity.replace(/^0+/, '')
        if (isNaN(num) || numStr.toLowerCase() !== entity) {
          strictFail(parser, 'Invalid character entity')
          return '&' + parser.entity + ';'
        }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        return String.fromCodePoint(num)
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function beginWhiteSpace (parser, c) {
        if (c === '<') {
          parser.state = S.OPEN_WAKA
          parser.startTagPosition = parser.position
        } else if (!isWhitespace(c)) {
          // have to process this as a text node.
          // weird, but happens.
          strictFail(parser, 'Non-whitespace before first tag.')
          parser.textNode = c
          parser.state = S.TEXT
        }
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function charAt (chunk, i) {
        var result = ''
        if (i < chunk.length) {
          result = chunk.charAt(i)
        }
        return result
      }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      function write (chunk) {
        var parser = this
        if (this.error) {
          throw this.error
        }
        if (parser.closed) {
          return error(parser,
            'Cannot write after close. Assign an onready handler.')
        }
        if (chunk === null) {
          return end(parser)
        }
        if (typeof chunk === 'object') {
          chunk = chunk.toString()
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
        }
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        var i = 0
        var c = ''
        while (true) {
          c = charAt(chunk, i++)
          parser.c = c
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
          if (!c) {
            break
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
          if (parser.trackPosition) {
            parser.position++
            if (c === '\n') {
              parser.line++
              parser.column = 0
            } else {
              parser.column++
            }
          }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
          switch (parser.state) {
            case S.BEGIN:
              parser.state = S.BEGIN_WHITESPACE
              if (c === '\uFEFF') {
                continue
              }
              beginWhiteSpace(parser, c)
              continue
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            case S.BEGIN_WHITESPACE:
              beginWhiteSpace(parser, c)
              continue
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            case S.TEXT:
              if (parser.sawRoot && !parser.closedRoot) {
                var starti = i - 1
                while (c && c !== '<' && c !== '&') {
                  c = charAt(chunk, i++)
                  if (c && parser.trackPosition) {
                    parser.position++
                    if (c === '\n') {
                      parser.line++
                      parser.column = 0
                    } else {
                      parser.column++
                    }
                  }
                }
                parser.textNode += chunk.substring(starti, i - 1)
              }
              if (c === '<' && !(parser.sawRoot && parser.closedRoot && !parser.strict)) {
                parser.state = S.OPEN_WAKA
                parser.startTagPosition = parser.position
              } else {
                if (!isWhitespace(c) && (!parser.sawRoot || parser.closedRoot)) {
                  strictFail(parser, 'Text data outside of root node.')
                }
                if (c === '&') {
                  parser.state = S.TEXT_ENTITY
                } else {
                  parser.textNode += c
                }
              }
              continue
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            case S.SCRIPT:
              // only non-strict
              if (c === '<') {
                parser.state = S.SCRIPT_ENDING
              } else {
                parser.script += c
              }
              continue
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            case S.SCRIPT_ENDING:
              if (c === '/') {
                parser.state = S.CLOSE_TAG
              } else {
                parser.script += '<' + c
                parser.state = S.SCRIPT
              }
              continue
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            case S.OPEN_WAKA:
              // either a /, ?, !, or text is coming next.
              if (c === '!') {
                parser.state = S.SGML_DECL
                parser.sgmlDecl = ''
              } else if (isWhitespace(c)) {
                // wait for it...
              } else if (isMatch(nameStart, c)) {
                parser.state = S.OPEN_TAG
                parser.tagName = c
              } else if (c === '/') {
                parser.state = S.CLOSE_TAG
                parser.tagName = ''
              } else if (c === '?') {
                parser.state = S.PROC_INST
                parser.procInstName = parser.procInstBody = ''
              } else {
                strictFail(parser, 'Unencoded <')
                // if there was some whitespace, then add that in.
                if (parser.startTagPosition + 1 < parser.position) {
                  var pad = parser.position - parser.startTagPosition
                  c = new Array(pad).join(' ') + c
                }
                parser.textNode += '<' + c
                parser.state = S.TEXT
              }
              continue
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            case S.SGML_DECL:
              if ((parser.sgmlDecl + c).toUpperCase() === CDATA) {
                emitNode(parser, 'onopencdata')
                parser.state = S.CDATA
                parser.sgmlDecl = ''
                parser.cdata = ''
              } else if (parser.sgmlDecl + c === '--') {
                parser.state = S.COMMENT
                parser.comment = ''
                parser.sgmlDecl = ''
              } else if ((parser.sgmlDecl + c).toUpperCase() === DOCTYPE) {
                parser.state = S.DOCTYPE
                if (parser.doctype || parser.sawRoot) {
                  strictFail(parser,
                    'Inappropriately located doctype declaration')
                }
                parser.doctype = ''
                parser.sgmlDecl = ''
              } else if (c === '>') {
                emitNode(parser, 'onsgmldeclaration', parser.sgmlDecl)