You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
19763 lines
746 KiB
19763 lines
746 KiB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.cheerio = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
'use strict'
|
|
|
|
exports.byteLength = byteLength
|
|
exports.toByteArray = toByteArray
|
|
exports.fromByteArray = fromByteArray
|
|
|
|
var lookup = []
|
|
var revLookup = []
|
|
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
|
|
|
|
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
|
for (var i = 0, len = code.length; i < len; ++i) {
|
|
lookup[i] = code[i]
|
|
revLookup[code.charCodeAt(i)] = i
|
|
}
|
|
|
|
// Support decoding URL-safe base64 strings, as Node.js does.
|
|
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
|
|
revLookup['-'.charCodeAt(0)] = 62
|
|
revLookup['_'.charCodeAt(0)] = 63
|
|
|
|
function getLens (b64) {
|
|
var len = b64.length
|
|
|
|
if (len % 4 > 0) {
|
|
throw new Error('Invalid string. Length must be a multiple of 4')
|
|
}
|
|
|
|
// Trim off extra bytes after placeholder bytes are found
|
|
// See: https://github.com/beatgammit/base64-js/issues/42
|
|
var validLen = b64.indexOf('=')
|
|
if (validLen === -1) validLen = len
|
|
|
|
var placeHoldersLen = validLen === len
|
|
? 0
|
|
: 4 - (validLen % 4)
|
|
|
|
return [validLen, placeHoldersLen]
|
|
}
|
|
|
|
// base64 is 4/3 + up to two characters of the original data
|
|
function byteLength (b64) {
|
|
var lens = getLens(b64)
|
|
var validLen = lens[0]
|
|
var placeHoldersLen = lens[1]
|
|
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
|
|
}
|
|
|
|
function _byteLength (b64, validLen, placeHoldersLen) {
|
|
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
|
|
}
|
|
|
|
function toByteArray (b64) {
|
|
var tmp
|
|
var lens = getLens(b64)
|
|
var validLen = lens[0]
|
|
var placeHoldersLen = lens[1]
|
|
|
|
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
|
|
|
|
var curByte = 0
|
|
|
|
// if there are placeholders, only get up to the last complete 4 chars
|
|
var len = placeHoldersLen > 0
|
|
? validLen - 4
|
|
: validLen
|
|
|
|
var i
|
|
for (i = 0; i < len; i += 4) {
|
|
tmp =
|
|
(revLookup[b64.charCodeAt(i)] << 18) |
|
|
(revLookup[b64.charCodeAt(i + 1)] << 12) |
|
|
(revLookup[b64.charCodeAt(i + 2)] << 6) |
|
|
revLookup[b64.charCodeAt(i + 3)]
|
|
arr[curByte++] = (tmp >> 16) & 0xFF
|
|
arr[curByte++] = (tmp >> 8) & 0xFF
|
|
arr[curByte++] = tmp & 0xFF
|
|
}
|
|
|
|
if (placeHoldersLen === 2) {
|
|
tmp =
|
|
(revLookup[b64.charCodeAt(i)] << 2) |
|
|
(revLookup[b64.charCodeAt(i + 1)] >> 4)
|
|
arr[curByte++] = tmp & 0xFF
|
|
}
|
|
|
|
if (placeHoldersLen === 1) {
|
|
tmp =
|
|
(revLookup[b64.charCodeAt(i)] << 10) |
|
|
(revLookup[b64.charCodeAt(i + 1)] << 4) |
|
|
(revLookup[b64.charCodeAt(i + 2)] >> 2)
|
|
arr[curByte++] = (tmp >> 8) & 0xFF
|
|
arr[curByte++] = tmp & 0xFF
|
|
}
|
|
|
|
return arr
|
|
}
|
|
|
|
function tripletToBase64 (num) {
|
|
return lookup[num >> 18 & 0x3F] +
|
|
lookup[num >> 12 & 0x3F] +
|
|
lookup[num >> 6 & 0x3F] +
|
|
lookup[num & 0x3F]
|
|
}
|
|
|
|
function encodeChunk (uint8, start, end) {
|
|
var tmp
|
|
var output = []
|
|
for (var i = start; i < end; i += 3) {
|
|
tmp =
|
|
((uint8[i] << 16) & 0xFF0000) +
|
|
((uint8[i + 1] << 8) & 0xFF00) +
|
|
(uint8[i + 2] & 0xFF)
|
|
output.push(tripletToBase64(tmp))
|
|
}
|
|
return output.join('')
|
|
}
|
|
|
|
function fromByteArray (uint8) {
|
|
var tmp
|
|
var len = uint8.length
|
|
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
|
|
var parts = []
|
|
var maxChunkLength = 16383 // must be multiple of 3
|
|
|
|
// go through the array every three bytes, we'll deal with trailing stuff later
|
|
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
|
|
parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
|
|
}
|
|
|
|
// pad the end with zeros, but make sure to not forget the extra bytes
|
|
if (extraBytes === 1) {
|
|
tmp = uint8[len - 1]
|
|
parts.push(
|
|
lookup[tmp >> 2] +
|
|
lookup[(tmp << 4) & 0x3F] +
|
|
'=='
|
|
)
|
|
} else if (extraBytes === 2) {
|
|
tmp = (uint8[len - 2] << 8) + uint8[len - 1]
|
|
parts.push(
|
|
lookup[tmp >> 10] +
|
|
lookup[(tmp >> 4) & 0x3F] +
|
|
lookup[(tmp << 2) & 0x3F] +
|
|
'='
|
|
)
|
|
}
|
|
|
|
return parts.join('')
|
|
}
|
|
|
|
},{}],2:[function(require,module,exports){
|
|
module.exports = {
|
|
trueFunc: function trueFunc(){
|
|
return true;
|
|
},
|
|
falseFunc: function falseFunc(){
|
|
return false;
|
|
}
|
|
};
|
|
},{}],3:[function(require,module,exports){
|
|
(function (Buffer){(function (){
|
|
/*!
|
|
* The buffer module from node.js, for the browser.
|
|
*
|
|
* @author Feross Aboukhadijeh <https://feross.org>
|
|
* @license MIT
|
|
*/
|
|
/* eslint-disable no-proto */
|
|
|
|
'use strict'
|
|
|
|
var base64 = require('base64-js')
|
|
var ieee754 = require('ieee754')
|
|
|
|
exports.Buffer = Buffer
|
|
exports.SlowBuffer = SlowBuffer
|
|
exports.INSPECT_MAX_BYTES = 50
|
|
|
|
var K_MAX_LENGTH = 0x7fffffff
|
|
exports.kMaxLength = K_MAX_LENGTH
|
|
|
|
/**
|
|
* If `Buffer.TYPED_ARRAY_SUPPORT`:
|
|
* === true Use Uint8Array implementation (fastest)
|
|
* === false Print warning and recommend using `buffer` v4.x which has an Object
|
|
* implementation (most compatible, even IE6)
|
|
*
|
|
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
|
|
* Opera 11.6+, iOS 4.2+.
|
|
*
|
|
* We report that the browser does not support typed arrays if the are not subclassable
|
|
* using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
|
|
* (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
|
|
* for __proto__ and has a buggy typed array implementation.
|
|
*/
|
|
Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()
|
|
|
|
if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&
|
|
typeof console.error === 'function') {
|
|
console.error(
|
|
'This browser lacks typed array (Uint8Array) support which is required by ' +
|
|
'`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
|
|
)
|
|
}
|
|
|
|
function typedArraySupport () {
|
|
// Can typed array instances can be augmented?
|
|
try {
|
|
var arr = new Uint8Array(1)
|
|
arr.__proto__ = { __proto__: Uint8Array.prototype, foo: function () { return 42 } }
|
|
return arr.foo() === 42
|
|
} catch (e) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
Object.defineProperty(Buffer.prototype, 'parent', {
|
|
enumerable: true,
|
|
get: function () {
|
|
if (!Buffer.isBuffer(this)) return undefined
|
|
return this.buffer
|
|
}
|
|
})
|
|
|
|
Object.defineProperty(Buffer.prototype, 'offset', {
|
|
enumerable: true,
|
|
get: function () {
|
|
if (!Buffer.isBuffer(this)) return undefined
|
|
return this.byteOffset
|
|
}
|
|
})
|
|
|
|
function createBuffer (length) {
|
|
if (length > K_MAX_LENGTH) {
|
|
throw new RangeError('The value "' + length + '" is invalid for option "size"')
|
|
}
|
|
// Return an augmented `Uint8Array` instance
|
|
var buf = new Uint8Array(length)
|
|
buf.__proto__ = Buffer.prototype
|
|
return buf
|
|
}
|
|
|
|
/**
|
|
* The Buffer constructor returns instances of `Uint8Array` that have their
|
|
* prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
|
|
* `Uint8Array`, so the returned instances will have all the node `Buffer` methods
|
|
* and the `Uint8Array` methods. Square bracket notation works as expected -- it
|
|
* returns a single octet.
|
|
*
|
|
* The `Uint8Array` prototype remains unmodified.
|
|
*/
|
|
|
|
function Buffer (arg, encodingOrOffset, length) {
|
|
// Common case.
|
|
if (typeof arg === 'number') {
|
|
if (typeof encodingOrOffset === 'string') {
|
|
throw new TypeError(
|
|
'The "string" argument must be of type string. Received type number'
|
|
)
|
|
}
|
|
return allocUnsafe(arg)
|
|
}
|
|
return from(arg, encodingOrOffset, length)
|
|
}
|
|
|
|
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
|
|
if (typeof Symbol !== 'undefined' && Symbol.species != null &&
|
|
Buffer[Symbol.species] === Buffer) {
|
|
Object.defineProperty(Buffer, Symbol.species, {
|
|
value: null,
|
|
configurable: true,
|
|
enumerable: false,
|
|
writable: false
|
|
})
|
|
}
|
|
|
|
Buffer.poolSize = 8192 // not used by this implementation
|
|
|
|
function from (value, encodingOrOffset, length) {
|
|
if (typeof value === 'string') {
|
|
return fromString(value, encodingOrOffset)
|
|
}
|
|
|
|
if (ArrayBuffer.isView(value)) {
|
|
return fromArrayLike(value)
|
|
}
|
|
|
|
if (value == null) {
|
|
throw TypeError(
|
|
'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
|
|
'or Array-like Object. Received type ' + (typeof value)
|
|
)
|
|
}
|
|
|
|
if (isInstance(value, ArrayBuffer) ||
|
|
(value && isInstance(value.buffer, ArrayBuffer))) {
|
|
return fromArrayBuffer(value, encodingOrOffset, length)
|
|
}
|
|
|
|
if (typeof value === 'number') {
|
|
throw new TypeError(
|
|
'The "value" argument must not be of type number. Received type number'
|
|
)
|
|
}
|
|
|
|
var valueOf = value.valueOf && value.valueOf()
|
|
if (valueOf != null && valueOf !== value) {
|
|
return Buffer.from(valueOf, encodingOrOffset, length)
|
|
}
|
|
|
|
var b = fromObject(value)
|
|
if (b) return b
|
|
|
|
if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&
|
|
typeof value[Symbol.toPrimitive] === 'function') {
|
|
return Buffer.from(
|
|
value[Symbol.toPrimitive]('string'), encodingOrOffset, length
|
|
)
|
|
}
|
|
|
|
throw new TypeError(
|
|
'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
|
|
'or Array-like Object. Received type ' + (typeof value)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
|
|
* if value is a number.
|
|
* Buffer.from(str[, encoding])
|
|
* Buffer.from(array)
|
|
* Buffer.from(buffer)
|
|
* Buffer.from(arrayBuffer[, byteOffset[, length]])
|
|
**/
|
|
Buffer.from = function (value, encodingOrOffset, length) {
|
|
return from(value, encodingOrOffset, length)
|
|
}
|
|
|
|
// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
|
|
// https://github.com/feross/buffer/pull/148
|
|
Buffer.prototype.__proto__ = Uint8Array.prototype
|
|
Buffer.__proto__ = Uint8Array
|
|
|
|
function assertSize (size) {
|
|
if (typeof size !== 'number') {
|
|
throw new TypeError('"size" argument must be of type number')
|
|
} else if (size < 0) {
|
|
throw new RangeError('The value "' + size + '" is invalid for option "size"')
|
|
}
|
|
}
|
|
|
|
function alloc (size, fill, encoding) {
|
|
assertSize(size)
|
|
if (size <= 0) {
|
|
return createBuffer(size)
|
|
}
|
|
if (fill !== undefined) {
|
|
// Only pay attention to encoding if it's a string. This
|
|
// prevents accidentally sending in a number that would
|
|
// be interpretted as a start offset.
|
|
return typeof encoding === 'string'
|
|
? createBuffer(size).fill(fill, encoding)
|
|
: createBuffer(size).fill(fill)
|
|
}
|
|
return createBuffer(size)
|
|
}
|
|
|
|
/**
|
|
* Creates a new filled Buffer instance.
|
|
* alloc(size[, fill[, encoding]])
|
|
**/
|
|
Buffer.alloc = function (size, fill, encoding) {
|
|
return alloc(size, fill, encoding)
|
|
}
|
|
|
|
function allocUnsafe (size) {
|
|
assertSize(size)
|
|
return createBuffer(size < 0 ? 0 : checked(size) | 0)
|
|
}
|
|
|
|
/**
|
|
* Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
|
|
* */
|
|
Buffer.allocUnsafe = function (size) {
|
|
return allocUnsafe(size)
|
|
}
|
|
/**
|
|
* Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
|
|
*/
|
|
Buffer.allocUnsafeSlow = function (size) {
|
|
return allocUnsafe(size)
|
|
}
|
|
|
|
function fromString (string, encoding) {
|
|
if (typeof encoding !== 'string' || encoding === '') {
|
|
encoding = 'utf8'
|
|
}
|
|
|
|
if (!Buffer.isEncoding(encoding)) {
|
|
throw new TypeError('Unknown encoding: ' + encoding)
|
|
}
|
|
|
|
var length = byteLength(string, encoding) | 0
|
|
var buf = createBuffer(length)
|
|
|
|
var actual = buf.write(string, encoding)
|
|
|
|
if (actual !== length) {
|
|
// Writing a hex string, for example, that contains invalid characters will
|
|
// cause everything after the first invalid character to be ignored. (e.g.
|
|
// 'abxxcd' will be treated as 'ab')
|
|
buf = buf.slice(0, actual)
|
|
}
|
|
|
|
return buf
|
|
}
|
|
|
|
function fromArrayLike (array) {
|
|
var length = array.length < 0 ? 0 : checked(array.length) | 0
|
|
var buf = createBuffer(length)
|
|
for (var i = 0; i < length; i += 1) {
|
|
buf[i] = array[i] & 255
|
|
}
|
|
return buf
|
|
}
|
|
|
|
function fromArrayBuffer (array, byteOffset, length) {
|
|
if (byteOffset < 0 || array.byteLength < byteOffset) {
|
|
throw new RangeError('"offset" is outside of buffer bounds')
|
|
}
|
|
|
|
if (array.byteLength < byteOffset + (length || 0)) {
|
|
throw new RangeError('"length" is outside of buffer bounds')
|
|
}
|
|
|
|
var buf
|
|
if (byteOffset === undefined && length === undefined) {
|
|
buf = new Uint8Array(array)
|
|
} else if (length === undefined) {
|
|
buf = new Uint8Array(array, byteOffset)
|
|
} else {
|
|
buf = new Uint8Array(array, byteOffset, length)
|
|
}
|
|
|
|
// Return an augmented `Uint8Array` instance
|
|
buf.__proto__ = Buffer.prototype
|
|
return buf
|
|
}
|
|
|
|
function fromObject (obj) {
|
|
if (Buffer.isBuffer(obj)) {
|
|
var len = checked(obj.length) | 0
|
|
var buf = createBuffer(len)
|
|
|
|
if (buf.length === 0) {
|
|
return buf
|
|
}
|
|
|
|
obj.copy(buf, 0, 0, len)
|
|
return buf
|
|
}
|
|
|
|
if (obj.length !== undefined) {
|
|
if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
|
|
return createBuffer(0)
|
|
}
|
|
return fromArrayLike(obj)
|
|
}
|
|
|
|
if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
|
|
return fromArrayLike(obj.data)
|
|
}
|
|
}
|
|
|
|
function checked (length) {
|
|
// Note: cannot use `length < K_MAX_LENGTH` here because that fails when
|
|
// length is NaN (which is otherwise coerced to zero.)
|
|
if (length >= K_MAX_LENGTH) {
|
|
throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
|
|
'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')
|
|
}
|
|
return length | 0
|
|
}
|
|
|
|
function SlowBuffer (length) {
|
|
if (+length != length) { // eslint-disable-line eqeqeq
|
|
length = 0
|
|
}
|
|
return Buffer.alloc(+length)
|
|
}
|
|
|
|
Buffer.isBuffer = function isBuffer (b) {
|
|
return b != null && b._isBuffer === true &&
|
|
b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false
|
|
}
|
|
|
|
Buffer.compare = function compare (a, b) {
|
|
if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength)
|
|
if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength)
|
|
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
|
|
throw new TypeError(
|
|
'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'
|
|
)
|
|
}
|
|
|
|
if (a === b) return 0
|
|
|
|
var x = a.length
|
|
var y = b.length
|
|
|
|
for (var i = 0, len = Math.min(x, y); i < len; ++i) {
|
|
if (a[i] !== b[i]) {
|
|
x = a[i]
|
|
y = b[i]
|
|
break
|
|
}
|
|
}
|
|
|
|
if (x < y) return -1
|
|
if (y < x) return 1
|
|
return 0
|
|
}
|
|
|
|
Buffer.isEncoding = function isEncoding (encoding) {
|
|
switch (String(encoding).toLowerCase()) {
|
|
case 'hex':
|
|
case 'utf8':
|
|
case 'utf-8':
|
|
case 'ascii':
|
|
case 'latin1':
|
|
case 'binary':
|
|
case 'base64':
|
|
case 'ucs2':
|
|
case 'ucs-2':
|
|
case 'utf16le':
|
|
case 'utf-16le':
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
Buffer.concat = function concat (list, length) {
|
|
if (!Array.isArray(list)) {
|
|
throw new TypeError('"list" argument must be an Array of Buffers')
|
|
}
|
|
|
|
if (list.length === 0) {
|
|
return Buffer.alloc(0)
|
|
}
|
|
|
|
var i
|
|
if (length === undefined) {
|
|
length = 0
|
|
for (i = 0; i < list.length; ++i) {
|
|
length += list[i].length
|
|
}
|
|
}
|
|
|
|
var buffer = Buffer.allocUnsafe(length)
|
|
var pos = 0
|
|
for (i = 0; i < list.length; ++i) {
|
|
var buf = list[i]
|
|
if (isInstance(buf, Uint8Array)) {
|
|
buf = Buffer.from(buf)
|
|
}
|
|
if (!Buffer.isBuffer(buf)) {
|
|
throw new TypeError('"list" argument must be an Array of Buffers')
|
|
}
|
|
buf.copy(buffer, pos)
|
|
pos += buf.length
|
|
}
|
|
return buffer
|
|
}
|
|
|
|
function byteLength (string, encoding) {
|
|
if (Buffer.isBuffer(string)) {
|
|
return string.length
|
|
}
|
|
if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
|
|
return string.byteLength
|
|
}
|
|
if (typeof string !== 'string') {
|
|
throw new TypeError(
|
|
'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +
|
|
'Received type ' + typeof string
|
|
)
|
|
}
|
|
|
|
var len = string.length
|
|
var mustMatch = (arguments.length > 2 && arguments[2] === true)
|
|
if (!mustMatch && len === 0) return 0
|
|
|
|
// Use a for loop to avoid recursion
|
|
var loweredCase = false
|
|
for (;;) {
|
|
switch (encoding) {
|
|
case 'ascii':
|
|
case 'latin1':
|
|
case 'binary':
|
|
return len
|
|
case 'utf8':
|
|
case 'utf-8':
|
|
return utf8ToBytes(string).length
|
|
case 'ucs2':
|
|
case 'ucs-2':
|
|
case 'utf16le':
|
|
case 'utf-16le':
|
|
return len * 2
|
|
case 'hex':
|
|
return len >>> 1
|
|
case 'base64':
|
|
return base64ToBytes(string).length
|
|
default:
|
|
if (loweredCase) {
|
|
return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8
|
|
}
|
|
encoding = ('' + encoding).toLowerCase()
|
|
loweredCase = true
|
|
}
|
|
}
|
|
}
|
|
Buffer.byteLength = byteLength
|
|
|
|
function slowToString (encoding, start, end) {
|
|
var loweredCase = false
|
|
|
|
// No need to verify that "this.length <= MAX_UINT32" since it's a read-only
|
|
// property of a typed array.
|
|
|
|
// This behaves neither like String nor Uint8Array in that we set start/end
|
|
// to their upper/lower bounds if the value passed is out of range.
|
|
// undefined is handled specially as per ECMA-262 6th Edition,
|
|
// Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
|
|
if (start === undefined || start < 0) {
|
|
start = 0
|
|
}
|
|
// Return early if start > this.length. Done here to prevent potential uint32
|
|
// coercion fail below.
|
|
if (start > this.length) {
|
|
return ''
|
|
}
|
|
|
|
if (end === undefined || end > this.length) {
|
|
end = this.length
|
|
}
|
|
|
|
if (end <= 0) {
|
|
return ''
|
|
}
|
|
|
|
// Force coersion to uint32. This will also coerce falsey/NaN values to 0.
|
|
end >>>= 0
|
|
start >>>= 0
|
|
|
|
if (end <= start) {
|
|
return ''
|
|
}
|
|
|
|
if (!encoding) encoding = 'utf8'
|
|
|
|
while (true) {
|
|
switch (encoding) {
|
|
case 'hex':
|
|
return hexSlice(this, start, end)
|
|
|
|
case 'utf8':
|
|
case 'utf-8':
|
|
return utf8Slice(this, start, end)
|
|
|
|
case 'ascii':
|
|
return asciiSlice(this, start, end)
|
|
|
|
case 'latin1':
|
|
case 'binary':
|
|
return latin1Slice(this, start, end)
|
|
|
|
case 'base64':
|
|
return base64Slice(this, start, end)
|
|
|
|
case 'ucs2':
|
|
case 'ucs-2':
|
|
case 'utf16le':
|
|
case 'utf-16le':
|
|
return utf16leSlice(this, start, end)
|
|
|
|
default:
|
|
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
|
|
encoding = (encoding + '').toLowerCase()
|
|
loweredCase = true
|
|
}
|
|
}
|
|
}
|
|
|
|
// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
|
|
// to detect a Buffer instance. It's not possible to use `instanceof Buffer`
|
|
// reliably in a browserify context because there could be multiple different
|
|
// copies of the 'buffer' package in use. This method works even for Buffer
|
|
// instances that were created from another copy of the `buffer` package.
|
|
// See: https://github.com/feross/buffer/issues/154
|
|
Buffer.prototype._isBuffer = true
|
|
|
|
function swap (b, n, m) {
|
|
var i = b[n]
|
|
b[n] = b[m]
|
|
b[m] = i
|
|
}
|
|
|
|
Buffer.prototype.swap16 = function swap16 () {
|
|
var len = this.length
|
|
if (len % 2 !== 0) {
|
|
throw new RangeError('Buffer size must be a multiple of 16-bits')
|
|
}
|
|
for (var i = 0; i < len; i += 2) {
|
|
swap(this, i, i + 1)
|
|
}
|
|
return this
|
|
}
|
|
|
|
Buffer.prototype.swap32 = function swap32 () {
|
|
var len = this.length
|
|
if (len % 4 !== 0) {
|
|
throw new RangeError('Buffer size must be a multiple of 32-bits')
|
|
}
|
|
for (var i = 0; i < len; i += 4) {
|
|
swap(this, i, i + 3)
|
|
swap(this, i + 1, i + 2)
|
|
}
|
|
return this
|
|
}
|
|
|
|
Buffer.prototype.swap64 = function swap64 () {
|
|
var len = this.length
|
|
if (len % 8 !== 0) {
|
|
throw new RangeError('Buffer size must be a multiple of 64-bits')
|
|
}
|
|
for (var i = 0; i < len; i += 8) {
|
|
swap(this, i, i + 7)
|
|
swap(this, i + 1, i + 6)
|
|
swap(this, i + 2, i + 5)
|
|
swap(this, i + 3, i + 4)
|
|
}
|
|
return this
|
|
}
|
|
|
|
Buffer.prototype.toString = function toString () {
|
|
var length = this.length
|
|
if (length === 0) return ''
|
|
if (arguments.length === 0) return utf8Slice(this, 0, length)
|
|
return slowToString.apply(this, arguments)
|
|
}
|
|
|
|
Buffer.prototype.toLocaleString = Buffer.prototype.toString
|
|
|
|
Buffer.prototype.equals = function equals (b) {
|
|
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
|
|
if (this === b) return true
|
|
return Buffer.compare(this, b) === 0
|
|
}
|
|
|
|
Buffer.prototype.inspect = function inspect () {
|
|
var str = ''
|
|
var max = exports.INSPECT_MAX_BYTES
|
|
str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim()
|
|
if (this.length > max) str += ' ... '
|
|
return '<Buffer ' + str + '>'
|
|
}
|
|
|
|
Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
|
|
if (isInstance(target, Uint8Array)) {
|
|
target = Buffer.from(target, target.offset, target.byteLength)
|
|
}
|
|
if (!Buffer.isBuffer(target)) {
|
|
throw new TypeError(
|
|
'The "target" argument must be one of type Buffer or Uint8Array. ' +
|
|
'Received type ' + (typeof target)
|
|
)
|
|
}
|
|
|
|
if (start === undefined) {
|
|
start = 0
|
|
}
|
|
if (end === undefined) {
|
|
end = target ? target.length : 0
|
|
}
|
|
if (thisStart === undefined) {
|
|
thisStart = 0
|
|
}
|
|
if (thisEnd === undefined) {
|
|
thisEnd = this.length
|
|
}
|
|
|
|
if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
|
|
throw new RangeError('out of range index')
|
|
}
|
|
|
|
if (thisStart >= thisEnd && start >= end) {
|
|
return 0
|
|
}
|
|
if (thisStart >= thisEnd) {
|
|
return -1
|
|
}
|
|
if (start >= end) {
|
|
return 1
|
|
}
|
|
|
|
start >>>= 0
|
|
end >>>= 0
|
|
thisStart >>>= 0
|
|
thisEnd >>>= 0
|
|
|
|
if (this === target) return 0
|
|
|
|
var x = thisEnd - thisStart
|
|
var y = end - start
|
|
var len = Math.min(x, y)
|
|
|
|
var thisCopy = this.slice(thisStart, thisEnd)
|
|
var targetCopy = target.slice(start, end)
|
|
|
|
for (var i = 0; i < len; ++i) {
|
|
if (thisCopy[i] !== targetCopy[i]) {
|
|
x = thisCopy[i]
|
|
y = targetCopy[i]
|
|
break
|
|
}
|
|
}
|
|
|
|
if (x < y) return -1
|
|
if (y < x) return 1
|
|
return 0
|
|
}
|
|
|
|
// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
|
|
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
|
|
//
|
|
// Arguments:
|
|
// - buffer - a Buffer to search
|
|
// - val - a string, Buffer, or number
|
|
// - byteOffset - an index into `buffer`; will be clamped to an int32
|
|
// - encoding - an optional encoding, relevant is val is a string
|
|
// - dir - true for indexOf, false for lastIndexOf
|
|
function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
|
|
// Empty buffer means no match
|
|
if (buffer.length === 0) return -1
|
|
|
|
// Normalize byteOffset
|
|
if (typeof byteOffset === 'string') {
|
|
encoding = byteOffset
|
|
byteOffset = 0
|
|
} else if (byteOffset > 0x7fffffff) {
|
|
byteOffset = 0x7fffffff
|
|
} else if (byteOffset < -0x80000000) {
|
|
byteOffset = -0x80000000
|
|
}
|
|
byteOffset = +byteOffset // Coerce to Number.
|
|
if (numberIsNaN(byteOffset)) {
|
|
// byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
|
|
byteOffset = dir ? 0 : (buffer.length - 1)
|
|
}
|
|
|
|
// Normalize byteOffset: negative offsets start from the end of the buffer
|
|
if (byteOffset < 0) byteOffset = buffer.length + byteOffset
|
|
if (byteOffset >= buffer.length) {
|
|
if (dir) return -1
|
|
else byteOffset = buffer.length - 1
|
|
} else if (byteOffset < 0) {
|
|
if (dir) byteOffset = 0
|
|
else return -1
|
|
}
|
|
|
|
// Normalize val
|
|
if (typeof val === 'string') {
|
|
val = Buffer.from(val, encoding)
|
|
}
|
|
|
|
// Finally, search either indexOf (if dir is true) or lastIndexOf
|
|
if (Buffer.isBuffer(val)) {
|
|
// Special case: looking for empty string/buffer always fails
|
|
if (val.length === 0) {
|
|
return -1
|
|
}
|
|
return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
|
|
} else if (typeof val === 'number') {
|
|
val = val & 0xFF // Search for a byte value [0-255]
|
|
if (typeof Uint8Array.prototype.indexOf === 'function') {
|
|
if (dir) {
|
|
return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
|
|
} else {
|
|
return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
|
|
}
|
|
}
|
|
return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
|
|
}
|
|
|
|
throw new TypeError('val must be string, number or Buffer')
|
|
}
|
|
|
|
function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
|
|
var indexSize = 1
|
|
var arrLength = arr.length
|
|
var valLength = val.length
|
|
|
|
if (encoding !== undefined) {
|
|
encoding = String(encoding).toLowerCase()
|
|
if (encoding === 'ucs2' || encoding === 'ucs-2' ||
|
|
encoding === 'utf16le' || encoding === 'utf-16le') {
|
|
if (arr.length < 2 || val.length < 2) {
|
|
return -1
|
|
}
|
|
indexSize = 2
|
|
arrLength /= 2
|
|
valLength /= 2
|
|
byteOffset /= 2
|
|
}
|
|
}
|
|
|
|
function read (buf, i) {
|
|
if (indexSize === 1) {
|
|
return buf[i]
|
|
} else {
|
|
return buf.readUInt16BE(i * indexSize)
|
|
}
|
|
}
|
|
|
|
var i
|
|
if (dir) {
|
|
var foundIndex = -1
|
|
for (i = byteOffset; i < arrLength; i++) {
|
|
if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
|
|
if (foundIndex === -1) foundIndex = i
|
|
if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
|
|
} else {
|
|
if (foundIndex !== -1) i -= i - foundIndex
|
|
foundIndex = -1
|
|
}
|
|
}
|
|
} else {
|
|
if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
|
|
for (i = byteOffset; i >= 0; i--) {
|
|
var found = true
|
|
for (var j = 0; j < valLength; j++) {
|
|
if (read(arr, i + j) !== read(val, j)) {
|
|
found = false
|
|
break
|
|
}
|
|
}
|
|
if (found) return i
|
|
}
|
|
}
|
|
|
|
return -1
|
|
}
|
|
|
|
Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
|
|
return this.indexOf(val, byteOffset, encoding) !== -1
|
|
}
|
|
|
|
Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
|
|
return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
|
|
}
|
|
|
|
Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
|
|
return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
|
|
}
|
|
|
|
function hexWrite (buf, string, offset, length) {
|
|
offset = Number(offset) || 0
|
|
var remaining = buf.length - offset
|
|
if (!length) {
|
|
length = remaining
|
|
} else {
|
|
length = Number(length)
|
|
if (length > remaining) {
|
|
length = remaining
|
|
}
|
|
}
|
|
|
|
var strLen = string.length
|
|
|
|
if (length > strLen / 2) {
|
|
length = strLen / 2
|
|
}
|
|
for (var i = 0; i < length; ++i) {
|
|
var parsed = parseInt(string.substr(i * 2, 2), 16)
|
|
if (numberIsNaN(parsed)) return i
|
|
buf[offset + i] = parsed
|
|
}
|
|
return i
|
|
}
|
|
|
|
function utf8Write (buf, string, offset, length) {
|
|
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
|
|
}
|
|
|
|
function asciiWrite (buf, string, offset, length) {
|
|
return blitBuffer(asciiToBytes(string), buf, offset, length)
|
|
}
|
|
|
|
function latin1Write (buf, string, offset, length) {
|
|
return asciiWrite(buf, string, offset, length)
|
|
}
|
|
|
|
function base64Write (buf, string, offset, length) {
|
|
return blitBuffer(base64ToBytes(string), buf, offset, length)
|
|
}
|
|
|
|
function ucs2Write (buf, string, offset, length) {
|
|
return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
|
|
}
|
|
|
|
Buffer.prototype.write = function write (string, offset, length, encoding) {
|
|
// Buffer#write(string)
|
|
if (offset === undefined) {
|
|
encoding = 'utf8'
|
|
length = this.length
|
|
offset = 0
|
|
// Buffer#write(string, encoding)
|
|
} else if (length === undefined && typeof offset === 'string') {
|
|
encoding = offset
|
|
length = this.length
|
|
offset = 0
|
|
// Buffer#write(string, offset[, length][, encoding])
|
|
} else if (isFinite(offset)) {
|
|
offset = offset >>> 0
|
|
if (isFinite(length)) {
|
|
length = length >>> 0
|
|
if (encoding === undefined) encoding = 'utf8'
|
|
} else {
|
|
encoding = length
|
|
length = undefined
|
|
}
|
|
} else {
|
|
throw new Error(
|
|
'Buffer.write(string, encoding, offset[, length]) is no longer supported'
|
|
)
|
|
}
|
|
|
|
var remaining = this.length - offset
|
|
if (length === undefined || length > remaining) length = remaining
|
|
|
|
if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
|
|
throw new RangeError('Attempt to write outside buffer bounds')
|
|
}
|
|
|
|
if (!encoding) encoding = 'utf8'
|
|
|
|
var loweredCase = false
|
|
for (;;) {
|
|
switch (encoding) {
|
|
case 'hex':
|
|
return hexWrite(this, string, offset, length)
|
|
|
|
case 'utf8':
|
|
case 'utf-8':
|
|
return utf8Write(this, string, offset, length)
|
|
|
|
case 'ascii':
|
|
return asciiWrite(this, string, offset, length)
|
|
|
|
case 'latin1':
|
|
case 'binary':
|
|
return latin1Write(this, string, offset, length)
|
|
|
|
case 'base64':
|
|
// Warning: maxLength not taken into account in base64Write
|
|
return base64Write(this, string, offset, length)
|
|
|
|
case 'ucs2':
|
|
case 'ucs-2':
|
|
case 'utf16le':
|
|
case 'utf-16le':
|
|
return ucs2Write(this, string, offset, length)
|
|
|
|
default:
|
|
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
|
|
encoding = ('' + encoding).toLowerCase()
|
|
loweredCase = true
|
|
}
|
|
}
|
|
}
|
|
|
|
Buffer.prototype.toJSON = function toJSON () {
|
|
return {
|
|
type: 'Buffer',
|
|
data: Array.prototype.slice.call(this._arr || this, 0)
|
|
}
|
|
}
|
|
|
|
function base64Slice (buf, start, end) {
|
|
if (start === 0 && end === buf.length) {
|
|
return base64.fromByteArray(buf)
|
|
} else {
|
|
return base64.fromByteArray(buf.slice(start, end))
|
|
}
|
|
}
|
|
|
|
function utf8Slice (buf, start, end) {
|
|
end = Math.min(buf.length, end)
|
|
var res = []
|
|
|
|
var i = start
|
|
while (i < end) {
|
|
var firstByte = buf[i]
|
|
var codePoint = null
|
|
var bytesPerSequence = (firstByte > 0xEF) ? 4
|
|
: (firstByte > 0xDF) ? 3
|
|
: (firstByte > 0xBF) ? 2
|
|
: 1
|
|
|
|
if (i + bytesPerSequence <= end) {
|
|
var secondByte, thirdByte, fourthByte, tempCodePoint
|
|
|
|
switch (bytesPerSequence) {
|
|
case 1:
|
|
if (firstByte < 0x80) {
|
|
codePoint = firstByte
|
|
}
|
|
break
|
|
case 2:
|
|
secondByte = buf[i + 1]
|
|
if ((secondByte & 0xC0) === 0x80) {
|
|
tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
|
|
if (tempCodePoint > 0x7F) {
|
|
codePoint = tempCodePoint
|
|
}
|
|
}
|
|
break
|
|
case 3:
|
|
secondByte = buf[i + 1]
|
|
thirdByte = buf[i + 2]
|
|
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
|
|
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
|
|
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
|
|
codePoint = tempCodePoint
|
|
}
|
|
}
|
|
break
|
|
case 4:
|
|
secondByte = buf[i + 1]
|
|
thirdByte = buf[i + 2]
|
|
fourthByte = buf[i + 3]
|
|
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
|
|
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
|
|
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
|
|
codePoint = tempCodePoint
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (codePoint === null) {
|
|
// we did not generate a valid codePoint so insert a
|
|
// replacement char (U+FFFD) and advance only 1 byte
|
|
codePoint = 0xFFFD
|
|
bytesPerSequence = 1
|
|
} else if (codePoint > 0xFFFF) {
|
|
// encode to utf16 (surrogate pair dance)
|
|
codePoint -= 0x10000
|
|
res.push(codePoint >>> 10 & 0x3FF | 0xD800)
|
|
codePoint = 0xDC00 | codePoint & 0x3FF
|
|
}
|
|
|
|
res.push(codePoint)
|
|
i += bytesPerSequence
|
|
}
|
|
|
|
return decodeCodePointsArray(res)
|
|
}
|
|
|
|
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
|
|
// the lowest limit is Chrome, with 0x10000 args.
|
|
// We go 1 magnitude less, for safety
|
|
var MAX_ARGUMENTS_LENGTH = 0x1000
|
|
|
|
function decodeCodePointsArray (codePoints) {
|
|
var len = codePoints.length
|
|
if (len <= MAX_ARGUMENTS_LENGTH) {
|
|
return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
|
|
}
|
|
|
|
// Decode in chunks to avoid "call stack size exceeded".
|
|
var res = ''
|
|
var i = 0
|
|
while (i < len) {
|
|
res += String.fromCharCode.apply(
|
|
String,
|
|
codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
|
|
)
|
|
}
|
|
return res
|
|
}
|
|
|
|
function asciiSlice (buf, start, end) {
|
|
var ret = ''
|
|
end = Math.min(buf.length, end)
|
|
|
|
for (var i = start; i < end; ++i) {
|
|
ret += String.fromCharCode(buf[i] & 0x7F)
|
|
}
|
|
return ret
|
|
}
|
|
|
|
function latin1Slice (buf, start, end) {
|
|
var ret = ''
|
|
end = Math.min(buf.length, end)
|
|
|
|
for (var i = start; i < end; ++i) {
|
|
ret += String.fromCharCode(buf[i])
|
|
}
|
|
return ret
|
|
}
|
|
|
|
function hexSlice (buf, start, end) {
|
|
var len = buf.length
|
|
|
|
if (!start || start < 0) start = 0
|
|
if (!end || end < 0 || end > len) end = len
|
|
|
|
var out = ''
|
|
for (var i = start; i < end; ++i) {
|
|
out += toHex(buf[i])
|
|
}
|
|
return out
|
|
}
|
|
|
|
function utf16leSlice (buf, start, end) {
|
|
var bytes = buf.slice(start, end)
|
|
var res = ''
|
|
for (var i = 0; i < bytes.length; i += 2) {
|
|
res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))
|
|
}
|
|
return res
|
|
}
|
|
|
|
Buffer.prototype.slice = function slice (start, end) {
|
|
var len = this.length
|
|
start = ~~start
|
|
end = end === undefined ? len : ~~end
|
|
|
|
if (start < 0) {
|
|
start += len
|
|
if (start < 0) start = 0
|
|
} else if (start > len) {
|
|
start = len
|
|
}
|
|
|
|
if (end < 0) {
|
|
end += len
|
|
if (end < 0) end = 0
|
|
} else if (end > len) {
|
|
end = len
|
|
}
|
|
|
|
if (end < start) end = start
|
|
|
|
var newBuf = this.subarray(start, end)
|
|
// Return an augmented `Uint8Array` instance
|
|
newBuf.__proto__ = Buffer.prototype
|
|
return newBuf
|
|
}
|
|
|
|
/*
|
|
* Need to make sure that buffer isn't trying to write out of bounds.
|
|
*/
|
|
function checkOffset (offset, ext, length) {
|
|
if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
|
|
if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
|
|
}
|
|
|
|
Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
|
|
offset = offset >>> 0
|
|
byteLength = byteLength >>> 0
|
|
if (!noAssert) checkOffset(offset, byteLength, this.length)
|
|
|
|
var val = this[offset]
|
|
var mul = 1
|
|
var i = 0
|
|
while (++i < byteLength && (mul *= 0x100)) {
|
|
val += this[offset + i] * mul
|
|
}
|
|
|
|
return val
|
|
}
|
|
|
|
Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
|
|
offset = offset >>> 0
|
|
byteLength = byteLength >>> 0
|
|
if (!noAssert) {
|
|
checkOffset(offset, byteLength, this.length)
|
|
}
|
|
|
|
var val = this[offset + --byteLength]
|
|
var mul = 1
|
|
while (byteLength > 0 && (mul *= 0x100)) {
|
|
val += this[offset + --byteLength] * mul
|
|
}
|
|
|
|
return val
|
|
}
|
|
|
|
Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 1, this.length)
|
|
return this[offset]
|
|
}
|
|
|
|
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 2, this.length)
|
|
return this[offset] | (this[offset + 1] << 8)
|
|
}
|
|
|
|
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 2, this.length)
|
|
return (this[offset] << 8) | this[offset + 1]
|
|
}
|
|
|
|
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 4, this.length)
|
|
|
|
return ((this[offset]) |
|
|
(this[offset + 1] << 8) |
|
|
(this[offset + 2] << 16)) +
|
|
(this[offset + 3] * 0x1000000)
|
|
}
|
|
|
|
Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 4, this.length)
|
|
|
|
return (this[offset] * 0x1000000) +
|
|
((this[offset + 1] << 16) |
|
|
(this[offset + 2] << 8) |
|
|
this[offset + 3])
|
|
}
|
|
|
|
Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
|
|
offset = offset >>> 0
|
|
byteLength = byteLength >>> 0
|
|
if (!noAssert) checkOffset(offset, byteLength, this.length)
|
|
|
|
var val = this[offset]
|
|
var mul = 1
|
|
var i = 0
|
|
while (++i < byteLength && (mul *= 0x100)) {
|
|
val += this[offset + i] * mul
|
|
}
|
|
mul *= 0x80
|
|
|
|
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
|
|
|
|
return val
|
|
}
|
|
|
|
Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
|
|
offset = offset >>> 0
|
|
byteLength = byteLength >>> 0
|
|
if (!noAssert) checkOffset(offset, byteLength, this.length)
|
|
|
|
var i = byteLength
|
|
var mul = 1
|
|
var val = this[offset + --i]
|
|
while (i > 0 && (mul *= 0x100)) {
|
|
val += this[offset + --i] * mul
|
|
}
|
|
mul *= 0x80
|
|
|
|
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
|
|
|
|
return val
|
|
}
|
|
|
|
Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 1, this.length)
|
|
if (!(this[offset] & 0x80)) return (this[offset])
|
|
return ((0xff - this[offset] + 1) * -1)
|
|
}
|
|
|
|
Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 2, this.length)
|
|
var val = this[offset] | (this[offset + 1] << 8)
|
|
return (val & 0x8000) ? val | 0xFFFF0000 : val
|
|
}
|
|
|
|
Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 2, this.length)
|
|
var val = this[offset + 1] | (this[offset] << 8)
|
|
return (val & 0x8000) ? val | 0xFFFF0000 : val
|
|
}
|
|
|
|
Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 4, this.length)
|
|
|
|
return (this[offset]) |
|
|
(this[offset + 1] << 8) |
|
|
(this[offset + 2] << 16) |
|
|
(this[offset + 3] << 24)
|
|
}
|
|
|
|
Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 4, this.length)
|
|
|
|
return (this[offset] << 24) |
|
|
(this[offset + 1] << 16) |
|
|
(this[offset + 2] << 8) |
|
|
(this[offset + 3])
|
|
}
|
|
|
|
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 4, this.length)
|
|
return ieee754.read(this, offset, true, 23, 4)
|
|
}
|
|
|
|
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 4, this.length)
|
|
return ieee754.read(this, offset, false, 23, 4)
|
|
}
|
|
|
|
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 8, this.length)
|
|
return ieee754.read(this, offset, true, 52, 8)
|
|
}
|
|
|
|
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 8, this.length)
|
|
return ieee754.read(this, offset, false, 52, 8)
|
|
}
|
|
|
|
function checkInt (buf, value, offset, ext, max, min) {
|
|
if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
|
|
if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
|
|
if (offset + ext > buf.length) throw new RangeError('Index out of range')
|
|
}
|
|
|
|
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
byteLength = byteLength >>> 0
|
|
if (!noAssert) {
|
|
var maxBytes = Math.pow(2, 8 * byteLength) - 1
|
|
checkInt(this, value, offset, byteLength, maxBytes, 0)
|
|
}
|
|
|
|
var mul = 1
|
|
var i = 0
|
|
this[offset] = value & 0xFF
|
|
while (++i < byteLength && (mul *= 0x100)) {
|
|
this[offset + i] = (value / mul) & 0xFF
|
|
}
|
|
|
|
return offset + byteLength
|
|
}
|
|
|
|
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
byteLength = byteLength >>> 0
|
|
if (!noAssert) {
|
|
var maxBytes = Math.pow(2, 8 * byteLength) - 1
|
|
checkInt(this, value, offset, byteLength, maxBytes, 0)
|
|
}
|
|
|
|
var i = byteLength - 1
|
|
var mul = 1
|
|
this[offset + i] = value & 0xFF
|
|
while (--i >= 0 && (mul *= 0x100)) {
|
|
this[offset + i] = (value / mul) & 0xFF
|
|
}
|
|
|
|
return offset + byteLength
|
|
}
|
|
|
|
Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
|
|
this[offset] = (value & 0xff)
|
|
return offset + 1
|
|
}
|
|
|
|
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
|
|
this[offset] = (value & 0xff)
|
|
this[offset + 1] = (value >>> 8)
|
|
return offset + 2
|
|
}
|
|
|
|
Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
|
|
this[offset] = (value >>> 8)
|
|
this[offset + 1] = (value & 0xff)
|
|
return offset + 2
|
|
}
|
|
|
|
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
|
|
this[offset + 3] = (value >>> 24)
|
|
this[offset + 2] = (value >>> 16)
|
|
this[offset + 1] = (value >>> 8)
|
|
this[offset] = (value & 0xff)
|
|
return offset + 4
|
|
}
|
|
|
|
Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
|
|
this[offset] = (value >>> 24)
|
|
this[offset + 1] = (value >>> 16)
|
|
this[offset + 2] = (value >>> 8)
|
|
this[offset + 3] = (value & 0xff)
|
|
return offset + 4
|
|
}
|
|
|
|
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) {
|
|
var limit = Math.pow(2, (8 * byteLength) - 1)
|
|
|
|
checkInt(this, value, offset, byteLength, limit - 1, -limit)
|
|
}
|
|
|
|
var i = 0
|
|
var mul = 1
|
|
var sub = 0
|
|
this[offset] = value & 0xFF
|
|
while (++i < byteLength && (mul *= 0x100)) {
|
|
if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
|
|
sub = 1
|
|
}
|
|
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
|
|
}
|
|
|
|
return offset + byteLength
|
|
}
|
|
|
|
Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) {
|
|
var limit = Math.pow(2, (8 * byteLength) - 1)
|
|
|
|
checkInt(this, value, offset, byteLength, limit - 1, -limit)
|
|
}
|
|
|
|
var i = byteLength - 1
|
|
var mul = 1
|
|
var sub = 0
|
|
this[offset + i] = value & 0xFF
|
|
while (--i >= 0 && (mul *= 0x100)) {
|
|
if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
|
|
sub = 1
|
|
}
|
|
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
|
|
}
|
|
|
|
return offset + byteLength
|
|
}
|
|
|
|
Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
|
|
if (value < 0) value = 0xff + value + 1
|
|
this[offset] = (value & 0xff)
|
|
return offset + 1
|
|
}
|
|
|
|
Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
|
|
this[offset] = (value & 0xff)
|
|
this[offset + 1] = (value >>> 8)
|
|
return offset + 2
|
|
}
|
|
|
|
Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
|
|
this[offset] = (value >>> 8)
|
|
this[offset + 1] = (value & 0xff)
|
|
return offset + 2
|
|
}
|
|
|
|
Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
|
|
this[offset] = (value & 0xff)
|
|
this[offset + 1] = (value >>> 8)
|
|
this[offset + 2] = (value >>> 16)
|
|
this[offset + 3] = (value >>> 24)
|
|
return offset + 4
|
|
}
|
|
|
|
Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
|
|
if (value < 0) value = 0xffffffff + value + 1
|
|
this[offset] = (value >>> 24)
|
|
this[offset + 1] = (value >>> 16)
|
|
this[offset + 2] = (value >>> 8)
|
|
this[offset + 3] = (value & 0xff)
|
|
return offset + 4
|
|
}
|
|
|
|
function checkIEEE754 (buf, value, offset, ext, max, min) {
|
|
if (offset + ext > buf.length) throw new RangeError('Index out of range')
|
|
if (offset < 0) throw new RangeError('Index out of range')
|
|
}
|
|
|
|
function writeFloat (buf, value, offset, littleEndian, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) {
|
|
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
|
|
}
|
|
ieee754.write(buf, value, offset, littleEndian, 23, 4)
|
|
return offset + 4
|
|
}
|
|
|
|
Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
|
|
return writeFloat(this, value, offset, true, noAssert)
|
|
}
|
|
|
|
Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
|
|
return writeFloat(this, value, offset, false, noAssert)
|
|
}
|
|
|
|
function writeDouble (buf, value, offset, littleEndian, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) {
|
|
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
|
|
}
|
|
ieee754.write(buf, value, offset, littleEndian, 52, 8)
|
|
return offset + 8
|
|
}
|
|
|
|
Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
|
|
return writeDouble(this, value, offset, true, noAssert)
|
|
}
|
|
|
|
Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
|
|
return writeDouble(this, value, offset, false, noAssert)
|
|
}
|
|
|
|
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
|
|
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
|
|
if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')
|
|
if (!start) start = 0
|
|
if (!end && end !== 0) end = this.length
|
|
if (targetStart >= target.length) targetStart = target.length
|
|
if (!targetStart) targetStart = 0
|
|
if (end > 0 && end < start) end = start
|
|
|
|
// Copy 0 bytes; we're done
|
|
if (end === start) return 0
|
|
if (target.length === 0 || this.length === 0) return 0
|
|
|
|
// Fatal error conditions
|
|
if (targetStart < 0) {
|
|
throw new RangeError('targetStart out of bounds')
|
|
}
|
|
if (start < 0 || start >= this.length) throw new RangeError('Index out of range')
|
|
if (end < 0) throw new RangeError('sourceEnd out of bounds')
|
|
|
|
// Are we oob?
|
|
if (end > this.length) end = this.length
|
|
if (target.length - targetStart < end - start) {
|
|
end = target.length - targetStart + start
|
|
}
|
|
|
|
var len = end - start
|
|
|
|
if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
|
|
// Use built-in when available, missing from IE11
|
|
this.copyWithin(targetStart, start, end)
|
|
} else if (this === target && start < targetStart && targetStart < end) {
|
|
// descending copy from end
|
|
for (var i = len - 1; i >= 0; --i) {
|
|
target[i + targetStart] = this[i + start]
|
|
}
|
|
} else {
|
|
Uint8Array.prototype.set.call(
|
|
target,
|
|
this.subarray(start, end),
|
|
targetStart
|
|
)
|
|
}
|
|
|
|
return len
|
|
}
|
|
|
|
// Usage:
|
|
// buffer.fill(number[, offset[, end]])
|
|
// buffer.fill(buffer[, offset[, end]])
|
|
// buffer.fill(string[, offset[, end]][, encoding])
|
|
Buffer.prototype.fill = function fill (val, start, end, encoding) {
|
|
// Handle string cases:
|
|
if (typeof val === 'string') {
|
|
if (typeof start === 'string') {
|
|
encoding = start
|
|
start = 0
|
|
end = this.length
|
|
} else if (typeof end === 'string') {
|
|
encoding = end
|
|
end = this.length
|
|
}
|
|
if (encoding !== undefined && typeof encoding !== 'string') {
|
|
throw new TypeError('encoding must be a string')
|
|
}
|
|
if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
|
|
throw new TypeError('Unknown encoding: ' + encoding)
|
|
}
|
|
if (val.length === 1) {
|
|
var code = val.charCodeAt(0)
|
|
if ((encoding === 'utf8' && code < 128) ||
|
|
encoding === 'latin1') {
|
|
// Fast path: If `val` fits into a single byte, use that numeric value.
|
|
val = code
|
|
}
|
|
}
|
|
} else if (typeof val === 'number') {
|
|
val = val & 255
|
|
}
|
|
|
|
// Invalid ranges are not set to a default, so can range check early.
|
|
if (start < 0 || this.length < start || this.length < end) {
|
|
throw new RangeError('Out of range index')
|
|
}
|
|
|
|
if (end <= start) {
|
|
return this
|
|
}
|
|
|
|
start = start >>> 0
|
|
end = end === undefined ? this.length : end >>> 0
|
|
|
|
if (!val) val = 0
|
|
|
|
var i
|
|
if (typeof val === 'number') {
|
|
for (i = start; i < end; ++i) {
|
|
this[i] = val
|
|
}
|
|
} else {
|
|
var bytes = Buffer.isBuffer(val)
|
|
? val
|
|
: Buffer.from(val, encoding)
|
|
var len = bytes.length
|
|
if (len === 0) {
|
|
throw new TypeError('The value "' + val +
|
|
'" is invalid for argument "value"')
|
|
}
|
|
for (i = 0; i < end - start; ++i) {
|
|
this[i + start] = bytes[i % len]
|
|
}
|
|
}
|
|
|
|
return this
|
|
}
|
|
|
|
// HELPER FUNCTIONS
|
|
// ================
|
|
|
|
var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g
|
|
|
|
function base64clean (str) {
|
|
// Node takes equal signs as end of the Base64 encoding
|
|
str = str.split('=')[0]
|
|
// Node strips out invalid characters like \n and \t from the string, base64-js does not
|
|
str = str.trim().replace(INVALID_BASE64_RE, '')
|
|
// Node converts strings with length < 2 to ''
|
|
if (str.length < 2) return ''
|
|
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
|
|
while (str.length % 4 !== 0) {
|
|
str = str + '='
|
|
}
|
|
return str
|
|
}
|
|
|
|
function toHex (n) {
|
|
if (n < 16) return '0' + n.toString(16)
|
|
return n.toString(16)
|
|
}
|
|
|
|
function utf8ToBytes (string, units) {
|
|
units = units || Infinity
|
|
var codePoint
|
|
var length = string.length
|
|
var leadSurrogate = null
|
|
var bytes = []
|
|
|
|
for (var i = 0; i < length; ++i) {
|
|
codePoint = string.charCodeAt(i)
|
|
|
|
// is surrogate component
|
|
if (codePoint > 0xD7FF && codePoint < 0xE000) {
|
|
// last char was a lead
|
|
if (!leadSurrogate) {
|
|
// no lead yet
|
|
if (codePoint > 0xDBFF) {
|
|
// unexpected trail
|
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
|
continue
|
|
} else if (i + 1 === length) {
|
|
// unpaired lead
|
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
|
continue
|
|
}
|
|
|
|
// valid lead
|
|
leadSurrogate = codePoint
|
|
|
|
continue
|
|
}
|
|
|
|
// 2 leads in a row
|
|
if (codePoint < 0xDC00) {
|
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
|
leadSurrogate = codePoint
|
|
continue
|
|
}
|
|
|
|
// valid surrogate pair
|
|
codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
|
|
} else if (leadSurrogate) {
|
|
// valid bmp char, but last char was a lead
|
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
|
}
|
|
|
|
leadSurrogate = null
|
|
|
|
// encode utf8
|
|
if (codePoint < 0x80) {
|
|
if ((units -= 1) < 0) break
|
|
bytes.push(codePoint)
|
|
} else if (codePoint < 0x800) {
|
|
if ((units -= 2) < 0) break
|
|
bytes.push(
|
|
codePoint >> 0x6 | 0xC0,
|
|
codePoint & 0x3F | 0x80
|
|
)
|
|
} else if (codePoint < 0x10000) {
|
|
if ((units -= 3) < 0) break
|
|
bytes.push(
|
|
codePoint >> 0xC | 0xE0,
|
|
codePoint >> 0x6 & 0x3F | 0x80,
|
|
codePoint & 0x3F | 0x80
|
|
)
|
|
} else if (codePoint < 0x110000) {
|
|
if ((units -= 4) < 0) break
|
|
bytes.push(
|
|
codePoint >> 0x12 | 0xF0,
|
|
codePoint >> 0xC & 0x3F | 0x80,
|
|
codePoint >> 0x6 & 0x3F | 0x80,
|
|
codePoint & 0x3F | 0x80
|
|
)
|
|
} else {
|
|
throw new Error('Invalid code point')
|
|
}
|
|
}
|
|
|
|
return bytes
|
|
}
|
|
|
|
function asciiToBytes (str) {
|
|
var byteArray = []
|
|
for (var i = 0; i < str.length; ++i) {
|
|
// Node's code seems to be doing this and not & 0x7F..
|
|
byteArray.push(str.charCodeAt(i) & 0xFF)
|
|
}
|
|
return byteArray
|
|
}
|
|
|
|
function utf16leToBytes (str, units) {
|
|
var c, hi, lo
|
|
var byteArray = []
|
|
for (var i = 0; i < str.length; ++i) {
|
|
if ((units -= 2) < 0) break
|
|
|
|
c = str.charCodeAt(i)
|
|
hi = c >> 8
|
|
lo = c % 256
|
|
byteArray.push(lo)
|
|
byteArray.push(hi)
|
|
}
|
|
|
|
return byteArray
|
|
}
|
|
|
|
function base64ToBytes (str) {
|
|
return base64.toByteArray(base64clean(str))
|
|
}
|
|
|
|
function blitBuffer (src, dst, offset, length) {
|
|
for (var i = 0; i < length; ++i) {
|
|
if ((i + offset >= dst.length) || (i >= src.length)) break
|
|
dst[i + offset] = src[i]
|
|
}
|
|
return i
|
|
}
|
|
|
|
// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
|
|
// the `instanceof` check but they should be treated as of that type.
|
|
// See: https://github.com/feross/buffer/issues/166
|
|
function isInstance (obj, type) {
|
|
return obj instanceof type ||
|
|
(obj != null && obj.constructor != null && obj.constructor.name != null &&
|
|
obj.constructor.name === type.name)
|
|
}
|
|
function numberIsNaN (obj) {
|
|
// For IE11 support
|
|
return obj !== obj // eslint-disable-line no-self-compare
|
|
}
|
|
|
|
}).call(this)}).call(this,require("buffer").Buffer)
|
|
},{"base64-js":1,"buffer":3,"ieee754":59}],4:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.groupSelectors = exports.getDocumentRoot = void 0;
|
|
var positionals_1 = require("./positionals");
|
|
function getDocumentRoot(node) {
|
|
while (node.parent)
|
|
node = node.parent;
|
|
return node;
|
|
}
|
|
exports.getDocumentRoot = getDocumentRoot;
|
|
function groupSelectors(selectors) {
|
|
var filteredSelectors = [];
|
|
var plainSelectors = [];
|
|
for (var _i = 0, selectors_1 = selectors; _i < selectors_1.length; _i++) {
|
|
var selector = selectors_1[_i];
|
|
if (selector.some(positionals_1.isFilter)) {
|
|
filteredSelectors.push(selector);
|
|
}
|
|
else {
|
|
plainSelectors.push(selector);
|
|
}
|
|
}
|
|
return [plainSelectors, filteredSelectors];
|
|
}
|
|
exports.groupSelectors = groupSelectors;
|
|
|
|
},{"./positionals":6}],5:[function(require,module,exports){
|
|
"use strict";
|
|
var __assign = (this && this.__assign) || function () {
|
|
__assign = Object.assign || function(t) {
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
s = arguments[i];
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
t[p] = s[p];
|
|
}
|
|
return t;
|
|
};
|
|
return __assign.apply(this, arguments);
|
|
};
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
|
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
|
to[j] = from[i];
|
|
return to;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.select = exports.filter = exports.some = exports.is = exports.aliases = exports.pseudos = exports.filters = void 0;
|
|
var css_what_1 = require("css-what");
|
|
var css_select_1 = require("css-select");
|
|
var DomUtils = __importStar(require("domutils"));
|
|
var helpers_1 = require("./helpers");
|
|
var positionals_1 = require("./positionals");
|
|
// Re-export pseudo extension points
|
|
var css_select_2 = require("css-select");
|
|
Object.defineProperty(exports, "filters", { enumerable: true, get: function () { return css_select_2.filters; } });
|
|
Object.defineProperty(exports, "pseudos", { enumerable: true, get: function () { return css_select_2.pseudos; } });
|
|
Object.defineProperty(exports, "aliases", { enumerable: true, get: function () { return css_select_2.aliases; } });
|
|
/** Used to indicate a scope should be filtered. Might be ignored when filtering. */
|
|
var SCOPE_PSEUDO = {
|
|
type: "pseudo",
|
|
name: "scope",
|
|
data: null,
|
|
};
|
|
/** Used for actually filtering for scope. */
|
|
var CUSTOM_SCOPE_PSEUDO = __assign({}, SCOPE_PSEUDO);
|
|
var UNIVERSAL_SELECTOR = { type: "universal", namespace: null };
|
|
function is(element, selector, options) {
|
|
if (options === void 0) { options = {}; }
|
|
if (typeof selector === "function")
|
|
return selector(element);
|
|
var _a = helpers_1.groupSelectors(css_what_1.parse(selector, options)), plain = _a[0], filtered = _a[1];
|
|
return ((plain.length > 0 && css_select_1.is(element, plain, options)) ||
|
|
filtered.some(function (sel) { return filterBySelector(sel, [element], options).length > 0; }));
|
|
}
|
|
exports.is = is;
|
|
function some(elements, selector, options) {
|
|
if (options === void 0) { options = {}; }
|
|
if (typeof selector === "function")
|
|
return elements.some(selector);
|
|
var _a = helpers_1.groupSelectors(css_what_1.parse(selector, options)), plain = _a[0], filtered = _a[1];
|
|
return ((plain.length > 0 && elements.some(css_select_1._compileToken(plain, options))) ||
|
|
filtered.some(function (sel) { return filterBySelector(sel, elements, options).length > 0; }));
|
|
}
|
|
exports.some = some;
|
|
function filterByPosition(filter, elems, data, options) {
|
|
var num = typeof data === "string" ? parseInt(data, 10) : NaN;
|
|
switch (filter) {
|
|
case "first":
|
|
case "lt":
|
|
// Already done in `getLimit`
|
|
return elems;
|
|
case "last":
|
|
return elems.length > 0 ? [elems[elems.length - 1]] : elems;
|
|
case "nth":
|
|
case "eq":
|
|
return isFinite(num) && Math.abs(num) < elems.length
|
|
? [num < 0 ? elems[elems.length + num] : elems[num]]
|
|
: [];
|
|
case "gt":
|
|
return isFinite(num) ? elems.slice(num + 1) : [];
|
|
case "even":
|
|
return elems.filter(function (_, i) { return i % 2 === 0; });
|
|
case "odd":
|
|
return elems.filter(function (_, i) { return i % 2 === 1; });
|
|
case "not": {
|
|
var filtered_1 = new Set(filterParsed(data, elems, options));
|
|
return elems.filter(function (e) { return !filtered_1.has(e); });
|
|
}
|
|
}
|
|
}
|
|
function filter(selector, elements, options) {
|
|
if (options === void 0) { options = {}; }
|
|
return filterParsed(css_what_1.parse(selector, options), elements, options);
|
|
}
|
|
exports.filter = filter;
|
|
/**
|
|
* Filter a set of elements by a selector.
|
|
*
|
|
* Will return elements in the original order.
|
|
*
|
|
* @param selector Selector to filter by.
|
|
* @param elements Elements to filter.
|
|
* @param options Options for selector.
|
|
*/
|
|
function filterParsed(selector, elements, options) {
|
|
if (elements.length === 0)
|
|
return [];
|
|
var _a = helpers_1.groupSelectors(selector), plainSelectors = _a[0], filteredSelectors = _a[1];
|
|
var found;
|
|
if (plainSelectors.length) {
|
|
var filtered = filterElements(elements, plainSelectors, options);
|
|
// If there are no filters, just return
|
|
if (filteredSelectors.length === 0) {
|
|
return filtered;
|
|
}
|
|
// Otherwise, we have to do some filtering
|
|
if (filtered.length) {
|
|
found = new Set(filtered);
|
|
}
|
|
}
|
|
for (var i = 0; i < filteredSelectors.length && (found === null || found === void 0 ? void 0 : found.size) !== elements.length; i++) {
|
|
var filteredSelector = filteredSelectors[i];
|
|
var missing = found
|
|
? elements.filter(function (e) { return !found.has(e); })
|
|
: elements;
|
|
if (missing.length === 0)
|
|
break;
|
|
var filtered = filterBySelector(filteredSelector, elements, options);
|
|
if (filtered.length) {
|
|
if (!found) {
|
|
/*
|
|
* If we haven't found anything before the last selector,
|
|
* just return what we found now.
|
|
*/
|
|
if (i === filteredSelectors.length - 1) {
|
|
return filtered;
|
|
}
|
|
found = new Set(filtered);
|
|
}
|
|
else {
|
|
filtered.forEach(function (el) { return found.add(el); });
|
|
}
|
|
}
|
|
}
|
|
return typeof found !== "undefined"
|
|
? found.size === elements.length
|
|
? elements
|
|
: elements.filter(function (el) { return found.has(el); })
|
|
: [];
|
|
}
|
|
function filterBySelector(selector, elements, options) {
|
|
if (selector.some(css_what_1.isTraversal)) {
|
|
/*
|
|
* Get one root node, run selector with the scope
|
|
* set to all of our nodes.
|
|
*/
|
|
var root = helpers_1.getDocumentRoot(elements[0]);
|
|
var sel = __spreadArray(__spreadArray([], selector), [CUSTOM_SCOPE_PSEUDO]);
|
|
return findFilterElements(root, sel, options, true, elements);
|
|
}
|
|
// Performance optimization: If we don't have to traverse, just filter set.
|
|
return findFilterElements(elements, selector, options, false);
|
|
}
|
|
function select(selector, root, options) {
|
|
if (options === void 0) { options = {}; }
|
|
if (typeof selector === "function") {
|
|
return find(root, selector);
|
|
}
|
|
var _a = helpers_1.groupSelectors(css_what_1.parse(selector, options)), plain = _a[0], filtered = _a[1];
|
|
var results = filtered.map(function (sel) {
|
|
return findFilterElements(root, sel, options, true);
|
|
});
|
|
// Plain selectors can be queried in a single go
|
|
if (plain.length) {
|
|
results.push(findElements(root, plain, options, Infinity));
|
|
}
|
|
// If there was only a single selector, just return the result
|
|
if (results.length === 1) {
|
|
return results[0];
|
|
}
|
|
// Sort results, filtering for duplicates
|
|
return DomUtils.uniqueSort(results.reduce(function (a, b) { return __spreadArray(__spreadArray([], a), b); }));
|
|
}
|
|
exports.select = select;
|
|
// Traversals that are treated differently in css-select.
|
|
var specialTraversal = new Set(["descendant", "adjacent"]);
|
|
function includesScopePseudo(t) {
|
|
return (t !== SCOPE_PSEUDO &&
|
|
t.type === "pseudo" &&
|
|
(t.name === "scope" ||
|
|
(Array.isArray(t.data) &&
|
|
t.data.some(function (data) { return data.some(includesScopePseudo); }))));
|
|
}
|
|
function addContextIfScope(selector, options, scopeContext) {
|
|
return scopeContext && selector.some(includesScopePseudo)
|
|
? __assign(__assign({}, options), { context: scopeContext }) : options;
|
|
}
|
|
/**
|
|
*
|
|
* @param root Element(s) to search from.
|
|
* @param selector Selector to look for.
|
|
* @param options Options for querying.
|
|
* @param queryForSelector Query multiple levels deep for the initial selector, even if it doesn't contain a traversal.
|
|
* @param scopeContext Optional context for a :scope.
|
|
*/
|
|
function findFilterElements(root, selector, options, queryForSelector, scopeContext) {
|
|
var filterIndex = selector.findIndex(positionals_1.isFilter);
|
|
var sub = selector.slice(0, filterIndex);
|
|
var filter = selector[filterIndex];
|
|
/*
|
|
* Set the number of elements to retrieve.
|
|
* Eg. for :first, we only have to get a single element.
|
|
*/
|
|
var limit = positionals_1.getLimit(filter.name, filter.data);
|
|
if (limit === 0)
|
|
return [];
|
|
var subOpts = addContextIfScope(sub, options, scopeContext);
|
|
/*
|
|
* Skip `findElements` call if our selector starts with a positional
|
|
* pseudo.
|
|
*/
|
|
var elemsNoLimit = sub.length === 0 && !Array.isArray(root)
|
|
? DomUtils.getChildren(root).filter(DomUtils.isTag)
|
|
: sub.length === 0 || (sub.length === 1 && sub[0] === SCOPE_PSEUDO)
|
|
? (Array.isArray(root) ? root : [root]).filter(DomUtils.isTag)
|
|
: queryForSelector || sub.some(css_what_1.isTraversal)
|
|
? findElements(root, [sub], subOpts, limit)
|
|
: filterElements(root, [sub], subOpts);
|
|
var elems = elemsNoLimit.slice(0, limit);
|
|
var result = filterByPosition(filter.name, elems, filter.data, options);
|
|
if (result.length === 0 || selector.length === filterIndex + 1) {
|
|
return result;
|
|
}
|
|
var remainingSelector = selector.slice(filterIndex + 1);
|
|
var remainingHasTraversal = remainingSelector.some(css_what_1.isTraversal);
|
|
var remainingOpts = addContextIfScope(remainingSelector, options, scopeContext);
|
|
if (remainingHasTraversal) {
|
|
/*
|
|
* Some types of traversals have special logic when they start a selector
|
|
* in css-select. If this is the case, add a universal selector in front of
|
|
* the selector to avoid this behavior.
|
|
*/
|
|
if (specialTraversal.has(remainingSelector[0].type)) {
|
|
remainingSelector.unshift(UNIVERSAL_SELECTOR);
|
|
}
|
|
/*
|
|
* Add a scope token in front of the remaining selector,
|
|
* to make sure traversals don't match elements that aren't a
|
|
* part of the considered tree.
|
|
*/
|
|
remainingSelector.unshift(SCOPE_PSEUDO);
|
|
}
|
|
/*
|
|
* If we have another filter, recursively call `findFilterElements`,
|
|
* with the `recursive` flag disabled. We only have to look for more
|
|
* elements when we see a traversal.
|
|
*
|
|
* Otherwise,
|
|
*/
|
|
return remainingSelector.some(positionals_1.isFilter)
|
|
? findFilterElements(result, remainingSelector, options, false, scopeContext)
|
|
: remainingHasTraversal
|
|
? // Query existing elements to resolve traversal.
|
|
findElements(result, [remainingSelector], remainingOpts, Infinity)
|
|
: // If we don't have any more traversals, simply filter elements.
|
|
filterElements(result, [remainingSelector], remainingOpts);
|
|
}
|
|
function findElements(root, sel, options, limit) {
|
|
if (limit === 0)
|
|
return [];
|
|
var query = css_select_1._compileToken(sel, options, root);
|
|
return find(root, query, limit);
|
|
}
|
|
function find(root, query, limit) {
|
|
if (limit === void 0) { limit = Infinity; }
|
|
var elems = css_select_1.prepareContext(root, DomUtils, query.shouldTestNextSiblings);
|
|
return DomUtils.find(function (node) { return DomUtils.isTag(node) && query(node); }, elems, true, limit);
|
|
}
|
|
function filterElements(elements, sel, options) {
|
|
var els = (Array.isArray(elements) ? elements : [elements]).filter(DomUtils.isTag);
|
|
if (els.length === 0)
|
|
return els;
|
|
var query = css_select_1._compileToken(sel, options);
|
|
return els.filter(query);
|
|
}
|
|
|
|
},{"./helpers":4,"./positionals":6,"css-select":24,"css-what":32,"domutils":41}],6:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.getLimit = exports.isFilter = exports.filterNames = void 0;
|
|
exports.filterNames = new Set([
|
|
"first",
|
|
"last",
|
|
"eq",
|
|
"gt",
|
|
"nth",
|
|
"lt",
|
|
"even",
|
|
"odd",
|
|
]);
|
|
function isFilter(s) {
|
|
if (s.type !== "pseudo")
|
|
return false;
|
|
if (exports.filterNames.has(s.name))
|
|
return true;
|
|
if (s.name === "not" && Array.isArray(s.data)) {
|
|
// Only consider `:not` with embedded filters
|
|
return s.data.some(function (s) { return s.some(isFilter); });
|
|
}
|
|
return false;
|
|
}
|
|
exports.isFilter = isFilter;
|
|
function getLimit(filter, data) {
|
|
var num = data != null ? parseInt(data, 10) : NaN;
|
|
switch (filter) {
|
|
case "first":
|
|
return 1;
|
|
case "nth":
|
|
case "eq":
|
|
return isFinite(num) ? (num >= 0 ? num + 1 : Infinity) : 0;
|
|
case "lt":
|
|
return isFinite(num) ? (num >= 0 ? num : Infinity) : 0;
|
|
case "gt":
|
|
return isFinite(num) ? Infinity : 0;
|
|
default:
|
|
return Infinity;
|
|
}
|
|
}
|
|
exports.getLimit = getLimit;
|
|
|
|
},{}],7:[function(require,module,exports){
|
|
"use strict";
|
|
/**
|
|
* Methods for getting and modifying attributes.
|
|
*
|
|
* @module cheerio/attributes
|
|
*/
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.is = exports.toggleClass = exports.removeClass = exports.addClass = exports.hasClass = exports.removeAttr = exports.val = exports.data = exports.prop = exports.attr = void 0;
|
|
var static_1 = require("../static");
|
|
var utils_1 = require("../utils");
|
|
var hasOwn = Object.prototype.hasOwnProperty;
|
|
var rspace = /\s+/;
|
|
var dataAttrPrefix = 'data-';
|
|
/*
|
|
* Lookup table for coercing string data-* attributes to their corresponding
|
|
* JavaScript primitives
|
|
*/
|
|
var primitives = {
|
|
null: null,
|
|
true: true,
|
|
false: false,
|
|
};
|
|
// Attributes that are booleans
|
|
var rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i;
|
|
// Matches strings that look like JSON objects or arrays
|
|
var rbrace = /^(?:{[\w\W]*}|\[[\w\W]*])$/;
|
|
function getAttr(elem, name) {
|
|
var _a;
|
|
if (!elem || !utils_1.isTag(elem))
|
|
return undefined;
|
|
(_a = elem.attribs) !== null && _a !== void 0 ? _a : (elem.attribs = {});
|
|
// Return the entire attribs object if no attribute specified
|
|
if (!name) {
|
|
return elem.attribs;
|
|
}
|
|
if (hasOwn.call(elem.attribs, name)) {
|
|
// Get the (decoded) attribute
|
|
return rboolean.test(name) ? name : elem.attribs[name];
|
|
}
|
|
// Mimic the DOM and return text content as value for `option's`
|
|
if (elem.name === 'option' && name === 'value') {
|
|
return static_1.text(elem.children);
|
|
}
|
|
// Mimic DOM with default value for radios/checkboxes
|
|
if (elem.name === 'input' &&
|
|
(elem.attribs.type === 'radio' || elem.attribs.type === 'checkbox') &&
|
|
name === 'value') {
|
|
return 'on';
|
|
}
|
|
return undefined;
|
|
}
|
|
/**
|
|
* Sets the value of an attribute. The attribute will be deleted if the value is `null`.
|
|
*
|
|
* @private
|
|
* @param el - The element to set the attribute on.
|
|
* @param name - The attribute's name.
|
|
* @param value - The attribute's value.
|
|
*/
|
|
function setAttr(el, name, value) {
|
|
if (value === null) {
|
|
removeAttribute(el, name);
|
|
}
|
|
else {
|
|
el.attribs[name] = "" + value;
|
|
}
|
|
}
|
|
function attr(name, value) {
|
|
// Set the value (with attr map support)
|
|
if (typeof name === 'object' || value !== undefined) {
|
|
if (typeof value === 'function') {
|
|
if (typeof name !== 'string') {
|
|
{
|
|
throw new Error('Bad combination of arguments.');
|
|
}
|
|
}
|
|
return utils_1.domEach(this, function (i, el) {
|
|
if (utils_1.isTag(el))
|
|
setAttr(el, name, value.call(el, i, el.attribs[name]));
|
|
});
|
|
}
|
|
return utils_1.domEach(this, function (_, el) {
|
|
if (!utils_1.isTag(el))
|
|
return;
|
|
if (typeof name === 'object') {
|
|
Object.keys(name).forEach(function (objName) {
|
|
var objValue = name[objName];
|
|
setAttr(el, objName, objValue);
|
|
});
|
|
}
|
|
else {
|
|
setAttr(el, name, value);
|
|
}
|
|
});
|
|
}
|
|
return arguments.length > 1 ? this : getAttr(this[0], name);
|
|
}
|
|
exports.attr = attr;
|
|
/**
|
|
* Gets a node's prop.
|
|
*
|
|
* @private
|
|
* @category Attributes
|
|
* @param el - Elenent to get the prop of.
|
|
* @param name - Name of the prop.
|
|
* @returns The prop's value.
|
|
*/
|
|
function getProp(el, name) {
|
|
if (!el || !utils_1.isTag(el))
|
|
return;
|
|
return name in el
|
|
? // @ts-expect-error TS doesn't like us accessing the value directly here.
|
|
el[name]
|
|
: rboolean.test(name)
|
|
? getAttr(el, name) !== undefined
|
|
: getAttr(el, name);
|
|
}
|
|
/**
|
|
* Sets the value of a prop.
|
|
*
|
|
* @private
|
|
* @param el - The element to set the prop on.
|
|
* @param name - The prop's name.
|
|
* @param value - The prop's value.
|
|
*/
|
|
function setProp(el, name, value) {
|
|
if (name in el) {
|
|
// @ts-expect-error Overriding value
|
|
el[name] = value;
|
|
}
|
|
else {
|
|
setAttr(el, name, rboolean.test(name) ? (value ? '' : null) : "" + value);
|
|
}
|
|
}
|
|
function prop(name, value) {
|
|
if (typeof name === 'string' && value === undefined) {
|
|
switch (name) {
|
|
case 'style': {
|
|
var property_1 = this.css();
|
|
var keys = Object.keys(property_1);
|
|
keys.forEach(function (p, i) {
|
|
property_1[i] = p;
|
|
});
|
|
property_1.length = keys.length;
|
|
return property_1;
|
|
}
|
|
case 'tagName':
|
|
case 'nodeName': {
|
|
var el = this[0];
|
|
return utils_1.isTag(el) ? el.name.toUpperCase() : undefined;
|
|
}
|
|
case 'outerHTML':
|
|
return this.clone().wrap('<container />').parent().html();
|
|
case 'innerHTML':
|
|
return this.html();
|
|
default:
|
|
return getProp(this[0], name);
|
|
}
|
|
}
|
|
if (typeof name === 'object' || value !== undefined) {
|
|
if (typeof value === 'function') {
|
|
if (typeof name === 'object') {
|
|
throw new Error('Bad combination of arguments.');
|
|
}
|
|
return utils_1.domEach(this, function (j, el) {
|
|
if (utils_1.isTag(el))
|
|
setProp(el, name, value.call(el, j, getProp(el, name)));
|
|
});
|
|
}
|
|
return utils_1.domEach(this, function (__, el) {
|
|
if (!utils_1.isTag(el))
|
|
return;
|
|
if (typeof name === 'object') {
|
|
Object.keys(name).forEach(function (key) {
|
|
var val = name[key];
|
|
setProp(el, key, val);
|
|
});
|
|
}
|
|
else {
|
|
setProp(el, name, value);
|
|
}
|
|
});
|
|
}
|
|
return undefined;
|
|
}
|
|
exports.prop = prop;
|
|
/**
|
|
* Sets the value of a data attribute.
|
|
*
|
|
* @private
|
|
* @param el - The element to set the data attribute on.
|
|
* @param name - The data attribute's name.
|
|
* @param value - The data attribute's value.
|
|
*/
|
|
function setData(el, name, value) {
|
|
var _a;
|
|
var elem = el;
|
|
(_a = elem.data) !== null && _a !== void 0 ? _a : (elem.data = {});
|
|
if (typeof name === 'object')
|
|
Object.assign(elem.data, name);
|
|
else if (typeof name === 'string' && value !== undefined) {
|
|
elem.data[name] = value;
|
|
}
|
|
}
|
|
/**
|
|
* Read the specified attribute from the equivalent HTML5 `data-*` attribute,
|
|
* and (if present) cache the value in the node's internal data store. If no
|
|
* attribute name is specified, read *all* HTML5 `data-*` attributes in this manner.
|
|
*
|
|
* @private
|
|
* @category Attributes
|
|
* @param el - Elenent to get the data attribute of.
|
|
* @param name - Name of the data attribute.
|
|
* @returns The data attribute's value, or a map with all of the data attribute.
|
|
*/
|
|
function readData(el, name) {
|
|
var domNames;
|
|
var jsNames;
|
|
var value;
|
|
if (name == null) {
|
|
domNames = Object.keys(el.attribs).filter(function (attrName) {
|
|
return attrName.startsWith(dataAttrPrefix);
|
|
});
|
|
jsNames = domNames.map(function (domName) {
|
|
return utils_1.camelCase(domName.slice(dataAttrPrefix.length));
|
|
});
|
|
}
|
|
else {
|
|
domNames = [dataAttrPrefix + utils_1.cssCase(name)];
|
|
jsNames = [name];
|
|
}
|
|
for (var idx = 0; idx < domNames.length; ++idx) {
|
|
var domName = domNames[idx];
|
|
var jsName = jsNames[idx];
|
|
if (hasOwn.call(el.attribs, domName) &&
|
|
!hasOwn.call(el.data, jsName)) {
|
|
value = el.attribs[domName];
|
|
if (hasOwn.call(primitives, value)) {
|
|
value = primitives[value];
|
|
}
|
|
else if (value === String(Number(value))) {
|
|
value = Number(value);
|
|
}
|
|
else if (rbrace.test(value)) {
|
|
try {
|
|
value = JSON.parse(value);
|
|
}
|
|
catch (e) {
|
|
/* Ignore */
|
|
}
|
|
}
|
|
el.data[jsName] = value;
|
|
}
|
|
}
|
|
return name == null ? el.data : value;
|
|
}
|
|
function data(name, value) {
|
|
var _a;
|
|
var elem = this[0];
|
|
if (!elem || !utils_1.isTag(elem))
|
|
return;
|
|
var dataEl = elem;
|
|
(_a = dataEl.data) !== null && _a !== void 0 ? _a : (dataEl.data = {});
|
|
// Return the entire data object if no data specified
|
|
if (!name) {
|
|
return readData(dataEl);
|
|
}
|
|
// Set the value (with attr map support)
|
|
if (typeof name === 'object' || value !== undefined) {
|
|
utils_1.domEach(this, function (_, el) {
|
|
if (utils_1.isTag(el))
|
|
if (typeof name === 'object')
|
|
setData(el, name);
|
|
else
|
|
setData(el, name, value);
|
|
});
|
|
return this;
|
|
}
|
|
if (hasOwn.call(dataEl.data, name)) {
|
|
return dataEl.data[name];
|
|
}
|
|
return readData(dataEl, name);
|
|
}
|
|
exports.data = data;
|
|
function val(value) {
|
|
var querying = arguments.length === 0;
|
|
var element = this[0];
|
|
if (!element || !utils_1.isTag(element))
|
|
return querying ? undefined : this;
|
|
switch (element.name) {
|
|
case 'textarea':
|
|
return this.text(value);
|
|
case 'select': {
|
|
var option = this.find('option:selected');
|
|
if (!querying) {
|
|
if (this.attr('multiple') == null && typeof value === 'object') {
|
|
return this;
|
|
}
|
|
this.find('option').removeAttr('selected');
|
|
var values = typeof value !== 'object' ? [value] : value;
|
|
for (var i = 0; i < values.length; i++) {
|
|
this.find("option[value=\"" + values[i] + "\"]").attr('selected', '');
|
|
}
|
|
return this;
|
|
}
|
|
return this.attr('multiple')
|
|
? option.toArray().map(function (el) { return static_1.text(el.children); })
|
|
: option.attr('value');
|
|
}
|
|
case 'input':
|
|
case 'option':
|
|
return querying
|
|
? this.attr('value')
|
|
: this.attr('value', value);
|
|
}
|
|
return undefined;
|
|
}
|
|
exports.val = val;
|
|
/**
|
|
* Remove an attribute.
|
|
*
|
|
* @private
|
|
* @param elem - Node to remove attribute from.
|
|
* @param name - Name of the attribute to remove.
|
|
*/
|
|
function removeAttribute(elem, name) {
|
|
if (!elem.attribs || !hasOwn.call(elem.attribs, name))
|
|
return;
|
|
delete elem.attribs[name];
|
|
}
|
|
/**
|
|
* Splits a space-separated list of names to individual names.
|
|
*
|
|
* @category Attributes
|
|
* @param names - Names to split.
|
|
* @returns - Split names.
|
|
*/
|
|
function splitNames(names) {
|
|
return names ? names.trim().split(rspace) : [];
|
|
}
|
|
/**
|
|
* Method for removing attributes by `name`.
|
|
*
|
|
* @category Attributes
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.pear').removeAttr('class').html();
|
|
* //=> <li>Pear</li>
|
|
*
|
|
* $('.apple').attr('id', 'favorite');
|
|
* $('.apple').removeAttr('id class').html();
|
|
* //=> <li>Apple</li>
|
|
* ```
|
|
*
|
|
* @param name - Name of the attribute.
|
|
* @returns The instance itself.
|
|
* @see {@link https://api.jquery.com/removeAttr/}
|
|
*/
|
|
function removeAttr(name) {
|
|
var attrNames = splitNames(name);
|
|
var _loop_1 = function (i) {
|
|
utils_1.domEach(this_1, function (_, elem) {
|
|
if (utils_1.isTag(elem))
|
|
removeAttribute(elem, attrNames[i]);
|
|
});
|
|
};
|
|
var this_1 = this;
|
|
for (var i = 0; i < attrNames.length; i++) {
|
|
_loop_1(i);
|
|
}
|
|
return this;
|
|
}
|
|
exports.removeAttr = removeAttr;
|
|
/**
|
|
* Check to see if *any* of the matched elements have the given `className`.
|
|
*
|
|
* @category Attributes
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.pear').hasClass('pear');
|
|
* //=> true
|
|
*
|
|
* $('apple').hasClass('fruit');
|
|
* //=> false
|
|
*
|
|
* $('li').hasClass('pear');
|
|
* //=> true
|
|
* ```
|
|
*
|
|
* @param className - Name of the class.
|
|
* @returns Indicates if an element has the given `className`.
|
|
* @see {@link https://api.jquery.com/hasClass/}
|
|
*/
|
|
function hasClass(className) {
|
|
return this.toArray().some(function (elem) {
|
|
var clazz = utils_1.isTag(elem) && elem.attribs.class;
|
|
var idx = -1;
|
|
if (clazz && className.length) {
|
|
while ((idx = clazz.indexOf(className, idx + 1)) > -1) {
|
|
var end = idx + className.length;
|
|
if ((idx === 0 || rspace.test(clazz[idx - 1])) &&
|
|
(end === clazz.length || rspace.test(clazz[end]))) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
});
|
|
}
|
|
exports.hasClass = hasClass;
|
|
/**
|
|
* Adds class(es) to all of the matched elements. Also accepts a `function`.
|
|
*
|
|
* @category Attributes
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.pear').addClass('fruit').html();
|
|
* //=> <li class="pear fruit">Pear</li>
|
|
*
|
|
* $('.apple').addClass('fruit red').html();
|
|
* //=> <li class="apple fruit red">Apple</li>
|
|
* ```
|
|
*
|
|
* @param value - Name of new class.
|
|
* @returns The instance itself.
|
|
* @see {@link https://api.jquery.com/addClass/}
|
|
*/
|
|
function addClass(value) {
|
|
// Support functions
|
|
if (typeof value === 'function') {
|
|
return utils_1.domEach(this, function (i, el) {
|
|
if (utils_1.isTag(el)) {
|
|
var className = el.attribs.class || '';
|
|
addClass.call([el], value.call(el, i, className));
|
|
}
|
|
});
|
|
}
|
|
// Return if no value or not a string or function
|
|
if (!value || typeof value !== 'string')
|
|
return this;
|
|
var classNames = value.split(rspace);
|
|
var numElements = this.length;
|
|
for (var i = 0; i < numElements; i++) {
|
|
var el = this[i];
|
|
// If selected element isn't a tag, move on
|
|
if (!utils_1.isTag(el))
|
|
continue;
|
|
// If we don't already have classes
|
|
var className = getAttr(el, 'class');
|
|
if (!className) {
|
|
setAttr(el, 'class', classNames.join(' ').trim());
|
|
}
|
|
else {
|
|
var setClass = " " + className + " ";
|
|
// Check if class already exists
|
|
for (var j = 0; j < classNames.length; j++) {
|
|
var appendClass = classNames[j] + " ";
|
|
if (!setClass.includes(" " + appendClass))
|
|
setClass += appendClass;
|
|
}
|
|
setAttr(el, 'class', setClass.trim());
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
exports.addClass = addClass;
|
|
/**
|
|
* Removes one or more space-separated classes from the selected elements. If no
|
|
* `className` is defined, all classes will be removed. Also accepts a `function`.
|
|
*
|
|
* @category Attributes
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.pear').removeClass('pear').html();
|
|
* //=> <li class="">Pear</li>
|
|
*
|
|
* $('.apple').addClass('red').removeClass().html();
|
|
* //=> <li class="">Apple</li>
|
|
* ```
|
|
*
|
|
* @param name - Name of the class. If not specified, removes all elements.
|
|
* @returns The instance itself.
|
|
* @see {@link https://api.jquery.com/removeClass/}
|
|
*/
|
|
function removeClass(name) {
|
|
// Handle if value is a function
|
|
if (typeof name === 'function') {
|
|
return utils_1.domEach(this, function (i, el) {
|
|
if (utils_1.isTag(el))
|
|
removeClass.call([el], name.call(el, i, el.attribs.class || ''));
|
|
});
|
|
}
|
|
var classes = splitNames(name);
|
|
var numClasses = classes.length;
|
|
var removeAll = arguments.length === 0;
|
|
return utils_1.domEach(this, function (_, el) {
|
|
if (!utils_1.isTag(el))
|
|
return;
|
|
if (removeAll) {
|
|
// Short circuit the remove all case as this is the nice one
|
|
el.attribs.class = '';
|
|
}
|
|
else {
|
|
var elClasses = splitNames(el.attribs.class);
|
|
var changed = false;
|
|
for (var j = 0; j < numClasses; j++) {
|
|
var index = elClasses.indexOf(classes[j]);
|
|
if (index >= 0) {
|
|
elClasses.splice(index, 1);
|
|
changed = true;
|
|
/*
|
|
* We have to do another pass to ensure that there are not duplicate
|
|
* classes listed
|
|
*/
|
|
j--;
|
|
}
|
|
}
|
|
if (changed) {
|
|
el.attribs.class = elClasses.join(' ');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
exports.removeClass = removeClass;
|
|
/**
|
|
* Add or remove class(es) from the matched elements, depending on either the
|
|
* class's presence or the value of the switch argument. Also accepts a `function`.
|
|
*
|
|
* @category Attributes
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.apple.green').toggleClass('fruit green red').html();
|
|
* //=> <li class="apple fruit red">Apple</li>
|
|
*
|
|
* $('.apple.green').toggleClass('fruit green red', true).html();
|
|
* //=> <li class="apple green fruit red">Apple</li>
|
|
* ```
|
|
*
|
|
* @param value - Name of the class. Can also be a function.
|
|
* @param stateVal - If specified the state of the class.
|
|
* @returns The instance itself.
|
|
* @see {@link https://api.jquery.com/toggleClass/}
|
|
*/
|
|
function toggleClass(value, stateVal) {
|
|
// Support functions
|
|
if (typeof value === 'function') {
|
|
return utils_1.domEach(this, function (i, el) {
|
|
if (utils_1.isTag(el)) {
|
|
toggleClass.call([el], value.call(el, i, el.attribs.class || '', stateVal), stateVal);
|
|
}
|
|
});
|
|
}
|
|
// Return if no value or not a string or function
|
|
if (!value || typeof value !== 'string')
|
|
return this;
|
|
var classNames = value.split(rspace);
|
|
var numClasses = classNames.length;
|
|
var state = typeof stateVal === 'boolean' ? (stateVal ? 1 : -1) : 0;
|
|
var numElements = this.length;
|
|
for (var i = 0; i < numElements; i++) {
|
|
var el = this[i];
|
|
// If selected element isn't a tag, move on
|
|
if (!utils_1.isTag(el))
|
|
continue;
|
|
var elementClasses = splitNames(el.attribs.class);
|
|
// Check if class already exists
|
|
for (var j = 0; j < numClasses; j++) {
|
|
// Check if the class name is currently defined
|
|
var index = elementClasses.indexOf(classNames[j]);
|
|
// Add if stateValue === true or we are toggling and there is no value
|
|
if (state >= 0 && index < 0) {
|
|
elementClasses.push(classNames[j]);
|
|
}
|
|
else if (state <= 0 && index >= 0) {
|
|
// Otherwise remove but only if the item exists
|
|
elementClasses.splice(index, 1);
|
|
}
|
|
}
|
|
el.attribs.class = elementClasses.join(' ');
|
|
}
|
|
return this;
|
|
}
|
|
exports.toggleClass = toggleClass;
|
|
/**
|
|
* Checks the current list of elements and returns `true` if *any* of the
|
|
* elements match the selector. If using an element or Cheerio selection,
|
|
* returns `true` if *any* of the elements match. If using a predicate function,
|
|
* the function is executed in the context of the selected element, so `this`
|
|
* refers to the current element.
|
|
*
|
|
* @category Attributes
|
|
* @param selector - Selector for the selection.
|
|
* @returns Whether or not the selector matches an element of the instance.
|
|
* @see {@link https://api.jquery.com/is/}
|
|
*/
|
|
function is(selector) {
|
|
if (selector) {
|
|
return this.filter(selector).length > 0;
|
|
}
|
|
return false;
|
|
}
|
|
exports.is = is;
|
|
|
|
},{"../static":18,"../utils":20}],8:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.css = void 0;
|
|
var utils_1 = require("../utils");
|
|
function css(prop, val) {
|
|
if ((prop != null && val != null) ||
|
|
// When `prop` is a "plain" object
|
|
(typeof prop === 'object' && !Array.isArray(prop))) {
|
|
return utils_1.domEach(this, function (idx, el) {
|
|
if (utils_1.isTag(el)) {
|
|
// `prop` can't be an array here anymore.
|
|
setCss(el, prop, val, idx);
|
|
}
|
|
});
|
|
}
|
|
return getCss(this[0], prop);
|
|
}
|
|
exports.css = css;
|
|
/**
|
|
* Set styles of all elements.
|
|
*
|
|
* @private
|
|
* @param el - Element to set style of.
|
|
* @param prop - Name of property.
|
|
* @param value - Value to set property to.
|
|
* @param idx - Optional index within the selection.
|
|
*/
|
|
function setCss(el, prop, value, idx) {
|
|
if (typeof prop === 'string') {
|
|
var styles = getCss(el);
|
|
var val = typeof value === 'function' ? value.call(el, idx, styles[prop]) : value;
|
|
if (val === '') {
|
|
delete styles[prop];
|
|
}
|
|
else if (val != null) {
|
|
styles[prop] = val;
|
|
}
|
|
el.attribs.style = stringify(styles);
|
|
}
|
|
else if (typeof prop === 'object') {
|
|
Object.keys(prop).forEach(function (k, i) {
|
|
setCss(el, k, prop[k], i);
|
|
});
|
|
}
|
|
}
|
|
function getCss(el, prop) {
|
|
if (!el || !utils_1.isTag(el))
|
|
return;
|
|
var styles = parse(el.attribs.style);
|
|
if (typeof prop === 'string') {
|
|
return styles[prop];
|
|
}
|
|
if (Array.isArray(prop)) {
|
|
var newStyles_1 = {};
|
|
prop.forEach(function (item) {
|
|
if (styles[item] != null) {
|
|
newStyles_1[item] = styles[item];
|
|
}
|
|
});
|
|
return newStyles_1;
|
|
}
|
|
return styles;
|
|
}
|
|
/**
|
|
* Stringify `obj` to styles.
|
|
*
|
|
* @private
|
|
* @category CSS
|
|
* @param obj - Object to stringify.
|
|
* @returns The serialized styles.
|
|
*/
|
|
function stringify(obj) {
|
|
return Object.keys(obj).reduce(function (str, prop) { return "" + str + (str ? ' ' : '') + prop + ": " + obj[prop] + ";"; }, '');
|
|
}
|
|
/**
|
|
* Parse `styles`.
|
|
*
|
|
* @private
|
|
* @category CSS
|
|
* @param styles - Styles to be parsed.
|
|
* @returns The parsed styles.
|
|
*/
|
|
function parse(styles) {
|
|
styles = (styles || '').trim();
|
|
if (!styles)
|
|
return {};
|
|
return styles.split(';').reduce(function (obj, str) {
|
|
var n = str.indexOf(':');
|
|
// Skip if there is no :, or if it is the first/last character
|
|
if (n < 1 || n === str.length - 1)
|
|
return obj;
|
|
obj[str.slice(0, n).trim()] = str.slice(n + 1).trim();
|
|
return obj;
|
|
}, {});
|
|
}
|
|
|
|
},{"../utils":20}],9:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.serializeArray = exports.serialize = void 0;
|
|
var utils_1 = require("../utils");
|
|
/*
|
|
* https://github.com/jquery/jquery/blob/2.1.3/src/manipulation/var/rcheckableType.js
|
|
* https://github.com/jquery/jquery/blob/2.1.3/src/serialize.js
|
|
*/
|
|
var submittableSelector = 'input,select,textarea,keygen';
|
|
var r20 = /%20/g;
|
|
var rCRLF = /\r?\n/g;
|
|
/**
|
|
* Encode a set of form elements as a string for submission.
|
|
*
|
|
* @category Forms
|
|
* @returns The serialized form.
|
|
* @see {@link https://api.jquery.com/serialize/}
|
|
*/
|
|
function serialize() {
|
|
// Convert form elements into name/value objects
|
|
var arr = this.serializeArray();
|
|
// Serialize each element into a key/value string
|
|
var retArr = arr.map(function (data) {
|
|
return encodeURIComponent(data.name) + "=" + encodeURIComponent(data.value);
|
|
});
|
|
// Return the resulting serialization
|
|
return retArr.join('&').replace(r20, '+');
|
|
}
|
|
exports.serialize = serialize;
|
|
/**
|
|
* Encode a set of form elements as an array of names and values.
|
|
*
|
|
* @category Forms
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('<form><input name="foo" value="bar" /></form>').serializeArray();
|
|
* //=> [ { name: 'foo', value: 'bar' } ]
|
|
* ```
|
|
*
|
|
* @returns The serialized form.
|
|
* @see {@link https://api.jquery.com/serializeArray/}
|
|
*/
|
|
function serializeArray() {
|
|
// Resolve all form elements from either forms or collections of form elements
|
|
var Cheerio = this.constructor;
|
|
return this.map(function (_, elem) {
|
|
var $elem = Cheerio(elem);
|
|
if (utils_1.isTag(elem) && elem.name === 'form') {
|
|
return $elem.find(submittableSelector).toArray();
|
|
}
|
|
return $elem.filter(submittableSelector).toArray();
|
|
})
|
|
.filter(
|
|
// Verify elements have a name (`attr.name`) and are not disabled (`:enabled`)
|
|
'[name!=""]:enabled' +
|
|
// And cannot be clicked (`[type=submit]`) or are used in `x-www-form-urlencoded` (`[type=file]`)
|
|
':not(:submit, :button, :image, :reset, :file)' +
|
|
// And are either checked/don't have a checkable state
|
|
':matches([checked], :not(:checkbox, :radio))'
|
|
// Convert each of the elements to its value(s)
|
|
)
|
|
.map(function (_, elem) {
|
|
var _a;
|
|
var $elem = Cheerio(elem);
|
|
var name = $elem.attr('name'); // We have filtered for elements with a name before.
|
|
// If there is no value set (e.g. `undefined`, `null`), then default value to empty
|
|
var value = (_a = $elem.val()) !== null && _a !== void 0 ? _a : '';
|
|
// If we have an array of values (e.g. `<select multiple>`), return an array of key/value pairs
|
|
if (Array.isArray(value)) {
|
|
return value.map(function (val) {
|
|
/*
|
|
* We trim replace any line endings (e.g. `\r` or `\r\n` with `\r\n`) to guarantee consistency across platforms
|
|
* These can occur inside of `<textarea>'s`
|
|
*/
|
|
return ({ name: name, value: val.replace(rCRLF, '\r\n') });
|
|
});
|
|
}
|
|
// Otherwise (e.g. `<input type="text">`, return only one key/value pair
|
|
return { name: name, value: value.replace(rCRLF, '\r\n') };
|
|
})
|
|
.toArray();
|
|
}
|
|
exports.serializeArray = serializeArray;
|
|
|
|
},{"../utils":20}],10:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.clone = exports.text = exports.toString = exports.html = exports.empty = exports.replaceWith = exports.remove = exports.insertBefore = exports.before = exports.insertAfter = exports.after = exports.wrapAll = exports.unwrap = exports.wrapInner = exports.wrap = exports.prepend = exports.append = exports.prependTo = exports.appendTo = exports._makeDomArray = void 0;
|
|
var tslib_1 = require("tslib");
|
|
var domhandler_1 = require("domhandler");
|
|
/**
|
|
* Methods for modifying the DOM structure.
|
|
*
|
|
* @module cheerio/manipulation
|
|
*/
|
|
var domhandler_2 = require("domhandler");
|
|
var parse_1 = tslib_1.__importStar(require("../parse"));
|
|
var static_1 = require("../static");
|
|
var utils_1 = require("../utils");
|
|
var htmlparser2_1 = require("htmlparser2");
|
|
/**
|
|
* Create an array of nodes, recursing into arrays and parsing strings if necessary.
|
|
*
|
|
* @private
|
|
* @category Manipulation
|
|
* @param elem - Elements to make an array of.
|
|
* @param clone - Optionally clone nodes.
|
|
* @returns The array of nodes.
|
|
*/
|
|
function _makeDomArray(elem, clone) {
|
|
var _this = this;
|
|
if (elem == null) {
|
|
return [];
|
|
}
|
|
if (utils_1.isCheerio(elem)) {
|
|
return clone ? utils_1.cloneDom(elem.get()) : elem.get();
|
|
}
|
|
if (Array.isArray(elem)) {
|
|
return elem.reduce(function (newElems, el) { return newElems.concat(_this._makeDomArray(el, clone)); }, []);
|
|
}
|
|
if (typeof elem === 'string') {
|
|
return parse_1.default(elem, this.options, false).children;
|
|
}
|
|
return clone ? utils_1.cloneDom([elem]) : [elem];
|
|
}
|
|
exports._makeDomArray = _makeDomArray;
|
|
function _insert(concatenator) {
|
|
return function () {
|
|
var _this = this;
|
|
var elems = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
elems[_i] = arguments[_i];
|
|
}
|
|
var lastIdx = this.length - 1;
|
|
return utils_1.domEach(this, function (i, el) {
|
|
if (!domhandler_1.hasChildren(el))
|
|
return;
|
|
var domSrc = typeof elems[0] === 'function'
|
|
? elems[0].call(el, i, static_1.html(el.children))
|
|
: elems;
|
|
var dom = _this._makeDomArray(domSrc, i < lastIdx);
|
|
concatenator(dom, el.children, el);
|
|
});
|
|
};
|
|
}
|
|
/**
|
|
* Modify an array in-place, removing some number of elements and adding new
|
|
* elements directly following them.
|
|
*
|
|
* @private
|
|
* @category Manipulation
|
|
* @param array - Target array to splice.
|
|
* @param spliceIdx - Index at which to begin changing the array.
|
|
* @param spliceCount - Number of elements to remove from the array.
|
|
* @param newElems - Elements to insert into the array.
|
|
* @param parent - The parent of the node.
|
|
* @returns The spliced array.
|
|
*/
|
|
function uniqueSplice(array, spliceIdx, spliceCount, newElems, parent) {
|
|
var _a, _b;
|
|
var spliceArgs = tslib_1.__spreadArray([
|
|
spliceIdx,
|
|
spliceCount
|
|
], newElems);
|
|
var prev = array[spliceIdx - 1] || null;
|
|
var next = array[spliceIdx + spliceCount] || null;
|
|
/*
|
|
* Before splicing in new elements, ensure they do not already appear in the
|
|
* current array.
|
|
*/
|
|
for (var idx = 0; idx < newElems.length; ++idx) {
|
|
var node = newElems[idx];
|
|
var oldParent = node.parent;
|
|
if (oldParent) {
|
|
var prevIdx = oldParent.children.indexOf(newElems[idx]);
|
|
if (prevIdx > -1) {
|
|
oldParent.children.splice(prevIdx, 1);
|
|
if (parent === oldParent && spliceIdx > prevIdx) {
|
|
spliceArgs[0]--;
|
|
}
|
|
}
|
|
}
|
|
node.parent = parent;
|
|
if (node.prev) {
|
|
node.prev.next = (_a = node.next) !== null && _a !== void 0 ? _a : null;
|
|
}
|
|
if (node.next) {
|
|
node.next.prev = (_b = node.prev) !== null && _b !== void 0 ? _b : null;
|
|
}
|
|
node.prev = newElems[idx - 1] || prev;
|
|
node.next = newElems[idx + 1] || next;
|
|
}
|
|
if (prev) {
|
|
prev.next = newElems[0];
|
|
}
|
|
if (next) {
|
|
next.prev = newElems[newElems.length - 1];
|
|
}
|
|
return array.splice.apply(array, spliceArgs);
|
|
}
|
|
/**
|
|
* Insert every element in the set of matched elements to the end of the target.
|
|
*
|
|
* @category Manipulation
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('<li class="plum">Plum</li>').appendTo('#fruits');
|
|
* $.html();
|
|
* //=> <ul id="fruits">
|
|
* // <li class="apple">Apple</li>
|
|
* // <li class="orange">Orange</li>
|
|
* // <li class="pear">Pear</li>
|
|
* // <li class="plum">Plum</li>
|
|
* // </ul>
|
|
* ```
|
|
*
|
|
* @param target - Element to append elements to.
|
|
* @returns The instance itself.
|
|
* @see {@link https://api.jquery.com/appendTo/}
|
|
*/
|
|
function appendTo(target) {
|
|
var appendTarget = utils_1.isCheerio(target)
|
|
? target
|
|
: this._make(target, null, this._originalRoot);
|
|
appendTarget.append(this);
|
|
return this;
|
|
}
|
|
exports.appendTo = appendTo;
|
|
/**
|
|
* Insert every element in the set of matched elements to the beginning of the target.
|
|
*
|
|
* @category Manipulation
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('<li class="plum">Plum</li>').prependTo('#fruits');
|
|
* $.html();
|
|
* //=> <ul id="fruits">
|
|
* // <li class="plum">Plum</li>
|
|
* // <li class="apple">Apple</li>
|
|
* // <li class="orange">Orange</li>
|
|
* // <li class="pear">Pear</li>
|
|
* // </ul>
|
|
* ```
|
|
*
|
|
* @param target - Element to prepend elements to.
|
|
* @returns The instance itself.
|
|
* @see {@link https://api.jquery.com/prependTo/}
|
|
*/
|
|
function prependTo(target) {
|
|
var prependTarget = utils_1.isCheerio(target)
|
|
? target
|
|
: this._make(target, null, this._originalRoot);
|
|
prependTarget.prepend(this);
|
|
return this;
|
|
}
|
|
exports.prependTo = prependTo;
|
|
/**
|
|
* Inserts content as the *last* child of each of the selected elements.
|
|
*
|
|
* @category Manipulation
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('ul').append('<li class="plum">Plum</li>');
|
|
* $.html();
|
|
* //=> <ul id="fruits">
|
|
* // <li class="apple">Apple</li>
|
|
* // <li class="orange">Orange</li>
|
|
* // <li class="pear">Pear</li>
|
|
* // <li class="plum">Plum</li>
|
|
* // </ul>
|
|
* ```
|
|
*
|
|
* @see {@link https://api.jquery.com/append/}
|
|
*/
|
|
exports.append = _insert(function (dom, children, parent) {
|
|
uniqueSplice(children, children.length, 0, dom, parent);
|
|
});
|
|
/**
|
|
* Inserts content as the *first* child of each of the selected elements.
|
|
*
|
|
* @category Manipulation
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('ul').prepend('<li class="plum">Plum</li>');
|
|
* $.html();
|
|
* //=> <ul id="fruits">
|
|
* // <li class="plum">Plum</li>
|
|
* // <li class="apple">Apple</li>
|
|
* // <li class="orange">Orange</li>
|
|
* // <li class="pear">Pear</li>
|
|
* // </ul>
|
|
* ```
|
|
*
|
|
* @see {@link https://api.jquery.com/prepend/}
|
|
*/
|
|
exports.prepend = _insert(function (dom, children, parent) {
|
|
uniqueSplice(children, 0, 0, dom, parent);
|
|
});
|
|
function _wrap(insert) {
|
|
return function (wrapper) {
|
|
var lastIdx = this.length - 1;
|
|
var lastParent = this.parents().last();
|
|
for (var i = 0; i < this.length; i++) {
|
|
var el = this[i];
|
|
var wrap_1 = typeof wrapper === 'function'
|
|
? wrapper.call(el, i, el)
|
|
: typeof wrapper === 'string' && !utils_1.isHtml(wrapper)
|
|
? lastParent.find(wrapper).clone()
|
|
: wrapper;
|
|
var wrapperDom = this._makeDomArray(wrap_1, i < lastIdx)[0];
|
|
if (!wrapperDom || !htmlparser2_1.DomUtils.hasChildren(wrapperDom))
|
|
continue;
|
|
var elInsertLocation = wrapperDom;
|
|
/*
|
|
* Find the deepest child. Only consider the first tag child of each node
|
|
* (ignore text); stop if no children are found.
|
|
*/
|
|
var j = 0;
|
|
while (j < elInsertLocation.children.length) {
|
|
var child = elInsertLocation.children[j];
|
|
if (utils_1.isTag(child)) {
|
|
elInsertLocation = child;
|
|
j = 0;
|
|
}
|
|
else {
|
|
j++;
|
|
}
|
|
}
|
|
insert(el, elInsertLocation, [wrapperDom]);
|
|
}
|
|
return this;
|
|
};
|
|
}
|
|
/**
|
|
* The .wrap() function can take any string or object that could be passed to
|
|
* the $() factory function to specify a DOM structure. This structure may be
|
|
* nested several levels deep, but should contain only one inmost element. A
|
|
* copy of this structure will be wrapped around each of the elements in the set
|
|
* of matched elements. This method returns the original set of elements for
|
|
* chaining purposes.
|
|
*
|
|
* @category Manipulation
|
|
* @example
|
|
*
|
|
* ```js
|
|
* const redFruit = $('<div class="red-fruit"></div>');
|
|
* $('.apple').wrap(redFruit);
|
|
*
|
|
* //=> <ul id="fruits">
|
|
* // <div class="red-fruit">
|
|
* // <li class="apple">Apple</li>
|
|
* // </div>
|
|
* // <li class="orange">Orange</li>
|
|
* // <li class="plum">Plum</li>
|
|
* // </ul>
|
|
*
|
|
* const healthy = $('<div class="healthy"></div>');
|
|
* $('li').wrap(healthy);
|
|
*
|
|
* //=> <ul id="fruits">
|
|
* // <div class="healthy">
|
|
* // <li class="apple">Apple</li>
|
|
* // </div>
|
|
* // <div class="healthy">
|
|
* // <li class="orange">Orange</li>
|
|
* // </div>
|
|
* // <div class="healthy">
|
|
* // <li class="plum">Plum</li>
|
|
* // </div>
|
|
* // </ul>
|
|
* ```
|
|
*
|
|
* @param wrapper - The DOM structure to wrap around each element in the selection.
|
|
* @see {@link https://api.jquery.com/wrap/}
|
|
*/
|
|
exports.wrap = _wrap(function (el, elInsertLocation, wrapperDom) {
|
|
var parent = el.parent;
|
|
if (!parent)
|
|
return;
|
|
var siblings = parent.children;
|
|
var index = siblings.indexOf(el);
|
|
parse_1.update([el], elInsertLocation);
|
|
/*
|
|
* The previous operation removed the current element from the `siblings`
|
|
* array, so the `dom` array can be inserted without removing any
|
|
* additional elements.
|
|
*/
|
|
uniqueSplice(siblings, index, 0, wrapperDom, parent);
|
|
});
|
|
/**
|
|
* The .wrapInner() function can take any string or object that could be passed
|
|
* to the $() factory function to specify a DOM structure. This structure may be
|
|
* nested several levels deep, but should contain only one inmost element. The
|
|
* structure will be wrapped around the content of each of the elements in the
|
|
* set of matched elements.
|
|
*
|
|
* @category Manipulation
|
|
* @example
|
|
*
|
|
* ```js
|
|
* const redFruit = $('<div class="red-fruit"></div>');
|
|
* $('.apple').wrapInner(redFruit);
|
|
*
|
|
* //=> <ul id="fruits">
|
|
* // <li class="apple">
|
|
* // <div class="red-fruit">Apple</div>
|
|
* // </li>
|
|
* // <li class="orange">Orange</li>
|
|
* // <li class="pear">Pear</li>
|
|
* // </ul>
|
|
*
|
|
* const healthy = $('<div class="healthy"></div>');
|
|
* $('li').wrapInner(healthy);
|
|
*
|
|
* //=> <ul id="fruits">
|
|
* // <li class="apple">
|
|
* // <div class="healthy">Apple</div>
|
|
* // </li>
|
|
* // <li class="orange">
|
|
* // <div class="healthy">Orange</div>
|
|
* // </li>
|
|
* // <li class="pear">
|
|
* // <div class="healthy">Pear</div>
|
|
* // </li>
|
|
* // </ul>
|
|
* ```
|
|
*
|
|
* @param wrapper - The DOM structure to wrap around the content of each element
|
|
* in the selection.
|
|
* @returns The instance itself, for chaining.
|
|
* @see {@link https://api.jquery.com/wrapInner/}
|
|
*/
|
|
exports.wrapInner = _wrap(function (el, elInsertLocation, wrapperDom) {
|
|
if (!domhandler_1.hasChildren(el))
|
|
return;
|
|
parse_1.update(el.children, elInsertLocation);
|
|
parse_1.update(wrapperDom, el);
|
|
});
|
|
/**
|
|
* The .unwrap() function, removes the parents of the set of matched elements
|
|
* from the DOM, leaving the matched elements in their place.
|
|
*
|
|
* @category Manipulation
|
|
* @example <caption>without selector</caption>
|
|
*
|
|
* ```js
|
|
* const $ = cheerio.load(
|
|
* '<div id=test>\n <div><p>Hello</p></div>\n <div><p>World</p></div>\n</div>'
|
|
* );
|
|
* $('#test p').unwrap();
|
|
*
|
|
* //=> <div id=test>
|
|
* // <p>Hello</p>
|
|
* // <p>World</p>
|
|
* // </div>
|
|
* ```
|
|
*
|
|
* @example <caption>with selector</caption>
|
|
*
|
|
* ```js
|
|
* const $ = cheerio.load(
|
|
* '<div id=test>\n <p>Hello</p>\n <b><p>World</p></b>\n</div>'
|
|
* );
|
|
* $('#test p').unwrap('b');
|
|
*
|
|
* //=> <div id=test>
|
|
* // <p>Hello</p>
|
|
* // <p>World</p>
|
|
* // </div>
|
|
* ```
|
|
*
|
|
* @param selector - A selector to check the parent element against. If an
|
|
* element's parent does not match the selector, the element won't be unwrapped.
|
|
* @returns The instance itself, for chaining.
|
|
* @see {@link https://api.jquery.com/unwrap/}
|
|
*/
|
|
function unwrap(selector) {
|
|
var _this = this;
|
|
this.parent(selector)
|
|
.not('body')
|
|
.each(function (_, el) {
|
|
_this._make(el).replaceWith(el.children);
|
|
});
|
|
return this;
|
|
}
|
|
exports.unwrap = unwrap;
|
|
/**
|
|
* The .wrapAll() function can take any string or object that could be passed to
|
|
* the $() function to specify a DOM structure. This structure may be nested
|
|
* several levels deep, but should contain only one inmost element. The
|
|
* structure will be wrapped around all of the elements in the set of matched
|
|
* elements, as a single group.
|
|
*
|
|
* @category Manipulation
|
|
* @example <caption>With markup passed to `wrapAll`</caption>
|
|
*
|
|
* ```js
|
|
* const $ = cheerio.load(
|
|
* '<div class="container"><div class="inner">First</div><div class="inner">Second</div></div>'
|
|
* );
|
|
* $('.inner').wrapAll("<div class='new'></div>");
|
|
*
|
|
* //=> <div class="container">
|
|
* // <div class='new'>
|
|
* // <div class="inner">First</div>
|
|
* // <div class="inner">Second</div>
|
|
* // </div>
|
|
* // </div>
|
|
* ```
|
|
*
|
|
* @example <caption>With an existing cheerio instance</caption>
|
|
*
|
|
* ```js
|
|
* const $ = cheerio.load(
|
|
* '<span>Span 1</span><strong>Strong</strong><span>Span 2</span>'
|
|
* );
|
|
* const wrap = $('<div><p><em><b></b></em></p></div>');
|
|
* $('span').wrapAll(wrap);
|
|
*
|
|
* //=> <div>
|
|
* // <p>
|
|
* // <em>
|
|
* // <b>
|
|
* // <span>Span 1</span>
|
|
* // <span>Span 2</span>
|
|
* // </b>
|
|
* // </em>
|
|
* // </p>
|
|
* // </div>
|
|
* // <strong>Strong</strong>
|
|
* ```
|
|
*
|
|
* @param wrapper - The DOM structure to wrap around all matched elements in the
|
|
* selection.
|
|
* @returns The instance itself.
|
|
* @see {@link https://api.jquery.com/wrapAll/}
|
|
*/
|
|
function wrapAll(wrapper) {
|
|
var el = this[0];
|
|
if (el) {
|
|
var wrap_2 = this._make(typeof wrapper === 'function' ? wrapper.call(el, 0, el) : wrapper).insertBefore(el);
|
|
// If html is given as wrapper, wrap may contain text elements
|
|
var elInsertLocation = void 0;
|
|
for (var i = 0; i < wrap_2.length; i++) {
|
|
if (wrap_2[i].type === 'tag')
|
|
elInsertLocation = wrap_2[i];
|
|
}
|
|
var j = 0;
|
|
/*
|
|
* Find the deepest child. Only consider the first tag child of each node
|
|
* (ignore text); stop if no children are found.
|
|
*/
|
|
while (elInsertLocation && j < elInsertLocation.children.length) {
|
|
var child = elInsertLocation.children[j];
|
|
if (child.type === 'tag') {
|
|
elInsertLocation = child;
|
|
j = 0;
|
|
}
|
|
else {
|
|
j++;
|
|
}
|
|
}
|
|
if (elInsertLocation)
|
|
this._make(elInsertLocation).append(this);
|
|
}
|
|
return this;
|
|
}
|
|
exports.wrapAll = wrapAll;
|
|
/* eslint-disable jsdoc/check-param-names*/
|
|
/**
|
|
* Insert content next to each element in the set of matched elements.
|
|
*
|
|
* @category Manipulation
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.apple').after('<li class="plum">Plum</li>');
|
|
* $.html();
|
|
* //=> <ul id="fruits">
|
|
* // <li class="apple">Apple</li>
|
|
* // <li class="plum">Plum</li>
|
|
* // <li class="orange">Orange</li>
|
|
* // <li class="pear">Pear</li>
|
|
* // </ul>
|
|
* ```
|
|
*
|
|
* @param content - HTML string, DOM element, array of DOM elements or Cheerio
|
|
* to insert after each element in the set of matched elements.
|
|
* @returns The instance itself.
|
|
* @see {@link https://api.jquery.com/after/}
|
|
*/
|
|
function after() {
|
|
var _this = this;
|
|
var elems = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
elems[_i] = arguments[_i];
|
|
}
|
|
var lastIdx = this.length - 1;
|
|
return utils_1.domEach(this, function (i, el) {
|
|
var parent = el.parent;
|
|
if (!htmlparser2_1.DomUtils.hasChildren(el) || !parent) {
|
|
return;
|
|
}
|
|
var siblings = parent.children;
|
|
var index = siblings.indexOf(el);
|
|
// If not found, move on
|
|
/* istanbul ignore next */
|
|
if (index < 0)
|
|
return;
|
|
var domSrc = typeof elems[0] === 'function'
|
|
? elems[0].call(el, i, static_1.html(el.children))
|
|
: elems;
|
|
var dom = _this._makeDomArray(domSrc, i < lastIdx);
|
|
// Add element after `this` element
|
|
uniqueSplice(siblings, index + 1, 0, dom, parent);
|
|
});
|
|
}
|
|
exports.after = after;
|
|
/* eslint-enable jsdoc/check-param-names*/
|
|
/**
|
|
* Insert every element in the set of matched elements after the target.
|
|
*
|
|
* @category Manipulation
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('<li class="plum">Plum</li>').insertAfter('.apple');
|
|
* $.html();
|
|
* //=> <ul id="fruits">
|
|
* // <li class="apple">Apple</li>
|
|
* // <li class="plum">Plum</li>
|
|
* // <li class="orange">Orange</li>
|
|
* // <li class="pear">Pear</li>
|
|
* // </ul>
|
|
* ```
|
|
*
|
|
* @param target - Element to insert elements after.
|
|
* @returns The set of newly inserted elements.
|
|
* @see {@link https://api.jquery.com/insertAfter/}
|
|
*/
|
|
function insertAfter(target) {
|
|
var _this = this;
|
|
if (typeof target === 'string') {
|
|
target = this._make(target, null, this._originalRoot);
|
|
}
|
|
this.remove();
|
|
var clones = [];
|
|
utils_1.domEach(this._makeDomArray(target), function (_, el) {
|
|
var clonedSelf = _this.clone().toArray();
|
|
var parent = el.parent;
|
|
if (!parent) {
|
|
return;
|
|
}
|
|
var siblings = parent.children;
|
|
var index = siblings.indexOf(el);
|
|
// If not found, move on
|
|
/* istanbul ignore next */
|
|
if (index < 0)
|
|
return;
|
|
// Add cloned `this` element(s) after target element
|
|
uniqueSplice(siblings, index + 1, 0, clonedSelf, parent);
|
|
clones.push.apply(clones, clonedSelf);
|
|
});
|
|
return this._make(clones);
|
|
}
|
|
exports.insertAfter = insertAfter;
|
|
/* eslint-disable jsdoc/check-param-names*/
|
|
/**
|
|
* Insert content previous to each element in the set of matched elements.
|
|
*
|
|
* @category Manipulation
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.apple').before('<li class="plum">Plum</li>');
|
|
* $.html();
|
|
* //=> <ul id="fruits">
|
|
* // <li class="plum">Plum</li>
|
|
* // <li class="apple">Apple</li>
|
|
* // <li class="orange">Orange</li>
|
|
* // <li class="pear">Pear</li>
|
|
* // </ul>
|
|
* ```
|
|
*
|
|
* @param content - HTML string, DOM element, array of DOM elements or Cheerio
|
|
* to insert before each element in the set of matched elements.
|
|
* @returns The instance itself.
|
|
* @see {@link https://api.jquery.com/before/}
|
|
*/
|
|
function before() {
|
|
var _this = this;
|
|
var elems = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
elems[_i] = arguments[_i];
|
|
}
|
|
var lastIdx = this.length - 1;
|
|
return utils_1.domEach(this, function (i, el) {
|
|
var parent = el.parent;
|
|
if (!htmlparser2_1.DomUtils.hasChildren(el) || !parent) {
|
|
return;
|
|
}
|
|
var siblings = parent.children;
|
|
var index = siblings.indexOf(el);
|
|
// If not found, move on
|
|
/* istanbul ignore next */
|
|
if (index < 0)
|
|
return;
|
|
var domSrc = typeof elems[0] === 'function'
|
|
? elems[0].call(el, i, static_1.html(el.children))
|
|
: elems;
|
|
var dom = _this._makeDomArray(domSrc, i < lastIdx);
|
|
// Add element before `el` element
|
|
uniqueSplice(siblings, index, 0, dom, parent);
|
|
});
|
|
}
|
|
exports.before = before;
|
|
/* eslint-enable jsdoc/check-param-names*/
|
|
/**
|
|
* Insert every element in the set of matched elements before the target.
|
|
*
|
|
* @category Manipulation
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('<li class="plum">Plum</li>').insertBefore('.apple');
|
|
* $.html();
|
|
* //=> <ul id="fruits">
|
|
* // <li class="plum">Plum</li>
|
|
* // <li class="apple">Apple</li>
|
|
* // <li class="orange">Orange</li>
|
|
* // <li class="pear">Pear</li>
|
|
* // </ul>
|
|
* ```
|
|
*
|
|
* @param target - Element to insert elements before.
|
|
* @returns The set of newly inserted elements.
|
|
* @see {@link https://api.jquery.com/insertBefore/}
|
|
*/
|
|
function insertBefore(target) {
|
|
var _this = this;
|
|
var targetArr = this._make(target, null, this._originalRoot);
|
|
this.remove();
|
|
var clones = [];
|
|
utils_1.domEach(targetArr, function (_, el) {
|
|
var clonedSelf = _this.clone().toArray();
|
|
var parent = el.parent;
|
|
if (!parent) {
|
|
return;
|
|
}
|
|
var siblings = parent.children;
|
|
var index = siblings.indexOf(el);
|
|
// If not found, move on
|
|
/* istanbul ignore next */
|
|
if (index < 0)
|
|
return;
|
|
// Add cloned `this` element(s) after target element
|
|
uniqueSplice(siblings, index, 0, clonedSelf, parent);
|
|
clones.push.apply(clones, clonedSelf);
|
|
});
|
|
return this._make(clones);
|
|
}
|
|
exports.insertBefore = insertBefore;
|
|
/**
|
|
* Removes the set of matched elements from the DOM and all their children.
|
|
* `selector` filters the set of matched elements to be removed.
|
|
*
|
|
* @category Manipulation
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.pear').remove();
|
|
* $.html();
|
|
* //=> <ul id="fruits">
|
|
* // <li class="apple">Apple</li>
|
|
* // <li class="orange">Orange</li>
|
|
* // </ul>
|
|
* ```
|
|
*
|
|
* @param selector - Optional selector for elements to remove.
|
|
* @returns The instance itself.
|
|
* @see {@link https://api.jquery.com/remove/}
|
|
*/
|
|
function remove(selector) {
|
|
// Filter if we have selector
|
|
var elems = selector ? this.filter(selector) : this;
|
|
utils_1.domEach(elems, function (_, el) {
|
|
htmlparser2_1.DomUtils.removeElement(el);
|
|
el.prev = el.next = el.parent = null;
|
|
});
|
|
return this;
|
|
}
|
|
exports.remove = remove;
|
|
/**
|
|
* Replaces matched elements with `content`.
|
|
*
|
|
* @category Manipulation
|
|
* @example
|
|
*
|
|
* ```js
|
|
* const plum = $('<li class="plum">Plum</li>');
|
|
* $('.pear').replaceWith(plum);
|
|
* $.html();
|
|
* //=> <ul id="fruits">
|
|
* // <li class="apple">Apple</li>
|
|
* // <li class="orange">Orange</li>
|
|
* // <li class="plum">Plum</li>
|
|
* // </ul>
|
|
* ```
|
|
*
|
|
* @param content - Replacement for matched elements.
|
|
* @returns The instance itself.
|
|
* @see {@link https://api.jquery.com/replaceWith/}
|
|
*/
|
|
function replaceWith(content) {
|
|
var _this = this;
|
|
return utils_1.domEach(this, function (i, el) {
|
|
var parent = el.parent;
|
|
if (!parent) {
|
|
return;
|
|
}
|
|
var siblings = parent.children;
|
|
var cont = typeof content === 'function' ? content.call(el, i, el) : content;
|
|
var dom = _this._makeDomArray(cont);
|
|
/*
|
|
* In the case that `dom` contains nodes that already exist in other
|
|
* structures, ensure those nodes are properly removed.
|
|
*/
|
|
parse_1.update(dom, null);
|
|
var index = siblings.indexOf(el);
|
|
// Completely remove old element
|
|
uniqueSplice(siblings, index, 1, dom, parent);
|
|
if (!dom.includes(el)) {
|
|
el.parent = el.prev = el.next = null;
|
|
}
|
|
});
|
|
}
|
|
exports.replaceWith = replaceWith;
|
|
/**
|
|
* Empties an element, removing all its children.
|
|
*
|
|
* @category Manipulation
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('ul').empty();
|
|
* $.html();
|
|
* //=> <ul id="fruits"></ul>
|
|
* ```
|
|
*
|
|
* @returns The instance itself.
|
|
* @see {@link https://api.jquery.com/empty/}
|
|
*/
|
|
function empty() {
|
|
return utils_1.domEach(this, function (_, el) {
|
|
if (!htmlparser2_1.DomUtils.hasChildren(el))
|
|
return;
|
|
el.children.forEach(function (child) {
|
|
child.next = child.prev = child.parent = null;
|
|
});
|
|
el.children.length = 0;
|
|
});
|
|
}
|
|
exports.empty = empty;
|
|
function html(str) {
|
|
if (str === undefined) {
|
|
var el = this[0];
|
|
if (!el || !htmlparser2_1.DomUtils.hasChildren(el))
|
|
return null;
|
|
return static_1.html(el.children, this.options);
|
|
}
|
|
// Keep main options unchanged
|
|
var opts = tslib_1.__assign(tslib_1.__assign({}, this.options), { context: null });
|
|
return utils_1.domEach(this, function (_, el) {
|
|
if (!htmlparser2_1.DomUtils.hasChildren(el))
|
|
return;
|
|
el.children.forEach(function (child) {
|
|
child.next = child.prev = child.parent = null;
|
|
});
|
|
opts.context = el;
|
|
var content = utils_1.isCheerio(str)
|
|
? str.clone().get()
|
|
: parse_1.default("" + str, opts, false).children;
|
|
parse_1.update(content, el);
|
|
});
|
|
}
|
|
exports.html = html;
|
|
/**
|
|
* Turns the collection to a string. Alias for `.html()`.
|
|
*
|
|
* @category Manipulation
|
|
* @returns The rendered document.
|
|
*/
|
|
function toString() {
|
|
return static_1.html(this, this.options);
|
|
}
|
|
exports.toString = toString;
|
|
function text(str) {
|
|
var _this = this;
|
|
// If `str` is undefined, act as a "getter"
|
|
if (str === undefined) {
|
|
return static_1.text(this);
|
|
}
|
|
if (typeof str === 'function') {
|
|
// Function support
|
|
return utils_1.domEach(this, function (i, el) {
|
|
text.call(_this._make(el), str.call(el, i, static_1.text([el])));
|
|
});
|
|
}
|
|
// Append text node to each selected elements
|
|
return utils_1.domEach(this, function (_, el) {
|
|
if (!htmlparser2_1.DomUtils.hasChildren(el))
|
|
return;
|
|
el.children.forEach(function (child) {
|
|
child.next = child.prev = child.parent = null;
|
|
});
|
|
var textNode = new domhandler_2.Text(str);
|
|
parse_1.update(textNode, el);
|
|
});
|
|
}
|
|
exports.text = text;
|
|
/**
|
|
* Clone the cheerio object.
|
|
*
|
|
* @category Manipulation
|
|
* @example
|
|
*
|
|
* ```js
|
|
* const moreFruit = $('#fruits').clone();
|
|
* ```
|
|
*
|
|
* @returns The cloned object.
|
|
* @see {@link https://api.jquery.com/clone/}
|
|
*/
|
|
function clone() {
|
|
return this._make(utils_1.cloneDom(this.get()));
|
|
}
|
|
exports.clone = clone;
|
|
|
|
},{"../parse":15,"../static":18,"../utils":20,"domhandler":38,"htmlparser2":58,"tslib":88}],11:[function(require,module,exports){
|
|
"use strict";
|
|
/**
|
|
* Methods for traversing the DOM structure.
|
|
*
|
|
* @module cheerio/traversing
|
|
*/
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.addBack = exports.add = exports.end = exports.slice = exports.index = exports.get = exports.eq = exports.last = exports.first = exports.has = exports.not = exports.filter = exports.map = exports.each = exports.contents = exports.children = exports.siblings = exports.prevUntil = exports.prevAll = exports.prev = exports.nextUntil = exports.nextAll = exports.next = exports.closest = exports.parentsUntil = exports.parents = exports.parent = exports.find = void 0;
|
|
var tslib_1 = require("tslib");
|
|
var domhandler_1 = require("domhandler");
|
|
var select = tslib_1.__importStar(require("cheerio-select"));
|
|
var utils_1 = require("../utils");
|
|
var htmlparser2_1 = require("htmlparser2");
|
|
var uniqueSort = htmlparser2_1.DomUtils.uniqueSort;
|
|
var reSiblingSelector = /^\s*[~+]/;
|
|
/**
|
|
* Get the descendants of each element in the current set of matched elements,
|
|
* filtered by a selector, jQuery object, or element.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('#fruits').find('li').length;
|
|
* //=> 3
|
|
* $('#fruits').find($('.apple')).length;
|
|
* //=> 1
|
|
* ```
|
|
*
|
|
* @param selectorOrHaystack - Element to look for.
|
|
* @returns The found elements.
|
|
* @see {@link https://api.jquery.com/find/}
|
|
*/
|
|
function find(selectorOrHaystack) {
|
|
if (!selectorOrHaystack) {
|
|
return this._make([]);
|
|
}
|
|
var context = this.toArray();
|
|
if (typeof selectorOrHaystack !== 'string') {
|
|
var contains_1 = this.constructor.contains;
|
|
var haystack = utils_1.isCheerio(selectorOrHaystack)
|
|
? selectorOrHaystack.get()
|
|
: [selectorOrHaystack];
|
|
return this._make(haystack.filter(function (elem) { return context.some(function (node) { return contains_1(node, elem); }); }));
|
|
}
|
|
var elems = reSiblingSelector.test(selectorOrHaystack)
|
|
? context
|
|
: context.reduce(function (newElems, elem) {
|
|
return domhandler_1.hasChildren(elem)
|
|
? newElems.concat(elem.children.filter(utils_1.isTag))
|
|
: newElems;
|
|
}, []);
|
|
var options = { context: context, xmlMode: this.options.xmlMode };
|
|
return this._make(select.select(selectorOrHaystack, elems, options));
|
|
}
|
|
exports.find = find;
|
|
/**
|
|
* Get the parent of each element in the current set of matched elements,
|
|
* optionally filtered by a selector.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.pear').parent().attr('id');
|
|
* //=> fruits
|
|
* ```
|
|
*
|
|
* @param selector - If specified filter for parent.
|
|
* @returns The parents.
|
|
* @see {@link https://api.jquery.com/parent/}
|
|
*/
|
|
function parent(selector) {
|
|
var set = [];
|
|
utils_1.domEach(this, function (_, elem) {
|
|
var parentElem = elem.parent;
|
|
if (parentElem &&
|
|
parentElem.type !== 'root' &&
|
|
!set.includes(parentElem)) {
|
|
set.push(parentElem);
|
|
}
|
|
});
|
|
return selector ? filter.call(set, selector, this) : this._make(set);
|
|
}
|
|
exports.parent = parent;
|
|
/**
|
|
* Get a set of parents filtered by `selector` of each element in the current
|
|
* set of match elements.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.orange').parents().length;
|
|
* //=> 2
|
|
* $('.orange').parents('#fruits').length;
|
|
* //=> 1
|
|
* ```
|
|
*
|
|
* @param selector - If specified filter for parents.
|
|
* @returns The parents.
|
|
* @see {@link https://api.jquery.com/parents/}
|
|
*/
|
|
function parents(selector) {
|
|
var _this = this;
|
|
var parentNodes = [];
|
|
/*
|
|
* When multiple DOM elements are in the original set, the resulting set will
|
|
* be in *reverse* order of the original elements as well, with duplicates
|
|
* removed.
|
|
*/
|
|
this.get()
|
|
.reverse()
|
|
.forEach(function (elem) {
|
|
return traverseParents(_this, elem.parent, selector, Infinity).forEach(function (node) {
|
|
// We know these must be `Element`s, as we filter out root nodes.
|
|
if (!parentNodes.includes(node)) {
|
|
parentNodes.push(node);
|
|
}
|
|
});
|
|
});
|
|
return this._make(parentNodes);
|
|
}
|
|
exports.parents = parents;
|
|
/**
|
|
* Get the ancestors of each element in the current set of matched elements, up
|
|
* to but not including the element matched by the selector, DOM node, or cheerio object.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.orange').parentsUntil('#food').length;
|
|
* //=> 1
|
|
* ```
|
|
*
|
|
* @param selector - Selector for element to stop at.
|
|
* @param filterBy - Optional filter for parents.
|
|
* @returns The parents.
|
|
* @see {@link https://api.jquery.com/parentsUntil/}
|
|
*/
|
|
function parentsUntil(selector, filterBy) {
|
|
var parentNodes = [];
|
|
var untilNode;
|
|
var untilNodes;
|
|
if (typeof selector === 'string') {
|
|
untilNodes = this.parents(selector).toArray();
|
|
}
|
|
else if (selector && utils_1.isCheerio(selector)) {
|
|
untilNodes = selector.toArray();
|
|
}
|
|
else if (selector) {
|
|
untilNode = selector;
|
|
}
|
|
/*
|
|
* When multiple DOM elements are in the original set, the resulting set will
|
|
* be in *reverse* order of the original elements as well, with duplicates
|
|
* removed.
|
|
*/
|
|
this.toArray()
|
|
.reverse()
|
|
.forEach(function (elem) {
|
|
while (elem.parent) {
|
|
elem = elem.parent;
|
|
if ((untilNode && elem !== untilNode) ||
|
|
(untilNodes && !untilNodes.includes(elem)) ||
|
|
(!untilNode && !untilNodes)) {
|
|
if (utils_1.isTag(elem) && !parentNodes.includes(elem)) {
|
|
parentNodes.push(elem);
|
|
}
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
}, this);
|
|
return filterBy
|
|
? filter.call(parentNodes, filterBy, this)
|
|
: this._make(parentNodes);
|
|
}
|
|
exports.parentsUntil = parentsUntil;
|
|
/**
|
|
* For each element in the set, get the first element that matches the selector
|
|
* by testing the element itself and traversing up through its ancestors in the DOM tree.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.orange').closest();
|
|
* //=> []
|
|
*
|
|
* $('.orange').closest('.apple');
|
|
* // => []
|
|
*
|
|
* $('.orange').closest('li');
|
|
* //=> [<li class="orange">Orange</li>]
|
|
*
|
|
* $('.orange').closest('#fruits');
|
|
* //=> [<ul id="fruits"> ... </ul>]
|
|
* ```
|
|
*
|
|
* @param selector - Selector for the element to find.
|
|
* @returns The closest nodes.
|
|
* @see {@link https://api.jquery.com/closest/}
|
|
*/
|
|
function closest(selector) {
|
|
var _this = this;
|
|
var set = [];
|
|
if (!selector) {
|
|
return this._make(set);
|
|
}
|
|
utils_1.domEach(this, function (_, elem) {
|
|
var closestElem = traverseParents(_this, elem, selector, 1)[0];
|
|
// Do not add duplicate elements to the set
|
|
if (closestElem && !set.includes(closestElem)) {
|
|
set.push(closestElem);
|
|
}
|
|
});
|
|
return this._make(set);
|
|
}
|
|
exports.closest = closest;
|
|
/**
|
|
* Gets the next sibling of the first selected element, optionally filtered by a selector.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.apple').next().hasClass('orange');
|
|
* //=> true
|
|
* ```
|
|
*
|
|
* @param selector - If specified filter for sibling.
|
|
* @returns The next nodes.
|
|
* @see {@link https://api.jquery.com/next/}
|
|
*/
|
|
function next(selector) {
|
|
var elems = [];
|
|
utils_1.domEach(this, function (_, elem) {
|
|
while (elem.next) {
|
|
elem = elem.next;
|
|
if (utils_1.isTag(elem)) {
|
|
elems.push(elem);
|
|
return;
|
|
}
|
|
}
|
|
});
|
|
return selector ? filter.call(elems, selector, this) : this._make(elems);
|
|
}
|
|
exports.next = next;
|
|
/**
|
|
* Gets all the following siblings of the first selected element, optionally
|
|
* filtered by a selector.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.apple').nextAll();
|
|
* //=> [<li class="orange">Orange</li>, <li class="pear">Pear</li>]
|
|
* $('.apple').nextAll('.orange');
|
|
* //=> [<li class="orange">Orange</li>]
|
|
* ```
|
|
*
|
|
* @param selector - If specified filter for siblings.
|
|
* @returns The next nodes.
|
|
* @see {@link https://api.jquery.com/nextAll/}
|
|
*/
|
|
function nextAll(selector) {
|
|
var elems = [];
|
|
utils_1.domEach(this, function (_, elem) {
|
|
while (elem.next) {
|
|
elem = elem.next;
|
|
if (utils_1.isTag(elem) && !elems.includes(elem)) {
|
|
elems.push(elem);
|
|
}
|
|
}
|
|
});
|
|
return selector ? filter.call(elems, selector, this) : this._make(elems);
|
|
}
|
|
exports.nextAll = nextAll;
|
|
/**
|
|
* Gets all the following siblings up to but not including the element matched
|
|
* by the selector, optionally filtered by another selector.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.apple').nextUntil('.pear');
|
|
* //=> [<li class="orange">Orange</li>]
|
|
* ```
|
|
*
|
|
* @param selector - Selector for element to stop at.
|
|
* @param filterSelector - If specified filter for siblings.
|
|
* @returns The next nodes.
|
|
* @see {@link https://api.jquery.com/nextUntil/}
|
|
*/
|
|
function nextUntil(selector, filterSelector) {
|
|
var elems = [];
|
|
var untilNode;
|
|
var untilNodes;
|
|
if (typeof selector === 'string') {
|
|
untilNodes = this.nextAll(selector).toArray();
|
|
}
|
|
else if (selector && utils_1.isCheerio(selector)) {
|
|
untilNodes = selector.get();
|
|
}
|
|
else if (selector) {
|
|
untilNode = selector;
|
|
}
|
|
utils_1.domEach(this, function (_, elem) {
|
|
while (elem.next) {
|
|
elem = elem.next;
|
|
if ((untilNode && elem !== untilNode) ||
|
|
(untilNodes && !untilNodes.includes(elem)) ||
|
|
(!untilNode && !untilNodes)) {
|
|
if (utils_1.isTag(elem) && !elems.includes(elem)) {
|
|
elems.push(elem);
|
|
}
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
return filterSelector
|
|
? filter.call(elems, filterSelector, this)
|
|
: this._make(elems);
|
|
}
|
|
exports.nextUntil = nextUntil;
|
|
/**
|
|
* Gets the previous sibling of the first selected element optionally filtered
|
|
* by a selector.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.orange').prev().hasClass('apple');
|
|
* //=> true
|
|
* ```
|
|
*
|
|
* @param selector - If specified filter for siblings.
|
|
* @returns The previous nodes.
|
|
* @see {@link https://api.jquery.com/prev/}
|
|
*/
|
|
function prev(selector) {
|
|
var elems = [];
|
|
utils_1.domEach(this, function (_, elem) {
|
|
while (elem.prev) {
|
|
elem = elem.prev;
|
|
if (utils_1.isTag(elem)) {
|
|
elems.push(elem);
|
|
return;
|
|
}
|
|
}
|
|
});
|
|
return selector ? filter.call(elems, selector, this) : this._make(elems);
|
|
}
|
|
exports.prev = prev;
|
|
/**
|
|
* Gets all the preceding siblings of the first selected element, optionally
|
|
* filtered by a selector.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.pear').prevAll();
|
|
* //=> [<li class="orange">Orange</li>, <li class="apple">Apple</li>]
|
|
*
|
|
* $('.pear').prevAll('.orange');
|
|
* //=> [<li class="orange">Orange</li>]
|
|
* ```
|
|
*
|
|
* @param selector - If specified filter for siblings.
|
|
* @returns The previous nodes.
|
|
* @see {@link https://api.jquery.com/prevAll/}
|
|
*/
|
|
function prevAll(selector) {
|
|
var elems = [];
|
|
utils_1.domEach(this, function (_, elem) {
|
|
while (elem.prev) {
|
|
elem = elem.prev;
|
|
if (utils_1.isTag(elem) && !elems.includes(elem)) {
|
|
elems.push(elem);
|
|
}
|
|
}
|
|
});
|
|
return selector ? filter.call(elems, selector, this) : this._make(elems);
|
|
}
|
|
exports.prevAll = prevAll;
|
|
/**
|
|
* Gets all the preceding siblings up to but not including the element matched
|
|
* by the selector, optionally filtered by another selector.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.pear').prevUntil('.apple');
|
|
* //=> [<li class="orange">Orange</li>]
|
|
* ```
|
|
*
|
|
* @param selector - Selector for element to stop at.
|
|
* @param filterSelector - If specified filter for siblings.
|
|
* @returns The previous nodes.
|
|
* @see {@link https://api.jquery.com/prevUntil/}
|
|
*/
|
|
function prevUntil(selector, filterSelector) {
|
|
var elems = [];
|
|
var untilNode;
|
|
var untilNodes;
|
|
if (typeof selector === 'string') {
|
|
untilNodes = this.prevAll(selector).toArray();
|
|
}
|
|
else if (selector && utils_1.isCheerio(selector)) {
|
|
untilNodes = selector.get();
|
|
}
|
|
else if (selector) {
|
|
untilNode = selector;
|
|
}
|
|
utils_1.domEach(this, function (_, elem) {
|
|
while (elem.prev) {
|
|
elem = elem.prev;
|
|
if ((untilNode && elem !== untilNode) ||
|
|
(untilNodes && !untilNodes.includes(elem)) ||
|
|
(!untilNode && !untilNodes)) {
|
|
if (utils_1.isTag(elem) && !elems.includes(elem)) {
|
|
elems.push(elem);
|
|
}
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
return filterSelector
|
|
? filter.call(elems, filterSelector, this)
|
|
: this._make(elems);
|
|
}
|
|
exports.prevUntil = prevUntil;
|
|
/**
|
|
* Get the siblings of each element (excluding the element) in the set of
|
|
* matched elements, optionally filtered by a selector.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.pear').siblings().length;
|
|
* //=> 2
|
|
*
|
|
* $('.pear').siblings('.orange').length;
|
|
* //=> 1
|
|
* ```
|
|
*
|
|
* @param selector - If specified filter for siblings.
|
|
* @returns The siblings.
|
|
* @see {@link https://api.jquery.com/siblings/}
|
|
*/
|
|
function siblings(selector) {
|
|
var _this = this;
|
|
// TODO Still get siblings if `parent` is null; see DomUtils' `getSiblings`.
|
|
var parent = this.parent();
|
|
var elems = parent
|
|
.children()
|
|
.toArray()
|
|
// TODO: This removes all elements in the selection. Note that they could be added here, if siblings are part of the selection.
|
|
.filter(function (elem) { return !_this.is(elem); });
|
|
return selector ? filter.call(elems, selector, this) : this._make(elems);
|
|
}
|
|
exports.siblings = siblings;
|
|
/**
|
|
* Gets the children of the first selected element.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('#fruits').children().length;
|
|
* //=> 3
|
|
*
|
|
* $('#fruits').children('.pear').text();
|
|
* //=> Pear
|
|
* ```
|
|
*
|
|
* @param selector - If specified filter for children.
|
|
* @returns The children.
|
|
* @see {@link https://api.jquery.com/children/}
|
|
*/
|
|
function children(selector) {
|
|
var elems = this.toArray().reduce(function (newElems, elem) {
|
|
return domhandler_1.hasChildren(elem)
|
|
? newElems.concat(elem.children.filter(utils_1.isTag))
|
|
: newElems;
|
|
}, []);
|
|
return selector ? filter.call(elems, selector, this) : this._make(elems);
|
|
}
|
|
exports.children = children;
|
|
/**
|
|
* Gets the children of each element in the set of matched elements, including
|
|
* text and comment nodes.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('#fruits').contents().length;
|
|
* //=> 3
|
|
* ```
|
|
*
|
|
* @returns The children.
|
|
* @see {@link https://api.jquery.com/contents/}
|
|
*/
|
|
function contents() {
|
|
var elems = this.toArray().reduce(function (newElems, elem) {
|
|
return domhandler_1.hasChildren(elem) ? newElems.concat(elem.children) : newElems;
|
|
}, []);
|
|
return this._make(elems);
|
|
}
|
|
exports.contents = contents;
|
|
/**
|
|
* Iterates over a cheerio object, executing a function for each matched
|
|
* element. When the callback is fired, the function is fired in the context of
|
|
* the DOM element, so `this` refers to the current element, which is equivalent
|
|
* to the function parameter `element`. To break out of the `each` loop early,
|
|
* return with `false`.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* const fruits = [];
|
|
*
|
|
* $('li').each(function (i, elem) {
|
|
* fruits[i] = $(this).text();
|
|
* });
|
|
*
|
|
* fruits.join(', ');
|
|
* //=> Apple, Orange, Pear
|
|
* ```
|
|
*
|
|
* @param fn - Function to execute.
|
|
* @returns The instance itself, useful for chaining.
|
|
* @see {@link https://api.jquery.com/each/}
|
|
*/
|
|
function each(fn) {
|
|
var i = 0;
|
|
var len = this.length;
|
|
while (i < len && fn.call(this[i], i, this[i]) !== false)
|
|
++i;
|
|
return this;
|
|
}
|
|
exports.each = each;
|
|
/**
|
|
* Pass each element in the current matched set through a function, producing a
|
|
* new Cheerio object containing the return values. The function can return an
|
|
* individual data item or an array of data items to be inserted into the
|
|
* resulting set. If an array is returned, the elements inside the array are
|
|
* inserted into the set. If the function returns null or undefined, no element
|
|
* will be inserted.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('li')
|
|
* .map(function (i, el) {
|
|
* // this === el
|
|
* return $(this).text();
|
|
* })
|
|
* .toArray()
|
|
* .join(' ');
|
|
* //=> "apple orange pear"
|
|
* ```
|
|
*
|
|
* @param fn - Function to execute.
|
|
* @returns The mapped elements, wrapped in a Cheerio collection.
|
|
* @see {@link https://api.jquery.com/map/}
|
|
*/
|
|
function map(fn) {
|
|
var elems = [];
|
|
for (var i = 0; i < this.length; i++) {
|
|
var el = this[i];
|
|
var val = fn.call(el, i, el);
|
|
if (val != null) {
|
|
elems = elems.concat(val);
|
|
}
|
|
}
|
|
return this._make(elems);
|
|
}
|
|
exports.map = map;
|
|
function getFilterFn(match) {
|
|
if (typeof match === 'function') {
|
|
return function (el, i) {
|
|
return match.call(el, i, el);
|
|
};
|
|
}
|
|
if (utils_1.isCheerio(match)) {
|
|
return match.is.bind(match);
|
|
}
|
|
return function (el) {
|
|
return match === el;
|
|
};
|
|
}
|
|
/**
|
|
* Iterates over a cheerio object, reducing the set of selector elements to
|
|
* those that match the selector or pass the function's test. When a Cheerio
|
|
* selection is specified, return only the elements contained in that selection.
|
|
* When an element is specified, return only that element (if it is contained in
|
|
* the original selection). If using the function method, the function is
|
|
* executed in the context of the selected element, so `this` refers to the
|
|
* current element.
|
|
*
|
|
* @category Traversing
|
|
* @example <caption>Selector</caption>
|
|
*
|
|
* ```js
|
|
* $('li').filter('.orange').attr('class');
|
|
* //=> orange
|
|
* ```
|
|
*
|
|
* @example <caption>Function</caption>
|
|
*
|
|
* ```js
|
|
* $('li')
|
|
* .filter(function (i, el) {
|
|
* // this === el
|
|
* return $(this).attr('class') === 'orange';
|
|
* })
|
|
* .attr('class'); //=> orange
|
|
* ```
|
|
*
|
|
* @param match - Value to look for, following the rules above.
|
|
* @param container - Optional node to filter instead.
|
|
* @returns The filtered collection.
|
|
* @see {@link https://api.jquery.com/filter/}
|
|
*/
|
|
function filter(match, container) {
|
|
if (container === void 0) { container = this; }
|
|
if (!utils_1.isCheerio(container)) {
|
|
throw new Error('Not able to create a Cheerio instance.');
|
|
}
|
|
var nodes = utils_1.isCheerio(this) ? this.toArray() : this;
|
|
var elements = nodes.filter(utils_1.isTag);
|
|
elements =
|
|
typeof match === 'string'
|
|
? select.filter(match, elements, container.options)
|
|
: elements.filter(getFilterFn(match));
|
|
return container._make(elements);
|
|
}
|
|
exports.filter = filter;
|
|
/**
|
|
* Remove elements from the set of matched elements. Given a Cheerio object that
|
|
* represents a set of DOM elements, the `.not()` method constructs a new
|
|
* Cheerio object from a subset of the matching elements. The supplied selector
|
|
* is tested against each element; the elements that don't match the selector
|
|
* will be included in the result.
|
|
*
|
|
* The `.not()` method can take a function as its argument in the same way that
|
|
* `.filter()` does. Elements for which the function returns `true` are excluded
|
|
* from the filtered set; all other elements are included.
|
|
*
|
|
* @category Traversing
|
|
* @example <caption>Selector</caption>
|
|
*
|
|
* ```js
|
|
* $('li').not('.apple').length;
|
|
* //=> 2
|
|
* ```
|
|
*
|
|
* @example <caption>Function</caption>
|
|
*
|
|
* ```js
|
|
* $('li').not(function (i, el) {
|
|
* // this === el
|
|
* return $(this).attr('class') === 'orange';
|
|
* }).length; //=> 2
|
|
* ```
|
|
*
|
|
* @param match - Value to look for, following the rules above.
|
|
* @param container - Optional node to filter instead.
|
|
* @returns The filtered collection.
|
|
* @see {@link https://api.jquery.com/not/}
|
|
*/
|
|
function not(match, container) {
|
|
if (container === void 0) { container = this; }
|
|
if (!utils_1.isCheerio(container)) {
|
|
throw new Error('Not able to create a Cheerio instance.');
|
|
}
|
|
var nodes = utils_1.isCheerio(this) ? this.toArray() : this;
|
|
if (typeof match === 'string') {
|
|
var elements = nodes.filter(utils_1.isTag);
|
|
var matches_1 = new Set(select.filter(match, elements, container.options));
|
|
nodes = nodes.filter(function (el) { return !matches_1.has(el); });
|
|
}
|
|
else {
|
|
var filterFn_1 = getFilterFn(match);
|
|
nodes = nodes.filter(function (el, i) { return !filterFn_1(el, i); });
|
|
}
|
|
return container._make(nodes);
|
|
}
|
|
exports.not = not;
|
|
/**
|
|
* Filters the set of matched elements to only those which have the given DOM
|
|
* element as a descendant or which have a descendant that matches the given
|
|
* selector. Equivalent to `.filter(':has(selector)')`.
|
|
*
|
|
* @category Traversing
|
|
* @example <caption>Selector</caption>
|
|
*
|
|
* ```js
|
|
* $('ul').has('.pear').attr('id');
|
|
* //=> fruits
|
|
* ```
|
|
*
|
|
* @example <caption>Element</caption>
|
|
*
|
|
* ```js
|
|
* $('ul').has($('.pear')[0]).attr('id');
|
|
* //=> fruits
|
|
* ```
|
|
*
|
|
* @param selectorOrHaystack - Element to look for.
|
|
* @returns The filtered collection.
|
|
* @see {@link https://api.jquery.com/has/}
|
|
*/
|
|
function has(selectorOrHaystack) {
|
|
var _this = this;
|
|
return filter.call(this, typeof selectorOrHaystack === 'string'
|
|
? // Using the `:has` selector here short-circuits searches.
|
|
":has(" + selectorOrHaystack + ")"
|
|
: function (_, el) { return _this._make(el).find(selectorOrHaystack).length > 0; });
|
|
}
|
|
exports.has = has;
|
|
/**
|
|
* Will select the first element of a cheerio object.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('#fruits').children().first().text();
|
|
* //=> Apple
|
|
* ```
|
|
*
|
|
* @returns The first element.
|
|
* @see {@link https://api.jquery.com/first/}
|
|
*/
|
|
function first() {
|
|
return this.length > 1 ? this._make(this[0]) : this;
|
|
}
|
|
exports.first = first;
|
|
/**
|
|
* Will select the last element of a cheerio object.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('#fruits').children().last().text();
|
|
* //=> Pear
|
|
* ```
|
|
*
|
|
* @returns The last element.
|
|
* @see {@link https://api.jquery.com/last/}
|
|
*/
|
|
function last() {
|
|
return this.length > 0 ? this._make(this[this.length - 1]) : this;
|
|
}
|
|
exports.last = last;
|
|
/**
|
|
* Reduce the set of matched elements to the one at the specified index. Use
|
|
* `.eq(-i)` to count backwards from the last selected element.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('li').eq(0).text();
|
|
* //=> Apple
|
|
*
|
|
* $('li').eq(-1).text();
|
|
* //=> Pear
|
|
* ```
|
|
*
|
|
* @param i - Index of the element to select.
|
|
* @returns The element at the `i`th position.
|
|
* @see {@link https://api.jquery.com/eq/}
|
|
*/
|
|
function eq(i) {
|
|
var _a;
|
|
i = +i;
|
|
// Use the first identity optimization if possible
|
|
if (i === 0 && this.length <= 1)
|
|
return this;
|
|
if (i < 0)
|
|
i = this.length + i;
|
|
return this._make((_a = this[i]) !== null && _a !== void 0 ? _a : []);
|
|
}
|
|
exports.eq = eq;
|
|
function get(i) {
|
|
if (i == null) {
|
|
return Array.prototype.slice.call(this);
|
|
}
|
|
return this[i < 0 ? this.length + i : i];
|
|
}
|
|
exports.get = get;
|
|
/**
|
|
* Search for a given element from among the matched elements.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.pear').index();
|
|
* //=> 2 $('.orange').index('li');
|
|
* //=> 1
|
|
* $('.apple').index($('#fruit, li'));
|
|
* //=> 1
|
|
* ```
|
|
*
|
|
* @param selectorOrNeedle - Element to look for.
|
|
* @returns The index of the element.
|
|
* @see {@link https://api.jquery.com/index/}
|
|
*/
|
|
function index(selectorOrNeedle) {
|
|
var $haystack;
|
|
var needle;
|
|
if (selectorOrNeedle == null) {
|
|
$haystack = this.parent().children();
|
|
needle = this[0];
|
|
}
|
|
else if (typeof selectorOrNeedle === 'string') {
|
|
$haystack = this._make(selectorOrNeedle);
|
|
needle = this[0];
|
|
}
|
|
else {
|
|
$haystack = this;
|
|
needle = utils_1.isCheerio(selectorOrNeedle)
|
|
? selectorOrNeedle[0]
|
|
: selectorOrNeedle;
|
|
}
|
|
return $haystack.get().indexOf(needle);
|
|
}
|
|
exports.index = index;
|
|
/**
|
|
* Gets the elements matching the specified range (0-based position).
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('li').slice(1).eq(0).text();
|
|
* //=> 'Orange'
|
|
*
|
|
* $('li').slice(1, 2).length;
|
|
* //=> 1
|
|
* ```
|
|
*
|
|
* @param start - An position at which the elements begin to be selected. If
|
|
* negative, it indicates an offset from the end of the set.
|
|
* @param end - An position at which the elements stop being selected. If
|
|
* negative, it indicates an offset from the end of the set. If omitted, the
|
|
* range continues until the end of the set.
|
|
* @returns The elements matching the specified range.
|
|
* @see {@link https://api.jquery.com/slice/}
|
|
*/
|
|
function slice(start, end) {
|
|
return this._make(Array.prototype.slice.call(this, start, end));
|
|
}
|
|
exports.slice = slice;
|
|
function traverseParents(self, elem, selector, limit) {
|
|
var elems = [];
|
|
while (elem && elems.length < limit && elem.type !== 'root') {
|
|
if (!selector || filter.call([elem], selector, self).length) {
|
|
elems.push(elem);
|
|
}
|
|
elem = elem.parent;
|
|
}
|
|
return elems;
|
|
}
|
|
/**
|
|
* End the most recent filtering operation in the current chain and return the
|
|
* set of matched elements to its previous state.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('li').eq(0).end().length;
|
|
* //=> 3
|
|
* ```
|
|
*
|
|
* @returns The previous state of the set of matched elements.
|
|
* @see {@link https://api.jquery.com/end/}
|
|
*/
|
|
function end() {
|
|
var _a;
|
|
return (_a = this.prevObject) !== null && _a !== void 0 ? _a : this._make([]);
|
|
}
|
|
exports.end = end;
|
|
/**
|
|
* Add elements to the set of matched elements.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('.apple').add('.orange').length;
|
|
* //=> 2
|
|
* ```
|
|
*
|
|
* @param other - Elements to add.
|
|
* @param context - Optionally the context of the new selection.
|
|
* @returns The combined set.
|
|
* @see {@link https://api.jquery.com/add/}
|
|
*/
|
|
function add(other, context) {
|
|
var selection = this._make(other, context);
|
|
var contents = uniqueSort(tslib_1.__spreadArray(tslib_1.__spreadArray([], this.get()), selection.get()));
|
|
return this._make(contents);
|
|
}
|
|
exports.add = add;
|
|
/**
|
|
* Add the previous set of elements on the stack to the current set, optionally
|
|
* filtered by a selector.
|
|
*
|
|
* @category Traversing
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('li').eq(0).addBack('.orange').length;
|
|
* //=> 2
|
|
* ```
|
|
*
|
|
* @param selector - Selector for the elements to add.
|
|
* @returns The combined set.
|
|
* @see {@link https://api.jquery.com/addBack/}
|
|
*/
|
|
function addBack(selector) {
|
|
return this.prevObject
|
|
? this.add(selector ? this.prevObject.filter(selector) : this.prevObject)
|
|
: this;
|
|
}
|
|
exports.addBack = addBack;
|
|
|
|
},{"../utils":20,"cheerio-select":5,"domhandler":38,"htmlparser2":58,"tslib":88}],12:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.Cheerio = void 0;
|
|
var tslib_1 = require("tslib");
|
|
var parse_1 = tslib_1.__importDefault(require("./parse"));
|
|
var options_1 = tslib_1.__importStar(require("./options"));
|
|
var utils_1 = require("./utils");
|
|
var Static = tslib_1.__importStar(require("./static"));
|
|
var Attributes = tslib_1.__importStar(require("./api/attributes"));
|
|
var Traversing = tslib_1.__importStar(require("./api/traversing"));
|
|
var Manipulation = tslib_1.__importStar(require("./api/manipulation"));
|
|
var Css = tslib_1.__importStar(require("./api/css"));
|
|
var Forms = tslib_1.__importStar(require("./api/forms"));
|
|
/*
|
|
* The API
|
|
*/
|
|
var api = [Attributes, Traversing, Manipulation, Css, Forms];
|
|
var Cheerio = /** @class */ (function () {
|
|
/**
|
|
* Instance of cheerio. Methods are specified in the modules. Usage of this
|
|
* constructor is not recommended. Please use $.load instead.
|
|
*
|
|
* @private
|
|
* @param selector - The new selection.
|
|
* @param context - Context of the selection.
|
|
* @param root - Sets the root node.
|
|
* @param options - Options for the instance.
|
|
*/
|
|
function Cheerio(selector, context, root, options) {
|
|
var _this = this;
|
|
if (!(this instanceof Cheerio)) {
|
|
return new Cheerio(selector, context, root, options);
|
|
}
|
|
this.length = 0;
|
|
this.options = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, options_1.default), this.options), options_1.flatten(options));
|
|
// $(), $(null), $(undefined), $(false)
|
|
if (!selector)
|
|
return this;
|
|
if (root) {
|
|
if (typeof root === 'string')
|
|
root = parse_1.default(root, this.options, false);
|
|
this._root = Cheerio.call(this, root);
|
|
}
|
|
// $($)
|
|
if (utils_1.isCheerio(selector))
|
|
return selector;
|
|
var elements = typeof selector === 'string' && utils_1.isHtml(selector)
|
|
? // $(<html>)
|
|
parse_1.default(selector, this.options, false).children
|
|
: isNode(selector)
|
|
? // $(dom)
|
|
[selector]
|
|
: Array.isArray(selector)
|
|
? // $([dom])
|
|
selector
|
|
: null;
|
|
if (elements) {
|
|
elements.forEach(function (elem, idx) {
|
|
_this[idx] = elem;
|
|
});
|
|
this.length = elements.length;
|
|
return this;
|
|
}
|
|
// We know that our selector is a string now.
|
|
var search = selector;
|
|
var searchContext = !context
|
|
? // If we don't have a context, maybe we have a root, from loading
|
|
this._root
|
|
: typeof context === 'string'
|
|
? utils_1.isHtml(context)
|
|
? // $('li', '<ul>...</ul>')
|
|
new Cheerio(parse_1.default(context, this.options, false))
|
|
: // $('li', 'ul')
|
|
((search = context + " " + search), this._root)
|
|
: utils_1.isCheerio(context)
|
|
? // $('li', $)
|
|
context
|
|
: // $('li', node), $('li', [nodes])
|
|
new Cheerio(context);
|
|
// If we still don't have a context, return
|
|
if (!searchContext)
|
|
return this;
|
|
/*
|
|
* #id, .class, tag
|
|
*/
|
|
// @ts-expect-error No good way to type this — we will always return `Cheerio<Element>` here.
|
|
return searchContext.find(search);
|
|
}
|
|
/**
|
|
* Make a cheerio object.
|
|
*
|
|
* @private
|
|
* @param dom - The contents of the new object.
|
|
* @param context - The context of the new object.
|
|
* @returns The new cheerio object.
|
|
*/
|
|
Cheerio.prototype._make = function (dom, context, root) {
|
|
if (root === void 0) { root = this._root; }
|
|
var cheerio = new this.constructor(dom, context, root, this.options);
|
|
cheerio.prevObject = this;
|
|
return cheerio;
|
|
};
|
|
/**
|
|
* Retrieve all the DOM elements contained in the jQuery set as an array.
|
|
*
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $('li').toArray();
|
|
* //=> [ {...}, {...}, {...} ]
|
|
* ```
|
|
*
|
|
* @returns The contained items.
|
|
*/
|
|
Cheerio.prototype.toArray = function () {
|
|
return this.get();
|
|
};
|
|
Cheerio.html = Static.html;
|
|
Cheerio.xml = Static.xml;
|
|
Cheerio.text = Static.text;
|
|
Cheerio.parseHTML = Static.parseHTML;
|
|
Cheerio.root = Static.root;
|
|
Cheerio.contains = Static.contains;
|
|
Cheerio.merge = Static.merge;
|
|
/** Mimic jQuery's prototype alias for plugin authors. */
|
|
Cheerio.fn = Cheerio.prototype;
|
|
return Cheerio;
|
|
}());
|
|
exports.Cheerio = Cheerio;
|
|
/** Set a signature of the object. */
|
|
Cheerio.prototype.cheerio = '[cheerio object]';
|
|
/*
|
|
* Make cheerio an array-like object
|
|
*/
|
|
Cheerio.prototype.splice = Array.prototype.splice;
|
|
// Support for (const element of $(...)) iteration:
|
|
Cheerio.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
|
|
// Plug in the API
|
|
api.forEach(function (mod) { return Object.assign(Cheerio.prototype, mod); });
|
|
function isNode(obj) {
|
|
return (!!obj.name ||
|
|
obj.type === 'root' ||
|
|
obj.type === 'text' ||
|
|
obj.type === 'comment');
|
|
}
|
|
// Make it possible to call Cheerio without using `new`.
|
|
exports.default = Cheerio;
|
|
|
|
},{"./api/attributes":7,"./api/css":8,"./api/forms":9,"./api/manipulation":10,"./api/traversing":11,"./options":14,"./parse":15,"./static":18,"./utils":20,"tslib":88}],13:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.load = void 0;
|
|
var tslib_1 = require("tslib");
|
|
var options_1 = tslib_1.__importStar(require("./options"));
|
|
var staticMethods = tslib_1.__importStar(require("./static"));
|
|
var cheerio_1 = require("./cheerio");
|
|
var parse_1 = tslib_1.__importDefault(require("./parse"));
|
|
/**
|
|
* Create a querying function, bound to a document created from the provided
|
|
* markup. Note that similar to web browser contexts, this operation may
|
|
* introduce `<html>`, `<head>`, and `<body>` elements; set `isDocument` to
|
|
* `false` to switch to fragment mode and disable this.
|
|
*
|
|
* See the README section titled "Loading" for additional usage information.
|
|
*
|
|
* @param content - Markup to be loaded.
|
|
* @param options - Options for the created instance.
|
|
* @param isDocument - Allows parser to be switched to fragment mode.
|
|
* @returns The loaded document.
|
|
*/
|
|
function load(content, options, isDocument) {
|
|
if (content == null) {
|
|
throw new Error('cheerio.load() expects a string');
|
|
}
|
|
options = tslib_1.__assign(tslib_1.__assign({}, options_1.default), options_1.flatten(options));
|
|
if (typeof isDocument === 'undefined')
|
|
isDocument = true;
|
|
var root = parse_1.default(content, options, isDocument);
|
|
var initialize = /** @class */ (function (_super) {
|
|
tslib_1.__extends(initialize, _super);
|
|
function initialize(selector, context, r, opts) {
|
|
if (r === void 0) { r = root; }
|
|
var _this = this;
|
|
// @ts-expect-error Using `this` before calling the constructor.
|
|
if (!(_this instanceof initialize)) {
|
|
return new initialize(selector, context, r, opts);
|
|
}
|
|
_this = _super.call(this, selector, context, r, tslib_1.__assign(tslib_1.__assign({}, options), opts)) || this;
|
|
return _this;
|
|
}
|
|
// Mimic jQuery's prototype alias for plugin authors.
|
|
initialize.fn = initialize.prototype;
|
|
return initialize;
|
|
}(cheerio_1.Cheerio));
|
|
/*
|
|
* Keep a reference to the top-level scope so we can chain methods that implicitly
|
|
* resolve selectors; e.g. $("<span>").(".bar"), which otherwise loses ._root
|
|
*/
|
|
initialize.prototype._originalRoot = root;
|
|
// Add in the static methods
|
|
Object.assign(initialize, staticMethods, { load: load });
|
|
// Add in the root
|
|
initialize._root = root;
|
|
// Store options
|
|
initialize._options = options;
|
|
return initialize;
|
|
}
|
|
exports.load = load;
|
|
|
|
},{"./cheerio":12,"./options":14,"./parse":15,"./static":18,"tslib":88}],14:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.flatten = void 0;
|
|
var tslib_1 = require("tslib");
|
|
var defaultOpts = {
|
|
xml: false,
|
|
decodeEntities: true,
|
|
};
|
|
/** Cheerio default options. */
|
|
exports.default = defaultOpts;
|
|
var xmlModeDefault = {
|
|
_useHtmlParser2: true,
|
|
xmlMode: true,
|
|
};
|
|
function flatten(options) {
|
|
return (options === null || options === void 0 ? void 0 : options.xml)
|
|
? typeof options.xml === 'boolean'
|
|
? xmlModeDefault
|
|
: tslib_1.__assign(tslib_1.__assign({}, xmlModeDefault), options.xml)
|
|
: options !== null && options !== void 0 ? options : undefined;
|
|
}
|
|
exports.flatten = flatten;
|
|
|
|
},{"tslib":88}],15:[function(require,module,exports){
|
|
(function (Buffer){(function (){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.update = void 0;
|
|
var htmlparser2_1 = require("htmlparser2");
|
|
var htmlparser2_2 = require("./parsers/htmlparser2");
|
|
var parse5_1 = require("./parsers/parse5");
|
|
var domhandler_1 = require("domhandler");
|
|
/*
|
|
* Parser
|
|
*/
|
|
function parse(content, options, isDocument) {
|
|
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(content)) {
|
|
content = content.toString();
|
|
}
|
|
if (typeof content === 'string') {
|
|
return options.xmlMode || options._useHtmlParser2
|
|
? htmlparser2_2.parse(content, options)
|
|
: parse5_1.parse(content, options, isDocument);
|
|
}
|
|
var doc = content;
|
|
if (!Array.isArray(doc) && domhandler_1.isDocument(doc)) {
|
|
// If `doc` is already a root, just return it
|
|
return doc;
|
|
}
|
|
// Add conent to new root element
|
|
var root = new domhandler_1.Document([]);
|
|
// Update the DOM using the root
|
|
update(doc, root);
|
|
return root;
|
|
}
|
|
exports.default = parse;
|
|
/**
|
|
* Update the dom structure, for one changed layer.
|
|
*
|
|
* @param newChilds - The new children.
|
|
* @param parent - The new parent.
|
|
* @returns The parent node.
|
|
*/
|
|
function update(newChilds, parent) {
|
|
// Normalize
|
|
var arr = Array.isArray(newChilds) ? newChilds : [newChilds];
|
|
// Update parent
|
|
if (parent) {
|
|
parent.children = arr;
|
|
}
|
|
else {
|
|
parent = null;
|
|
}
|
|
// Update neighbors
|
|
for (var i = 0; i < arr.length; i++) {
|
|
var node = arr[i];
|
|
// Cleanly remove existing nodes from their previous structures.
|
|
if (node.parent && node.parent.children !== arr) {
|
|
htmlparser2_1.DomUtils.removeElement(node);
|
|
}
|
|
if (parent) {
|
|
node.prev = arr[i - 1] || null;
|
|
node.next = arr[i + 1] || null;
|
|
}
|
|
else {
|
|
node.prev = node.next = null;
|
|
}
|
|
node.parent = parent;
|
|
}
|
|
return parent;
|
|
}
|
|
exports.update = update;
|
|
|
|
}).call(this)}).call(this,require("buffer").Buffer)
|
|
},{"./parsers/htmlparser2":16,"./parsers/parse5":17,"buffer":3,"domhandler":38,"htmlparser2":58}],16:[function(require,module,exports){
|
|
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.render = exports.parse = void 0;
|
|
var htmlparser2_1 = require("htmlparser2");
|
|
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return htmlparser2_1.parseDocument; } });
|
|
var dom_serializer_1 = require("dom-serializer");
|
|
Object.defineProperty(exports, "render", { enumerable: true, get: function () { return __importDefault(dom_serializer_1).default; } });
|
|
|
|
},{"dom-serializer":36,"htmlparser2":58}],17:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.render = exports.parse = void 0;
|
|
var tslib_1 = require("tslib");
|
|
var domhandler_1 = require("domhandler");
|
|
var parse5_1 = require("parse5");
|
|
var parse5_htmlparser2_tree_adapter_1 = tslib_1.__importDefault(require("parse5-htmlparser2-tree-adapter"));
|
|
function parse(content, options, isDocument) {
|
|
var opts = {
|
|
scriptingEnabled: typeof options.scriptingEnabled === 'boolean'
|
|
? options.scriptingEnabled
|
|
: true,
|
|
treeAdapter: parse5_htmlparser2_tree_adapter_1.default,
|
|
sourceCodeLocationInfo: options.sourceCodeLocationInfo,
|
|
};
|
|
var context = options.context;
|
|
// @ts-expect-error The tree adapter unfortunately doesn't return the exact types.
|
|
return isDocument
|
|
? parse5_1.parse(content, opts)
|
|
: // @ts-expect-error Same issue again.
|
|
parse5_1.parseFragment(context, content, opts);
|
|
}
|
|
exports.parse = parse;
|
|
function render(dom) {
|
|
var _a;
|
|
/*
|
|
* `dom-serializer` passes over the special "root" node and renders the
|
|
* node's children in its place. To mimic this behavior with `parse5`, an
|
|
* equivalent operation must be applied to the input array.
|
|
*/
|
|
var nodes = 'length' in dom ? dom : [dom];
|
|
for (var index = 0; index < nodes.length; index += 1) {
|
|
var node = nodes[index];
|
|
if (domhandler_1.isDocument(node)) {
|
|
(_a = Array.prototype.splice).call.apply(_a, tslib_1.__spreadArray([nodes, index, 1], node.children));
|
|
}
|
|
}
|
|
// @ts-expect-error Types don't align here either.
|
|
return parse5_1.serialize({ children: nodes }, { treeAdapter: parse5_htmlparser2_tree_adapter_1.default });
|
|
}
|
|
exports.render = render;
|
|
|
|
},{"domhandler":38,"parse5":77,"parse5-htmlparser2-tree-adapter":63,"tslib":88}],18:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.merge = exports.contains = exports.root = exports.parseHTML = exports.text = exports.xml = exports.html = void 0;
|
|
var tslib_1 = require("tslib");
|
|
var options_1 = tslib_1.__importStar(require("./options"));
|
|
var cheerio_select_1 = require("cheerio-select");
|
|
var htmlparser2_1 = require("htmlparser2");
|
|
var parse5_1 = require("./parsers/parse5");
|
|
var htmlparser2_2 = require("./parsers/htmlparser2");
|
|
/**
|
|
* Helper function to render a DOM.
|
|
*
|
|
* @param that - Cheerio instance to render.
|
|
* @param dom - The DOM to render. Defaults to `that`'s root.
|
|
* @param options - Options for rendering.
|
|
* @returns The rendered document.
|
|
*/
|
|
function render(that, dom, options) {
|
|
var _a, _b;
|
|
if (!dom) {
|
|
if ((_a = that === null || that === void 0 ? void 0 : that._root) === null || _a === void 0 ? void 0 : _a.children) {
|
|
dom = that._root.children;
|
|
}
|
|
else {
|
|
return '';
|
|
}
|
|
}
|
|
else if (typeof dom === 'string') {
|
|
dom = cheerio_select_1.select(dom, (_b = that === null || that === void 0 ? void 0 : that._root) !== null && _b !== void 0 ? _b : [], options);
|
|
}
|
|
return options.xmlMode || options._useHtmlParser2
|
|
? // FIXME: Pull in new version of dom-serializer to fix this.
|
|
htmlparser2_2.render(dom, options)
|
|
: parse5_1.render(dom);
|
|
}
|
|
/**
|
|
* Checks if a passed object is an options object.
|
|
*
|
|
* @param dom - Object to check if it is an options object.
|
|
* @returns Whether the object is an options object.
|
|
*/
|
|
function isOptions(dom) {
|
|
return (typeof dom === 'object' &&
|
|
dom != null &&
|
|
!('length' in dom) &&
|
|
!('type' in dom));
|
|
}
|
|
function html(dom, options) {
|
|
/*
|
|
* Be flexible about parameters, sometimes we call html(),
|
|
* with options as only parameter
|
|
* check dom argument for dom element specific properties
|
|
* assume there is no 'length' or 'type' properties in the options object
|
|
*/
|
|
if (!options && isOptions(dom)) {
|
|
options = dom;
|
|
dom = undefined;
|
|
}
|
|
/*
|
|
* Sometimes `$.html()` is used without preloading html,
|
|
* so fallback non-existing options to the default ones.
|
|
*/
|
|
options = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, options_1.default), (this ? this._options : {})), options_1.flatten(options !== null && options !== void 0 ? options : {}));
|
|
return render(this || undefined, dom, options);
|
|
}
|
|
exports.html = html;
|
|
/**
|
|
* Render the document as XML.
|
|
*
|
|
* @param dom - Element to render.
|
|
* @returns THe rendered document.
|
|
*/
|
|
function xml(dom) {
|
|
var options = tslib_1.__assign(tslib_1.__assign({}, this._options), { xmlMode: true });
|
|
return render(this, dom, options);
|
|
}
|
|
exports.xml = xml;
|
|
/**
|
|
* Render the document as text.
|
|
*
|
|
* @param elements - Elements to render.
|
|
* @returns The rendered document.
|
|
*/
|
|
function text(elements) {
|
|
var elems = elements ? elements : this ? this.root() : [];
|
|
var ret = '';
|
|
for (var i = 0; i < elems.length; i++) {
|
|
var elem = elems[i];
|
|
if (htmlparser2_1.DomUtils.isText(elem))
|
|
ret += elem.data;
|
|
else if (htmlparser2_1.DomUtils.hasChildren(elem) &&
|
|
elem.type !== htmlparser2_1.ElementType.Comment &&
|
|
elem.type !== htmlparser2_1.ElementType.Script &&
|
|
elem.type !== htmlparser2_1.ElementType.Style) {
|
|
ret += text(elem.children);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
exports.text = text;
|
|
function parseHTML(data, context, keepScripts) {
|
|
if (keepScripts === void 0) { keepScripts = typeof context === 'boolean' ? context : false; }
|
|
if (!data || typeof data !== 'string') {
|
|
return null;
|
|
}
|
|
if (typeof context === 'boolean') {
|
|
keepScripts = context;
|
|
}
|
|
var parsed = this.load(data, options_1.default, false);
|
|
if (!keepScripts) {
|
|
parsed('script').remove();
|
|
}
|
|
/*
|
|
* The `children` array is used by Cheerio internally to group elements that
|
|
* share the same parents. When nodes created through `parseHTML` are
|
|
* inserted into previously-existing DOM structures, they will be removed
|
|
* from the `children` array. The results of `parseHTML` should remain
|
|
* constant across these operations, so a shallow copy should be returned.
|
|
*/
|
|
return parsed.root()[0].children.slice();
|
|
}
|
|
exports.parseHTML = parseHTML;
|
|
/**
|
|
* Sometimes you need to work with the top-level root element. To query it, you
|
|
* can use `$.root()`.
|
|
*
|
|
* @example
|
|
*
|
|
* ```js
|
|
* $.root().append('<ul id="vegetables"></ul>').html();
|
|
* //=> <ul id="fruits">...</ul><ul id="vegetables"></ul>
|
|
* ```
|
|
*
|
|
* @returns Cheerio instance wrapping the root node.
|
|
* @alias Cheerio.root
|
|
*/
|
|
function root() {
|
|
var fn = this;
|
|
return fn(this._root);
|
|
}
|
|
exports.root = root;
|
|
/**
|
|
* Checks to see if the `contained` DOM element is a descendant of the
|
|
* `container` DOM element.
|
|
*
|
|
* @param container - Potential parent node.
|
|
* @param contained - Potential child node.
|
|
* @returns Indicates if the nodes contain one another.
|
|
* @alias Cheerio.contains
|
|
* @see {@link https://api.jquery.com/jQuery.contains/}
|
|
*/
|
|
function contains(container, contained) {
|
|
// According to the jQuery API, an element does not "contain" itself
|
|
if (contained === container) {
|
|
return false;
|
|
}
|
|
/*
|
|
* Step up the descendants, stopping when the root element is reached
|
|
* (signaled by `.parent` returning a reference to the same object)
|
|
*/
|
|
var next = contained;
|
|
while (next && next !== next.parent) {
|
|
next = next.parent;
|
|
if (next === container) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
exports.contains = contains;
|
|
/**
|
|
* $.merge().
|
|
*
|
|
* @param arr1 - First array.
|
|
* @param arr2 - Second array.
|
|
* @returns `arr1`, with elements of `arr2` inserted.
|
|
* @alias Cheerio.merge
|
|
* @see {@link https://api.jquery.com/jQuery.merge/}
|
|
*/
|
|
function merge(arr1, arr2) {
|
|
if (!isArrayLike(arr1) || !isArrayLike(arr2)) {
|
|
return;
|
|
}
|
|
var newLength = arr1.length;
|
|
var len = +arr2.length;
|
|
for (var i = 0; i < len; i++) {
|
|
arr1[newLength++] = arr2[i];
|
|
}
|
|
arr1.length = newLength;
|
|
return arr1;
|
|
}
|
|
exports.merge = merge;
|
|
/**
|
|
* @param item - Item to check.
|
|
* @returns Indicates if the item is array-like.
|
|
*/
|
|
function isArrayLike(item) {
|
|
if (Array.isArray(item)) {
|
|
return true;
|
|
}
|
|
if (typeof item !== 'object' ||
|
|
!Object.prototype.hasOwnProperty.call(item, 'length') ||
|
|
typeof item.length !== 'number' ||
|
|
item.length < 0) {
|
|
return false;
|
|
}
|
|
for (var i = 0; i < item.length; i++) {
|
|
if (!(i in item)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
},{"./options":14,"./parsers/htmlparser2":16,"./parsers/parse5":17,"cheerio-select":5,"htmlparser2":58,"tslib":88}],19:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
},{}],20:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.isHtml = exports.cloneDom = exports.domEach = exports.cssCase = exports.camelCase = exports.isCheerio = exports.isTag = void 0;
|
|
var htmlparser2_1 = require("htmlparser2");
|
|
var domhandler_1 = require("domhandler");
|
|
/**
|
|
* Check if the DOM element is a tag.
|
|
*
|
|
* `isTag(type)` includes `<script>` and `<style>` tags.
|
|
*
|
|
* @private
|
|
* @category Utils
|
|
* @param type - DOM node to check.
|
|
* @returns Whether the node is a tag.
|
|
*/
|
|
exports.isTag = htmlparser2_1.DomUtils.isTag;
|
|
/**
|
|
* Checks if an object is a Cheerio instance.
|
|
*
|
|
* @category Utils
|
|
* @param maybeCheerio - The object to check.
|
|
* @returns Whether the object is a Cheerio instance.
|
|
*/
|
|
function isCheerio(maybeCheerio) {
|
|
return maybeCheerio.cheerio != null;
|
|
}
|
|
exports.isCheerio = isCheerio;
|
|
/**
|
|
* Convert a string to camel case notation.
|
|
*
|
|
* @private
|
|
* @category Utils
|
|
* @param str - String to be converted.
|
|
* @returns String in camel case notation.
|
|
*/
|
|
function camelCase(str) {
|
|
return str.replace(/[_.-](\w|$)/g, function (_, x) { return x.toUpperCase(); });
|
|
}
|
|
exports.camelCase = camelCase;
|
|
/**
|
|
* Convert a string from camel case to "CSS case", where word boundaries are
|
|
* described by hyphens ("-") and all characters are lower-case.
|
|
*
|
|
* @private
|
|
* @category Utils
|
|
* @param str - String to be converted.
|
|
* @returns String in "CSS case".
|
|
*/
|
|
function cssCase(str) {
|
|
return str.replace(/[A-Z]/g, '-$&').toLowerCase();
|
|
}
|
|
exports.cssCase = cssCase;
|
|
/**
|
|
* Iterate over each DOM element without creating intermediary Cheerio instances.
|
|
*
|
|
* This is indented for use internally to avoid otherwise unnecessary memory
|
|
* pressure introduced by _make.
|
|
*
|
|
* @category Utils
|
|
* @param array - Array to iterate over.
|
|
* @param fn - Function to call.
|
|
* @returns The original instance.
|
|
*/
|
|
function domEach(array, fn) {
|
|
var len = array.length;
|
|
for (var i = 0; i < len && fn(i, array[i]) !== false; i++)
|
|
;
|
|
return array;
|
|
}
|
|
exports.domEach = domEach;
|
|
/**
|
|
* Create a deep copy of the given DOM structure. Sets the parents of the copies
|
|
* of the passed nodes to `null`.
|
|
*
|
|
* @private
|
|
* @category Utils
|
|
* @param dom - The htmlparser2-compliant DOM structure.
|
|
* @returns - The cloned DOM.
|
|
*/
|
|
function cloneDom(dom) {
|
|
var clone = 'length' in dom
|
|
? Array.prototype.map.call(dom, function (el) { return domhandler_1.cloneNode(el, true); })
|
|
: [domhandler_1.cloneNode(dom, true)];
|
|
// Add a root node around the cloned nodes
|
|
var root = new domhandler_1.Document(clone);
|
|
clone.forEach(function (node) {
|
|
node.parent = root;
|
|
});
|
|
return clone;
|
|
}
|
|
exports.cloneDom = cloneDom;
|
|
/**
|
|
* A simple way to check for HTML strings. Tests for a `<` within a string,
|
|
* immediate followed by a letter and eventually followed by a `>`.
|
|
*
|
|
* @private
|
|
*/
|
|
var quickExpr = /<[a-zA-Z][^]*>/;
|
|
/**
|
|
* Check if string is HTML.
|
|
*
|
|
* @private
|
|
* @category Utils
|
|
* @param str - String to check.
|
|
* @returns Indicates if `str` is HTML.
|
|
*/
|
|
function isHtml(str) {
|
|
// Run the regex
|
|
return quickExpr.test(str);
|
|
}
|
|
exports.isHtml = isHtml;
|
|
|
|
},{"domhandler":38,"htmlparser2":58}],21:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.attributeRules = void 0;
|
|
var boolbase_1 = require("boolbase");
|
|
/**
|
|
* All reserved characters in a regex, used for escaping.
|
|
*
|
|
* Taken from XRegExp, (c) 2007-2020 Steven Levithan under the MIT license
|
|
* https://github.com/slevithan/xregexp/blob/95eeebeb8fac8754d54eafe2b4743661ac1cf028/src/xregexp.js#L794
|
|
*/
|
|
var reChars = /[-[\]{}()*+?.,\\^$|#\s]/g;
|
|
function escapeRegex(value) {
|
|
return value.replace(reChars, "\\$&");
|
|
}
|
|
/**
|
|
* Attribute selectors
|
|
*/
|
|
exports.attributeRules = {
|
|
equals: function (next, data, _a) {
|
|
var adapter = _a.adapter;
|
|
var name = data.name;
|
|
var value = data.value;
|
|
if (data.ignoreCase) {
|
|
value = value.toLowerCase();
|
|
return function (elem) {
|
|
var attr = adapter.getAttributeValue(elem, name);
|
|
return (attr != null &&
|
|
attr.length === value.length &&
|
|
attr.toLowerCase() === value &&
|
|
next(elem));
|
|
};
|
|
}
|
|
return function (elem) {
|
|
return adapter.getAttributeValue(elem, name) === value && next(elem);
|
|
};
|
|
},
|
|
hyphen: function (next, data, _a) {
|
|
var adapter = _a.adapter;
|
|
var name = data.name;
|
|
var value = data.value;
|
|
var len = value.length;
|
|
if (data.ignoreCase) {
|
|
value = value.toLowerCase();
|
|
return function hyphenIC(elem) {
|
|
var attr = adapter.getAttributeValue(elem, name);
|
|
return (attr != null &&
|
|
(attr.length === len || attr.charAt(len) === "-") &&
|
|
attr.substr(0, len).toLowerCase() === value &&
|
|
next(elem));
|
|
};
|
|
}
|
|
return function hyphen(elem) {
|
|
var attr = adapter.getAttributeValue(elem, name);
|
|
return (attr != null &&
|
|
(attr.length === len || attr.charAt(len) === "-") &&
|
|
attr.substr(0, len) === value &&
|
|
next(elem));
|
|
};
|
|
},
|
|
element: function (next, _a, _b) {
|
|
var name = _a.name, value = _a.value, ignoreCase = _a.ignoreCase;
|
|
var adapter = _b.adapter;
|
|
if (/\s/.test(value)) {
|
|
return boolbase_1.falseFunc;
|
|
}
|
|
var regex = new RegExp("(?:^|\\s)" + escapeRegex(value) + "(?:$|\\s)", ignoreCase ? "i" : "");
|
|
return function element(elem) {
|
|
var attr = adapter.getAttributeValue(elem, name);
|
|
return (attr != null &&
|
|
attr.length >= value.length &&
|
|
regex.test(attr) &&
|
|
next(elem));
|
|
};
|
|
},
|
|
exists: function (next, _a, _b) {
|
|
var name = _a.name;
|
|
var adapter = _b.adapter;
|
|
return function (elem) { return adapter.hasAttrib(elem, name) && next(elem); };
|
|
},
|
|
start: function (next, data, _a) {
|
|
var adapter = _a.adapter;
|
|
var name = data.name;
|
|
var value = data.value;
|
|
var len = value.length;
|
|
if (len === 0) {
|
|
return boolbase_1.falseFunc;
|
|
}
|
|
if (data.ignoreCase) {
|
|
value = value.toLowerCase();
|
|
return function (elem) {
|
|
var attr = adapter.getAttributeValue(elem, name);
|
|
return (attr != null &&
|
|
attr.length >= len &&
|
|
attr.substr(0, len).toLowerCase() === value &&
|
|
next(elem));
|
|
};
|
|
}
|
|
return function (elem) {
|
|
var _a;
|
|
return !!((_a = adapter.getAttributeValue(elem, name)) === null || _a === void 0 ? void 0 : _a.startsWith(value)) &&
|
|
next(elem);
|
|
};
|
|
},
|
|
end: function (next, data, _a) {
|
|
var adapter = _a.adapter;
|
|
var name = data.name;
|
|
var value = data.value;
|
|
var len = -value.length;
|
|
if (len === 0) {
|
|
return boolbase_1.falseFunc;
|
|
}
|
|
if (data.ignoreCase) {
|
|
value = value.toLowerCase();
|
|
return function (elem) {
|
|
var _a;
|
|
return ((_a = adapter
|
|
.getAttributeValue(elem, name)) === null || _a === void 0 ? void 0 : _a.substr(len).toLowerCase()) === value && next(elem);
|
|
};
|
|
}
|
|
return function (elem) {
|
|
var _a;
|
|
return !!((_a = adapter.getAttributeValue(elem, name)) === null || _a === void 0 ? void 0 : _a.endsWith(value)) &&
|
|
next(elem);
|
|
};
|
|
},
|
|
any: function (next, data, _a) {
|
|
var adapter = _a.adapter;
|
|
var name = data.name, value = data.value;
|
|
if (value === "") {
|
|
return boolbase_1.falseFunc;
|
|
}
|
|
if (data.ignoreCase) {
|
|
var regex_1 = new RegExp(escapeRegex(value), "i");
|
|
return function anyIC(elem) {
|
|
var attr = adapter.getAttributeValue(elem, name);
|
|
return (attr != null &&
|
|
attr.length >= value.length &&
|
|
regex_1.test(attr) &&
|
|
next(elem));
|
|
};
|
|
}
|
|
return function (elem) {
|
|
var _a;
|
|
return !!((_a = adapter.getAttributeValue(elem, name)) === null || _a === void 0 ? void 0 : _a.includes(value)) &&
|
|
next(elem);
|
|
};
|
|
},
|
|
not: function (next, data, _a) {
|
|
var adapter = _a.adapter;
|
|
var name = data.name;
|
|
var value = data.value;
|
|
if (value === "") {
|
|
return function (elem) {
|
|
return !!adapter.getAttributeValue(elem, name) && next(elem);
|
|
};
|
|
}
|
|
else if (data.ignoreCase) {
|
|
value = value.toLowerCase();
|
|
return function (elem) {
|
|
var attr = adapter.getAttributeValue(elem, name);
|
|
return ((attr == null ||
|
|
attr.length !== value.length ||
|
|
attr.toLowerCase() !== value) &&
|
|
next(elem));
|
|
};
|
|
}
|
|
return function (elem) {
|
|
return adapter.getAttributeValue(elem, name) !== value && next(elem);
|
|
};
|
|
},
|
|
};
|
|
|
|
},{"boolbase":2}],22:[function(require,module,exports){
|
|
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.compileToken = exports.compileUnsafe = exports.compile = void 0;
|
|
var css_what_1 = require("css-what");
|
|
var boolbase_1 = require("boolbase");
|
|
var sort_1 = __importDefault(require("./sort"));
|
|
var procedure_1 = require("./procedure");
|
|
var general_1 = require("./general");
|
|
var subselects_1 = require("./pseudo-selectors/subselects");
|
|
/**
|
|
* Compiles a selector to an executable function.
|
|
*
|
|
* @param selector Selector to compile.
|
|
* @param options Compilation options.
|
|
* @param context Optional context for the selector.
|
|
*/
|
|
function compile(selector, options, context) {
|
|
var next = compileUnsafe(selector, options, context);
|
|
return subselects_1.ensureIsTag(next, options.adapter);
|
|
}
|
|
exports.compile = compile;
|
|
function compileUnsafe(selector, options, context) {
|
|
var token = typeof selector === "string" ? css_what_1.parse(selector, options) : selector;
|
|
return compileToken(token, options, context);
|
|
}
|
|
exports.compileUnsafe = compileUnsafe;
|
|
function includesScopePseudo(t) {
|
|
return (t.type === "pseudo" &&
|
|
(t.name === "scope" ||
|
|
(Array.isArray(t.data) &&
|
|
t.data.some(function (data) { return data.some(includesScopePseudo); }))));
|
|
}
|
|
var DESCENDANT_TOKEN = { type: "descendant" };
|
|
var FLEXIBLE_DESCENDANT_TOKEN = {
|
|
type: "_flexibleDescendant",
|
|
};
|
|
var SCOPE_TOKEN = { type: "pseudo", name: "scope", data: null };
|
|
/*
|
|
* CSS 4 Spec (Draft): 3.3.1. Absolutizing a Scope-relative Selector
|
|
* http://www.w3.org/TR/selectors4/#absolutizing
|
|
*/
|
|
function absolutize(token, _a, context) {
|
|
var adapter = _a.adapter;
|
|
// TODO Use better check if the context is a document
|
|
var hasContext = !!(context === null || context === void 0 ? void 0 : context.every(function (e) {
|
|
var parent = adapter.isTag(e) && adapter.getParent(e);
|
|
return e === subselects_1.PLACEHOLDER_ELEMENT || (parent && adapter.isTag(parent));
|
|
}));
|
|
for (var _i = 0, token_1 = token; _i < token_1.length; _i++) {
|
|
var t = token_1[_i];
|
|
if (t.length > 0 && procedure_1.isTraversal(t[0]) && t[0].type !== "descendant") {
|
|
// Don't continue in else branch
|
|
}
|
|
else if (hasContext && !t.some(includesScopePseudo)) {
|
|
t.unshift(DESCENDANT_TOKEN);
|
|
}
|
|
else {
|
|
continue;
|
|
}
|
|
t.unshift(SCOPE_TOKEN);
|
|
}
|
|
}
|
|
function compileToken(token, options, context) {
|
|
var _a;
|
|
token = token.filter(function (t) { return t.length > 0; });
|
|
token.forEach(sort_1.default);
|
|
context = (_a = options.context) !== null && _a !== void 0 ? _a : context;
|
|
var isArrayContext = Array.isArray(context);
|
|
var finalContext = context && (Array.isArray(context) ? context : [context]);
|
|
absolutize(token, options, finalContext);
|
|
var shouldTestNextSiblings = false;
|
|
var query = token
|
|
.map(function (rules) {
|
|
if (rules.length >= 2) {
|
|
var first = rules[0], second = rules[1];
|
|
if (first.type !== "pseudo" || first.name !== "scope") {
|
|
// Ignore
|
|
}
|
|
else if (isArrayContext && second.type === "descendant") {
|
|
rules[1] = FLEXIBLE_DESCENDANT_TOKEN;
|
|
}
|
|
else if (second.type === "adjacent" ||
|
|
second.type === "sibling") {
|
|
shouldTestNextSiblings = true;
|
|
}
|
|
}
|
|
return compileRules(rules, options, finalContext);
|
|
})
|
|
.reduce(reduceRules, boolbase_1.falseFunc);
|
|
query.shouldTestNextSiblings = shouldTestNextSiblings;
|
|
return query;
|
|
}
|
|
exports.compileToken = compileToken;
|
|
function compileRules(rules, options, context) {
|
|
var _a;
|
|
return rules.reduce(function (previous, rule) {
|
|
return previous === boolbase_1.falseFunc
|
|
? boolbase_1.falseFunc
|
|
: general_1.compileGeneralSelector(previous, rule, options, context, compileToken);
|
|
}, (_a = options.rootFunc) !== null && _a !== void 0 ? _a : boolbase_1.trueFunc);
|
|
}
|
|
function reduceRules(a, b) {
|
|
if (b === boolbase_1.falseFunc || a === boolbase_1.trueFunc) {
|
|
return a;
|
|
}
|
|
if (a === boolbase_1.falseFunc || b === boolbase_1.trueFunc) {
|
|
return b;
|
|
}
|
|
return function combine(elem) {
|
|
return a(elem) || b(elem);
|
|
};
|
|
}
|
|
|
|
},{"./general":23,"./procedure":25,"./pseudo-selectors/subselects":30,"./sort":31,"boolbase":2,"css-what":32}],23:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.compileGeneralSelector = void 0;
|
|
var attributes_1 = require("./attributes");
|
|
var pseudo_selectors_1 = require("./pseudo-selectors");
|
|
/*
|
|
* All available rules
|
|
*/
|
|
function compileGeneralSelector(next, selector, options, context, compileToken) {
|
|
var adapter = options.adapter, equals = options.equals;
|
|
switch (selector.type) {
|
|
case "pseudo-element":
|
|
throw new Error("Pseudo-elements are not supported by css-select");
|
|
case "attribute":
|
|
return attributes_1.attributeRules[selector.action](next, selector, options);
|
|
case "pseudo":
|
|
return pseudo_selectors_1.compilePseudoSelector(next, selector, options, context, compileToken);
|
|
// Tags
|
|
case "tag":
|
|
return function tag(elem) {
|
|
return adapter.getName(elem) === selector.name && next(elem);
|
|
};
|
|
// Traversal
|
|
case "descendant":
|
|
if (options.cacheResults === false ||
|
|
typeof WeakSet === "undefined") {
|
|
return function descendant(elem) {
|
|
var current = elem;
|
|
while ((current = adapter.getParent(current))) {
|
|
if (adapter.isTag(current) && next(current)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
}
|
|
// @ts-expect-error `ElementNode` is not extending object
|
|
// eslint-disable-next-line no-case-declarations
|
|
var isFalseCache_1 = new WeakSet();
|
|
return function cachedDescendant(elem) {
|
|
var current = elem;
|
|
while ((current = adapter.getParent(current))) {
|
|
if (!isFalseCache_1.has(current)) {
|
|
if (adapter.isTag(current) && next(current)) {
|
|
return true;
|
|
}
|
|
isFalseCache_1.add(current);
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
case "_flexibleDescendant":
|
|
// Include element itself, only used while querying an array
|
|
return function flexibleDescendant(elem) {
|
|
var current = elem;
|
|
do {
|
|
if (adapter.isTag(current) && next(current))
|
|
return true;
|
|
} while ((current = adapter.getParent(current)));
|
|
return false;
|
|
};
|
|
case "parent":
|
|
return function parent(elem) {
|
|
return adapter
|
|
.getChildren(elem)
|
|
.some(function (elem) { return adapter.isTag(elem) && next(elem); });
|
|
};
|
|
case "child":
|
|
return function child(elem) {
|
|
var parent = adapter.getParent(elem);
|
|
return parent != null && adapter.isTag(parent) && next(parent);
|
|
};
|
|
case "sibling":
|
|
return function sibling(elem) {
|
|
var siblings = adapter.getSiblings(elem);
|
|
for (var i = 0; i < siblings.length; i++) {
|
|
var currentSibling = siblings[i];
|
|
if (equals(elem, currentSibling))
|
|
break;
|
|
if (adapter.isTag(currentSibling) && next(currentSibling)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
case "adjacent":
|
|
return function adjacent(elem) {
|
|
var siblings = adapter.getSiblings(elem);
|
|
var lastElement;
|
|
for (var i = 0; i < siblings.length; i++) {
|
|
var currentSibling = siblings[i];
|
|
if (equals(elem, currentSibling))
|
|
break;
|
|
if (adapter.isTag(currentSibling)) {
|
|
lastElement = currentSibling;
|
|
}
|
|
}
|
|
return !!lastElement && next(lastElement);
|
|
};
|
|
case "universal":
|
|
return next;
|
|
}
|
|
}
|
|
exports.compileGeneralSelector = compileGeneralSelector;
|
|
|
|
},{"./attributes":21,"./pseudo-selectors":28}],24:[function(require,module,exports){
|
|
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.aliases = exports.pseudos = exports.filters = exports.is = exports.selectOne = exports.selectAll = exports.prepareContext = exports._compileToken = exports._compileUnsafe = exports.compile = void 0;
|
|
var DomUtils = __importStar(require("domutils"));
|
|
var boolbase_1 = require("boolbase");
|
|
var compile_1 = require("./compile");
|
|
var subselects_1 = require("./pseudo-selectors/subselects");
|
|
var defaultEquals = function (a, b) { return a === b; };
|
|
var defaultOptions = {
|
|
adapter: DomUtils,
|
|
equals: defaultEquals,
|
|
};
|
|
function convertOptionFormats(options) {
|
|
var _a, _b, _c, _d;
|
|
/*
|
|
* We force one format of options to the other one.
|
|
*/
|
|
// @ts-expect-error Default options may have incompatible `Node` / `ElementNode`.
|
|
var opts = options !== null && options !== void 0 ? options : defaultOptions;
|
|
// @ts-expect-error Same as above.
|
|
(_a = opts.adapter) !== null && _a !== void 0 ? _a : (opts.adapter = DomUtils);
|
|
// @ts-expect-error `equals` does not exist on `Options`
|
|
(_b = opts.equals) !== null && _b !== void 0 ? _b : (opts.equals = (_d = (_c = opts.adapter) === null || _c === void 0 ? void 0 : _c.equals) !== null && _d !== void 0 ? _d : defaultEquals);
|
|
return opts;
|
|
}
|
|
function wrapCompile(func) {
|
|
return function addAdapter(selector, options, context) {
|
|
var opts = convertOptionFormats(options);
|
|
return func(selector, opts, context);
|
|
};
|
|
}
|
|
/**
|
|
* Compiles the query, returns a function.
|
|
*/
|
|
exports.compile = wrapCompile(compile_1.compile);
|
|
exports._compileUnsafe = wrapCompile(compile_1.compileUnsafe);
|
|
exports._compileToken = wrapCompile(compile_1.compileToken);
|
|
function getSelectorFunc(searchFunc) {
|
|
return function select(query, elements, options) {
|
|
var opts = convertOptionFormats(options);
|
|
if (typeof query !== "function") {
|
|
query = compile_1.compileUnsafe(query, opts, elements);
|
|
}
|
|
var filteredElements = prepareContext(elements, opts.adapter, query.shouldTestNextSiblings);
|
|
return searchFunc(query, filteredElements, opts);
|
|
};
|
|
}
|
|
function prepareContext(elems, adapter, shouldTestNextSiblings) {
|
|
if (shouldTestNextSiblings === void 0) { shouldTestNextSiblings = false; }
|
|
/*
|
|
* Add siblings if the query requires them.
|
|
* See https://github.com/fb55/css-select/pull/43#issuecomment-225414692
|
|
*/
|
|
if (shouldTestNextSiblings) {
|
|
elems = appendNextSiblings(elems, adapter);
|
|
}
|
|
return Array.isArray(elems)
|
|
? adapter.removeSubsets(elems)
|
|
: adapter.getChildren(elems);
|
|
}
|
|
exports.prepareContext = prepareContext;
|
|
function appendNextSiblings(elem, adapter) {
|
|
// Order matters because jQuery seems to check the children before the siblings
|
|
var elems = Array.isArray(elem) ? elem.slice(0) : [elem];
|
|
for (var i = 0; i < elems.length; i++) {
|
|
var nextSiblings = subselects_1.getNextSiblings(elems[i], adapter);
|
|
elems.push.apply(elems, nextSiblings);
|
|
}
|
|
return elems;
|
|
}
|
|
/**
|
|
* @template Node The generic Node type for the DOM adapter being used.
|
|
* @template ElementNode The Node type for elements for the DOM adapter being used.
|
|
* @param elems Elements to query. If it is an element, its children will be queried..
|
|
* @param query can be either a CSS selector string or a compiled query function.
|
|
* @param [options] options for querying the document.
|
|
* @see compile for supported selector queries.
|
|
* @returns All matching elements.
|
|
*
|
|
*/
|
|
exports.selectAll = getSelectorFunc(function (query, elems, options) {
|
|
return query === boolbase_1.falseFunc || !elems || elems.length === 0
|
|
? []
|
|
: options.adapter.findAll(query, elems);
|
|
});
|
|
/**
|
|
* @template Node The generic Node type for the DOM adapter being used.
|
|
* @template ElementNode The Node type for elements for the DOM adapter being used.
|
|
* @param elems Elements to query. If it is an element, its children will be queried..
|
|
* @param query can be either a CSS selector string or a compiled query function.
|
|
* @param [options] options for querying the document.
|
|
* @see compile for supported selector queries.
|
|
* @returns the first match, or null if there was no match.
|
|
*/
|
|
exports.selectOne = getSelectorFunc(function (query, elems, options) {
|
|
return query === boolbase_1.falseFunc || !elems || elems.length === 0
|
|
? null
|
|
: options.adapter.findOne(query, elems);
|
|
});
|
|
/**
|
|
* Tests whether or not an element is matched by query.
|
|
*
|
|
* @template Node The generic Node type for the DOM adapter being used.
|
|
* @template ElementNode The Node type for elements for the DOM adapter being used.
|
|
* @param elem The element to test if it matches the query.
|
|
* @param query can be either a CSS selector string or a compiled query function.
|
|
* @param [options] options for querying the document.
|
|
* @see compile for supported selector queries.
|
|
* @returns
|
|
*/
|
|
function is(elem, query, options) {
|
|
var opts = convertOptionFormats(options);
|
|
return (typeof query === "function" ? query : compile_1.compile(query, opts))(elem);
|
|
}
|
|
exports.is = is;
|
|
/**
|
|
* Alias for selectAll(query, elems, options).
|
|
* @see [compile] for supported selector queries.
|
|
*/
|
|
exports.default = exports.selectAll;
|
|
// Export filters, pseudos and aliases to allow users to supply their own.
|
|
var pseudo_selectors_1 = require("./pseudo-selectors");
|
|
Object.defineProperty(exports, "filters", { enumerable: true, get: function () { return pseudo_selectors_1.filters; } });
|
|
Object.defineProperty(exports, "pseudos", { enumerable: true, get: function () { return pseudo_selectors_1.pseudos; } });
|
|
Object.defineProperty(exports, "aliases", { enumerable: true, get: function () { return pseudo_selectors_1.aliases; } });
|
|
|
|
},{"./compile":22,"./pseudo-selectors":28,"./pseudo-selectors/subselects":30,"boolbase":2,"domutils":41}],25:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.isTraversal = exports.procedure = void 0;
|
|
exports.procedure = {
|
|
universal: 50,
|
|
tag: 30,
|
|
attribute: 1,
|
|
pseudo: 0,
|
|
"pseudo-element": 0,
|
|
descendant: -1,
|
|
child: -1,
|
|
parent: -1,
|
|
sibling: -1,
|
|
adjacent: -1,
|
|
_flexibleDescendant: -1,
|
|
};
|
|
function isTraversal(t) {
|
|
return exports.procedure[t.type] < 0;
|
|
}
|
|
exports.isTraversal = isTraversal;
|
|
|
|
},{}],26:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.aliases = void 0;
|
|
/**
|
|
* Aliases are pseudos that are expressed as selectors.
|
|
*/
|
|
exports.aliases = {
|
|
// Links
|
|
"any-link": ":is(a, area, link)[href]",
|
|
link: ":any-link:not(:visited)",
|
|
// Forms
|
|
// https://html.spec.whatwg.org/multipage/scripting.html#disabled-elements
|
|
disabled: ":is(\n :is(button, input, select, textarea, optgroup, option)[disabled],\n optgroup[disabled] > option,\n fieldset[disabled]:not(fieldset[disabled] legend:first-of-type *)\n )",
|
|
enabled: ":not(:disabled)",
|
|
checked: ":is(:is(input[type=radio], input[type=checkbox])[checked], option:selected)",
|
|
required: ":is(input, select, textarea)[required]",
|
|
optional: ":is(input, select, textarea):not([required])",
|
|
// JQuery extensions
|
|
// https://html.spec.whatwg.org/multipage/form-elements.html#concept-option-selectedness
|
|
selected: "option:is([selected], select:not([multiple]):not(:has(> option[selected])) > :first-of-type)",
|
|
checkbox: "[type=checkbox]",
|
|
file: "[type=file]",
|
|
password: "[type=password]",
|
|
radio: "[type=radio]",
|
|
reset: "[type=reset]",
|
|
image: "[type=image]",
|
|
submit: "[type=submit]",
|
|
parent: ":not(:empty)",
|
|
header: ":is(h1, h2, h3, h4, h5, h6)",
|
|
button: ":is(button, input[type=button])",
|
|
input: ":is(input, textarea, select, button)",
|
|
text: "input:is(:not([type!='']), [type=text])",
|
|
};
|
|
|
|
},{}],27:[function(require,module,exports){
|
|
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.filters = void 0;
|
|
var nth_check_1 = __importDefault(require("nth-check"));
|
|
var boolbase_1 = require("boolbase");
|
|
function getChildFunc(next, adapter) {
|
|
return function (elem) {
|
|
var parent = adapter.getParent(elem);
|
|
return parent != null && adapter.isTag(parent) && next(elem);
|
|
};
|
|
}
|
|
exports.filters = {
|
|
contains: function (next, text, _a) {
|
|
var adapter = _a.adapter;
|
|
return function contains(elem) {
|
|
return next(elem) && adapter.getText(elem).includes(text);
|
|
};
|
|
},
|
|
icontains: function (next, text, _a) {
|
|
var adapter = _a.adapter;
|
|
var itext = text.toLowerCase();
|
|
return function icontains(elem) {
|
|
return (next(elem) &&
|
|
adapter.getText(elem).toLowerCase().includes(itext));
|
|
};
|
|
},
|
|
// Location specific methods
|
|
"nth-child": function (next, rule, _a) {
|
|
var adapter = _a.adapter, equals = _a.equals;
|
|
var func = nth_check_1.default(rule);
|
|
if (func === boolbase_1.falseFunc)
|
|
return boolbase_1.falseFunc;
|
|
if (func === boolbase_1.trueFunc)
|
|
return getChildFunc(next, adapter);
|
|
return function nthChild(elem) {
|
|
var siblings = adapter.getSiblings(elem);
|
|
var pos = 0;
|
|
for (var i = 0; i < siblings.length; i++) {
|
|
if (equals(elem, siblings[i]))
|
|
break;
|
|
if (adapter.isTag(siblings[i])) {
|
|
pos++;
|
|
}
|
|
}
|
|
return func(pos) && next(elem);
|
|
};
|
|
},
|
|
"nth-last-child": function (next, rule, _a) {
|
|
var adapter = _a.adapter, equals = _a.equals;
|
|
var func = nth_check_1.default(rule);
|
|
if (func === boolbase_1.falseFunc)
|
|
return boolbase_1.falseFunc;
|
|
if (func === boolbase_1.trueFunc)
|
|
return getChildFunc(next, adapter);
|
|
return function nthLastChild(elem) {
|
|
var siblings = adapter.getSiblings(elem);
|
|
var pos = 0;
|
|
for (var i = siblings.length - 1; i >= 0; i--) {
|
|
if (equals(elem, siblings[i]))
|
|
break;
|
|
if (adapter.isTag(siblings[i])) {
|
|
pos++;
|
|
}
|
|
}
|
|
return func(pos) && next(elem);
|
|
};
|
|
},
|
|
"nth-of-type": function (next, rule, _a) {
|
|
var adapter = _a.adapter, equals = _a.equals;
|
|
var func = nth_check_1.default(rule);
|
|
if (func === boolbase_1.falseFunc)
|
|
return boolbase_1.falseFunc;
|
|
if (func === boolbase_1.trueFunc)
|
|
return getChildFunc(next, adapter);
|
|
return function nthOfType(elem) {
|
|
var siblings = adapter.getSiblings(elem);
|
|
var pos = 0;
|
|
for (var i = 0; i < siblings.length; i++) {
|
|
var currentSibling = siblings[i];
|
|
if (equals(elem, currentSibling))
|
|
break;
|
|
if (adapter.isTag(currentSibling) &&
|
|
adapter.getName(currentSibling) === adapter.getName(elem)) {
|
|
pos++;
|
|
}
|
|
}
|
|
return func(pos) && next(elem);
|
|
};
|
|
},
|
|
"nth-last-of-type": function (next, rule, _a) {
|
|
var adapter = _a.adapter, equals = _a.equals;
|
|
var func = nth_check_1.default(rule);
|
|
if (func === boolbase_1.falseFunc)
|
|
return boolbase_1.falseFunc;
|
|
if (func === boolbase_1.trueFunc)
|
|
return getChildFunc(next, adapter);
|
|
return function nthLastOfType(elem) {
|
|
var siblings = adapter.getSiblings(elem);
|
|
var pos = 0;
|
|
for (var i = siblings.length - 1; i >= 0; i--) {
|
|
var currentSibling = siblings[i];
|
|
if (equals(elem, currentSibling))
|
|
break;
|
|
if (adapter.isTag(currentSibling) &&
|
|
adapter.getName(currentSibling) === adapter.getName(elem)) {
|
|
pos++;
|
|
}
|
|
}
|
|
return func(pos) && next(elem);
|
|
};
|
|
},
|
|
// TODO determine the actual root element
|
|
root: function (next, _rule, _a) {
|
|
var adapter = _a.adapter;
|
|
return function (elem) {
|
|
var parent = adapter.getParent(elem);
|
|
return (parent == null || !adapter.isTag(parent)) && next(elem);
|
|
};
|
|
},
|
|
scope: function (next, rule, options, context) {
|
|
var equals = options.equals;
|
|
if (!context || context.length === 0) {
|
|
// Equivalent to :root
|
|
return exports.filters.root(next, rule, options);
|
|
}
|
|
if (context.length === 1) {
|
|
// NOTE: can't be unpacked, as :has uses this for side-effects
|
|
return function (elem) { return equals(context[0], elem) && next(elem); };
|
|
}
|
|
return function (elem) { return context.includes(elem) && next(elem); };
|
|
},
|
|
hover: dynamicStatePseudo("isHovered"),
|
|
visited: dynamicStatePseudo("isVisited"),
|
|
active: dynamicStatePseudo("isActive"),
|
|
};
|
|
/**
|
|
* Dynamic state pseudos. These depend on optional Adapter methods.
|
|
*
|
|
* @param name The name of the adapter method to call.
|
|
* @returns Pseudo for the `filters` object.
|
|
*/
|
|
function dynamicStatePseudo(name) {
|
|
return function dynamicPseudo(next, _rule, _a) {
|
|
var adapter = _a.adapter;
|
|
var func = adapter[name];
|
|
if (typeof func !== "function") {
|
|
return boolbase_1.falseFunc;
|
|
}
|
|
return function active(elem) {
|
|
return func(elem) && next(elem);
|
|
};
|
|
};
|
|
}
|
|
|
|
},{"boolbase":2,"nth-check":61}],28:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.compilePseudoSelector = exports.aliases = exports.pseudos = exports.filters = void 0;
|
|
/*
|
|
* Pseudo selectors
|
|
*
|
|
* Pseudo selectors are available in three forms:
|
|
*
|
|
* 1. Filters are called when the selector is compiled and return a function
|
|
* that has to return either false, or the results of `next()`.
|
|
* 2. Pseudos are called on execution. They have to return a boolean.
|
|
* 3. Subselects work like filters, but have an embedded selector that will be run separately.
|
|
*
|
|
* Filters are great if you want to do some pre-processing, or change the call order
|
|
* of `next()` and your code.
|
|
* Pseudos should be used to implement simple checks.
|
|
*/
|
|
var boolbase_1 = require("boolbase");
|
|
var css_what_1 = require("css-what");
|
|
var filters_1 = require("./filters");
|
|
Object.defineProperty(exports, "filters", { enumerable: true, get: function () { return filters_1.filters; } });
|
|
var pseudos_1 = require("./pseudos");
|
|
Object.defineProperty(exports, "pseudos", { enumerable: true, get: function () { return pseudos_1.pseudos; } });
|
|
var aliases_1 = require("./aliases");
|
|
Object.defineProperty(exports, "aliases", { enumerable: true, get: function () { return aliases_1.aliases; } });
|
|
var subselects_1 = require("./subselects");
|
|
function compilePseudoSelector(next, selector, options, context, compileToken) {
|
|
var name = selector.name, data = selector.data;
|
|
if (Array.isArray(data)) {
|
|
return subselects_1.subselects[name](next, data, options, context, compileToken);
|
|
}
|
|
if (name in aliases_1.aliases) {
|
|
if (data != null) {
|
|
throw new Error("Pseudo " + name + " doesn't have any arguments");
|
|
}
|
|
// The alias has to be parsed here, to make sure options are respected.
|
|
var alias = css_what_1.parse(aliases_1.aliases[name], options);
|
|
return subselects_1.subselects.is(next, alias, options, context, compileToken);
|
|
}
|
|
if (name in filters_1.filters) {
|
|
return filters_1.filters[name](next, data, options, context);
|
|
}
|
|
if (name in pseudos_1.pseudos) {
|
|
var pseudo_1 = pseudos_1.pseudos[name];
|
|
pseudos_1.verifyPseudoArgs(pseudo_1, name, data);
|
|
return pseudo_1 === boolbase_1.falseFunc
|
|
? boolbase_1.falseFunc
|
|
: next === boolbase_1.trueFunc
|
|
? function (elem) { return pseudo_1(elem, options, data); }
|
|
: function (elem) { return pseudo_1(elem, options, data) && next(elem); };
|
|
}
|
|
throw new Error("unmatched pseudo-class :" + name);
|
|
}
|
|
exports.compilePseudoSelector = compilePseudoSelector;
|
|
|
|
},{"./aliases":26,"./filters":27,"./pseudos":29,"./subselects":30,"boolbase":2,"css-what":32}],29:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.verifyPseudoArgs = exports.pseudos = void 0;
|
|
// While filters are precompiled, pseudos get called when they are needed
|
|
exports.pseudos = {
|
|
empty: function (elem, _a) {
|
|
var adapter = _a.adapter;
|
|
return !adapter.getChildren(elem).some(function (elem) {
|
|
// FIXME: `getText` call is potentially expensive.
|
|
return adapter.isTag(elem) || adapter.getText(elem) !== "";
|
|
});
|
|
},
|
|
"first-child": function (elem, _a) {
|
|
var adapter = _a.adapter, equals = _a.equals;
|
|
var firstChild = adapter
|
|
.getSiblings(elem)
|
|
.find(function (elem) { return adapter.isTag(elem); });
|
|
return firstChild != null && equals(elem, firstChild);
|
|
},
|
|
"last-child": function (elem, _a) {
|
|
var adapter = _a.adapter, equals = _a.equals;
|
|
var siblings = adapter.getSiblings(elem);
|
|
for (var i = siblings.length - 1; i >= 0; i--) {
|
|
if (equals(elem, siblings[i]))
|
|
return true;
|
|
if (adapter.isTag(siblings[i]))
|
|
break;
|
|
}
|
|
return false;
|
|
},
|
|
"first-of-type": function (elem, _a) {
|
|
var adapter = _a.adapter, equals = _a.equals;
|
|
var siblings = adapter.getSiblings(elem);
|
|
var elemName = adapter.getName(elem);
|
|
for (var i = 0; i < siblings.length; i++) {
|
|
var currentSibling = siblings[i];
|
|
if (equals(elem, currentSibling))
|
|
return true;
|
|
if (adapter.isTag(currentSibling) &&
|
|
adapter.getName(currentSibling) === elemName) {
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
"last-of-type": function (elem, _a) {
|
|
var adapter = _a.adapter, equals = _a.equals;
|
|
var siblings = adapter.getSiblings(elem);
|
|
var elemName = adapter.getName(elem);
|
|
for (var i = siblings.length - 1; i >= 0; i--) {
|
|
var currentSibling = siblings[i];
|
|
if (equals(elem, currentSibling))
|
|
return true;
|
|
if (adapter.isTag(currentSibling) &&
|
|
adapter.getName(currentSibling) === elemName) {
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
"only-of-type": function (elem, _a) {
|
|
var adapter = _a.adapter, equals = _a.equals;
|
|
var elemName = adapter.getName(elem);
|
|
return adapter
|
|
.getSiblings(elem)
|
|
.every(function (sibling) {
|
|
return equals(elem, sibling) ||
|
|
!adapter.isTag(sibling) ||
|
|
adapter.getName(sibling) !== elemName;
|
|
});
|
|
},
|
|
"only-child": function (elem, _a) {
|
|
var adapter = _a.adapter, equals = _a.equals;
|
|
return adapter
|
|
.getSiblings(elem)
|
|
.every(function (sibling) { return equals(elem, sibling) || !adapter.isTag(sibling); });
|
|
},
|
|
};
|
|
function verifyPseudoArgs(func, name, subselect) {
|
|
if (subselect === null) {
|
|
if (func.length > 2) {
|
|
throw new Error("pseudo-selector :" + name + " requires an argument");
|
|
}
|
|
}
|
|
else if (func.length === 2) {
|
|
throw new Error("pseudo-selector :" + name + " doesn't have any arguments");
|
|
}
|
|
}
|
|
exports.verifyPseudoArgs = verifyPseudoArgs;
|
|
|
|
},{}],30:[function(require,module,exports){
|
|
"use strict";
|
|
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
|
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
|
to[j] = from[i];
|
|
return to;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.subselects = exports.getNextSiblings = exports.ensureIsTag = exports.PLACEHOLDER_ELEMENT = void 0;
|
|
var boolbase_1 = require("boolbase");
|
|
var procedure_1 = require("../procedure");
|
|
/** Used as a placeholder for :has. Will be replaced with the actual element. */
|
|
exports.PLACEHOLDER_ELEMENT = {};
|
|
function ensureIsTag(next, adapter) {
|
|
if (next === boolbase_1.falseFunc)
|
|
return next;
|
|
return function (elem) { return adapter.isTag(elem) && next(elem); };
|
|
}
|
|
exports.ensureIsTag = ensureIsTag;
|
|
function getNextSiblings(elem, adapter) {
|
|
var siblings = adapter.getSiblings(elem);
|
|
if (siblings.length <= 1)
|
|
return [];
|
|
var elemIndex = siblings.indexOf(elem);
|
|
if (elemIndex < 0 || elemIndex === siblings.length - 1)
|
|
return [];
|
|
return siblings.slice(elemIndex + 1).filter(adapter.isTag);
|
|
}
|
|
exports.getNextSiblings = getNextSiblings;
|
|
var is = function (next, token, options, context, compileToken) {
|
|
var opts = {
|
|
xmlMode: !!options.xmlMode,
|
|
adapter: options.adapter,
|
|
equals: options.equals,
|
|
};
|
|
var func = compileToken(token, opts, context);
|
|
return function (elem) { return func(elem) && next(elem); };
|
|
};
|
|
/*
|
|
* :not, :has, :is and :matches have to compile selectors
|
|
* doing this in src/pseudos.ts would lead to circular dependencies,
|
|
* so we add them here
|
|
*/
|
|
exports.subselects = {
|
|
is: is,
|
|
/**
|
|
* `:matches` is an alias for `:is`.
|
|
*/
|
|
matches: is,
|
|
not: function (next, token, options, context, compileToken) {
|
|
var opts = {
|
|
xmlMode: !!options.xmlMode,
|
|
adapter: options.adapter,
|
|
equals: options.equals,
|
|
};
|
|
var func = compileToken(token, opts, context);
|
|
if (func === boolbase_1.falseFunc)
|
|
return next;
|
|
if (func === boolbase_1.trueFunc)
|
|
return boolbase_1.falseFunc;
|
|
return function not(elem) {
|
|
return !func(elem) && next(elem);
|
|
};
|
|
},
|
|
has: function (next, subselect, options, _context, compileToken) {
|
|
var adapter = options.adapter;
|
|
var opts = {
|
|
xmlMode: !!options.xmlMode,
|
|
adapter: adapter,
|
|
equals: options.equals,
|
|
};
|
|
// @ts-expect-error Uses an array as a pointer to the current element (side effects)
|
|
var context = subselect.some(function (s) {
|
|
return s.some(procedure_1.isTraversal);
|
|
})
|
|
? [exports.PLACEHOLDER_ELEMENT]
|
|
: undefined;
|
|
var compiled = compileToken(subselect, opts, context);
|
|
if (compiled === boolbase_1.falseFunc)
|
|
return boolbase_1.falseFunc;
|
|
if (compiled === boolbase_1.trueFunc) {
|
|
return function (elem) {
|
|
return adapter.getChildren(elem).some(adapter.isTag) && next(elem);
|
|
};
|
|
}
|
|
var hasElement = ensureIsTag(compiled, adapter);
|
|
var _a = compiled.shouldTestNextSiblings, shouldTestNextSiblings = _a === void 0 ? false : _a;
|
|
/*
|
|
* `shouldTestNextSiblings` will only be true if the query starts with
|
|
* a traversal (sibling or adjacent). That means we will always have a context.
|
|
*/
|
|
if (context) {
|
|
return function (elem) {
|
|
context[0] = elem;
|
|
var childs = adapter.getChildren(elem);
|
|
var nextElements = shouldTestNextSiblings
|
|
? __spreadArray(__spreadArray([], childs), getNextSiblings(elem, adapter)) : childs;
|
|
return (next(elem) && adapter.existsOne(hasElement, nextElements));
|
|
};
|
|
}
|
|
return function (elem) {
|
|
return next(elem) &&
|
|
adapter.existsOne(hasElement, adapter.getChildren(elem));
|
|
};
|
|
},
|
|
};
|
|
|
|
},{"../procedure":25,"boolbase":2}],31:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
var procedure_1 = require("./procedure");
|
|
var attributes = {
|
|
exists: 10,
|
|
equals: 8,
|
|
not: 7,
|
|
start: 6,
|
|
end: 6,
|
|
any: 5,
|
|
hyphen: 4,
|
|
element: 4,
|
|
};
|
|
/**
|
|
* Sort the parts of the passed selector,
|
|
* as there is potential for optimization
|
|
* (some types of selectors are faster than others)
|
|
*
|
|
* @param arr Selector to sort
|
|
*/
|
|
function sortByProcedure(arr) {
|
|
var procs = arr.map(getProcedure);
|
|
for (var i = 1; i < arr.length; i++) {
|
|
var procNew = procs[i];
|
|
if (procNew < 0)
|
|
continue;
|
|
for (var j = i - 1; j >= 0 && procNew < procs[j]; j--) {
|
|
var token = arr[j + 1];
|
|
arr[j + 1] = arr[j];
|
|
arr[j] = token;
|
|
procs[j + 1] = procs[j];
|
|
procs[j] = procNew;
|
|
}
|
|
}
|
|
}
|
|
exports.default = sortByProcedure;
|
|
function getProcedure(token) {
|
|
var proc = procedure_1.procedure[token.type];
|
|
if (token.type === "attribute") {
|
|
proc = attributes[token.action];
|
|
if (proc === attributes.equals && token.name === "id") {
|
|
// Prefer ID selectors (eg. #ID)
|
|
proc = 9;
|
|
}
|
|
if (token.ignoreCase) {
|
|
/*
|
|
* IgnoreCase adds some overhead, prefer "normal" token
|
|
* this is a binary operation, to ensure it's still an int
|
|
*/
|
|
proc >>= 1;
|
|
}
|
|
}
|
|
else if (token.type === "pseudo") {
|
|
if (!token.data) {
|
|
proc = 3;
|
|
}
|
|
else if (token.name === "has" || token.name === "contains") {
|
|
proc = 0; // Expensive in any case
|
|
}
|
|
else if (Array.isArray(token.data)) {
|
|
// "matches" and "not"
|
|
proc = 0;
|
|
for (var i = 0; i < token.data.length; i++) {
|
|
// TODO better handling of complex selectors
|
|
if (token.data[i].length !== 1)
|
|
continue;
|
|
var cur = getProcedure(token.data[i][0]);
|
|
// Avoid executing :has or :contains
|
|
if (cur === 0) {
|
|
proc = 0;
|
|
break;
|
|
}
|
|
if (cur > proc)
|
|
proc = cur;
|
|
}
|
|
if (token.data.length > 1 && proc > 0)
|
|
proc -= 1;
|
|
}
|
|
else {
|
|
proc = 1;
|
|
}
|
|
}
|
|
return proc;
|
|
}
|
|
|
|
},{"./procedure":25}],32:[function(require,module,exports){
|
|
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
};
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.stringify = exports.parse = void 0;
|
|
__exportStar(require("./parse"), exports);
|
|
var parse_1 = require("./parse");
|
|
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return __importDefault(parse_1).default; } });
|
|
var stringify_1 = require("./stringify");
|
|
Object.defineProperty(exports, "stringify", { enumerable: true, get: function () { return __importDefault(stringify_1).default; } });
|
|
|
|
},{"./parse":33,"./stringify":34}],33:[function(require,module,exports){
|
|
"use strict";
|
|
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
|
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
|
to[j] = from[i];
|
|
return to;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.isTraversal = void 0;
|
|
var reName = /^[^\\#]?(?:\\(?:[\da-f]{1,6}\s?|.)|[\w\-\u00b0-\uFFFF])+/;
|
|
var reEscape = /\\([\da-f]{1,6}\s?|(\s)|.)/gi;
|
|
var actionTypes = new Map([
|
|
["~", "element"],
|
|
["^", "start"],
|
|
["$", "end"],
|
|
["*", "any"],
|
|
["!", "not"],
|
|
["|", "hyphen"],
|
|
]);
|
|
var Traversals = {
|
|
">": "child",
|
|
"<": "parent",
|
|
"~": "sibling",
|
|
"+": "adjacent",
|
|
};
|
|
var attribSelectors = {
|
|
"#": ["id", "equals"],
|
|
".": ["class", "element"],
|
|
};
|
|
// Pseudos, whose data property is parsed as well.
|
|
var unpackPseudos = new Set([
|
|
"has",
|
|
"not",
|
|
"matches",
|
|
"is",
|
|
"host",
|
|
"host-context",
|
|
]);
|
|
var traversalNames = new Set(__spreadArray([
|
|
"descendant"
|
|
], Object.keys(Traversals).map(function (k) { return Traversals[k]; })));
|
|
/**
|
|
* Attributes that are case-insensitive in HTML.
|
|
*
|
|
* @private
|
|
* @see https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors
|
|
*/
|
|
var caseInsensitiveAttributes = new Set([
|
|
"accept",
|
|
"accept-charset",
|
|
"align",
|
|
"alink",
|
|
"axis",
|
|
"bgcolor",
|
|
"charset",
|
|
"checked",
|
|
"clear",
|
|
"codetype",
|
|
"color",
|
|
"compact",
|
|
"declare",
|
|
"defer",
|
|
"dir",
|
|
"direction",
|
|
"disabled",
|
|
"enctype",
|
|
"face",
|
|
"frame",
|
|
"hreflang",
|
|
"http-equiv",
|
|
"lang",
|
|
"language",
|
|
"link",
|
|
"media",
|
|
"method",
|
|
"multiple",
|
|
"nohref",
|
|
"noresize",
|
|
"noshade",
|
|
"nowrap",
|
|
"readonly",
|
|
"rel",
|
|
"rev",
|
|
"rules",
|
|
"scope",
|
|
"scrolling",
|
|
"selected",
|
|
"shape",
|
|
"target",
|
|
"text",
|
|
"type",
|
|
"valign",
|
|
"valuetype",
|
|
"vlink",
|
|
]);
|
|
/**
|
|
* Checks whether a specific selector is a traversal.
|
|
* This is useful eg. in swapping the order of elements that
|
|
* are not traversals.
|
|
*
|
|
* @param selector Selector to check.
|
|
*/
|
|
function isTraversal(selector) {
|
|
return traversalNames.has(selector.type);
|
|
}
|
|
exports.isTraversal = isTraversal;
|
|
var stripQuotesFromPseudos = new Set(["contains", "icontains"]);
|
|
var quotes = new Set(['"', "'"]);
|
|
// Unescape function taken from https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L152
|
|
function funescape(_, escaped, escapedWhitespace) {
|
|
var high = parseInt(escaped, 16) - 0x10000;
|
|
// NaN means non-codepoint
|
|
return high !== high || escapedWhitespace
|
|
? escaped
|
|
: high < 0
|
|
? // BMP codepoint
|
|
String.fromCharCode(high + 0x10000)
|
|
: // Supplemental Plane codepoint (surrogate pair)
|
|
String.fromCharCode((high >> 10) | 0xd800, (high & 0x3ff) | 0xdc00);
|
|
}
|
|
function unescapeCSS(str) {
|
|
return str.replace(reEscape, funescape);
|
|
}
|
|
function isWhitespace(c) {
|
|
return c === " " || c === "\n" || c === "\t" || c === "\f" || c === "\r";
|
|
}
|
|
/**
|
|
* Parses `selector`, optionally with the passed `options`.
|
|
*
|
|
* @param selector Selector to parse.
|
|
* @param options Options for parsing.
|
|
* @returns Returns a two-dimensional array.
|
|
* The first dimension represents selectors separated by commas (eg. `sub1, sub2`),
|
|
* the second contains the relevant tokens for that selector.
|
|
*/
|
|
function parse(selector, options) {
|
|
var subselects = [];
|
|
var endIndex = parseSelector(subselects, "" + selector, options, 0);
|
|
if (endIndex < selector.length) {
|
|
throw new Error("Unmatched selector: " + selector.slice(endIndex));
|
|
}
|
|
return subselects;
|
|
}
|
|
exports.default = parse;
|
|
function parseSelector(subselects, selector, options, selectorIndex) {
|
|
var _a, _b;
|
|
if (options === void 0) { options = {}; }
|
|
var tokens = [];
|
|
var sawWS = false;
|
|
function getName(offset) {
|
|
var match = selector.slice(selectorIndex + offset).match(reName);
|
|
if (!match) {
|
|
throw new Error("Expected name, found " + selector.slice(selectorIndex));
|
|
}
|
|
var name = match[0];
|
|
selectorIndex += offset + name.length;
|
|
return unescapeCSS(name);
|
|
}
|
|
function stripWhitespace(offset) {
|
|
while (isWhitespace(selector.charAt(selectorIndex + offset)))
|
|
offset++;
|
|
selectorIndex += offset;
|
|
}
|
|
function isEscaped(pos) {
|
|
var slashCount = 0;
|
|
while (selector.charAt(--pos) === "\\")
|
|
slashCount++;
|
|
return (slashCount & 1) === 1;
|
|
}
|
|
function ensureNotTraversal() {
|
|
if (tokens.length > 0 && isTraversal(tokens[tokens.length - 1])) {
|
|
throw new Error("Did not expect successive traversals.");
|
|
}
|
|
}
|
|
stripWhitespace(0);
|
|
while (selector !== "") {
|
|
var firstChar = selector.charAt(selectorIndex);
|
|
if (isWhitespace(firstChar)) {
|
|
sawWS = true;
|
|
stripWhitespace(1);
|
|
}
|
|
else if (firstChar in Traversals) {
|
|
ensureNotTraversal();
|
|
tokens.push({ type: Traversals[firstChar] });
|
|
sawWS = false;
|
|
stripWhitespace(1);
|
|
}
|
|
else if (firstChar === ",") {
|
|
if (tokens.length === 0) {
|
|
throw new Error("Empty sub-selector");
|
|
}
|
|
subselects.push(tokens);
|
|
tokens = [];
|
|
sawWS = false;
|
|
stripWhitespace(1);
|
|
}
|
|
else if (selector.startsWith("/*", selectorIndex)) {
|
|
var endIndex = selector.indexOf("*/", selectorIndex + 2);
|
|
if (endIndex < 0) {
|
|
throw new Error("Comment was not terminated");
|
|
}
|
|
selectorIndex = endIndex + 2;
|
|
}
|
|
else {
|
|
if (sawWS) {
|
|
ensureNotTraversal();
|
|
tokens.push({ type: "descendant" });
|
|
sawWS = false;
|
|
}
|
|
if (firstChar in attribSelectors) {
|
|
var _c = attribSelectors[firstChar], name_1 = _c[0], action = _c[1];
|
|
tokens.push({
|
|
type: "attribute",
|
|
name: name_1,
|
|
action: action,
|
|
value: getName(1),
|
|
namespace: null,
|
|
// TODO: Add quirksMode option, which makes `ignoreCase` `true` for HTML.
|
|
ignoreCase: options.xmlMode ? null : false,
|
|
});
|
|
}
|
|
else if (firstChar === "[") {
|
|
stripWhitespace(1);
|
|
// Determine attribute name and namespace
|
|
var name_2 = void 0;
|
|
var namespace = null;
|
|
if (selector.charAt(selectorIndex) === "|") {
|
|
namespace = "";
|
|
selectorIndex += 1;
|
|
}
|
|
if (selector.startsWith("*|", selectorIndex)) {
|
|
namespace = "*";
|
|
selectorIndex += 2;
|
|
}
|
|
name_2 = getName(0);
|
|
if (namespace === null &&
|
|
selector.charAt(selectorIndex) === "|" &&
|
|
selector.charAt(selectorIndex + 1) !== "=") {
|
|
namespace = name_2;
|
|
name_2 = getName(1);
|
|
}
|
|
if ((_a = options.lowerCaseAttributeNames) !== null && _a !== void 0 ? _a : !options.xmlMode) {
|
|
name_2 = name_2.toLowerCase();
|
|
}
|
|
stripWhitespace(0);
|
|
// Determine comparison operation
|
|
var action = "exists";
|
|
var possibleAction = actionTypes.get(selector.charAt(selectorIndex));
|
|
if (possibleAction) {
|
|
action = possibleAction;
|
|
if (selector.charAt(selectorIndex + 1) !== "=") {
|
|
throw new Error("Expected `=`");
|
|
}
|
|
stripWhitespace(2);
|
|
}
|
|
else if (selector.charAt(selectorIndex) === "=") {
|
|
action = "equals";
|
|
stripWhitespace(1);
|
|
}
|
|
// Determine value
|
|
var value = "";
|
|
var ignoreCase = null;
|
|
if (action !== "exists") {
|
|
if (quotes.has(selector.charAt(selectorIndex))) {
|
|
var quote = selector.charAt(selectorIndex);
|
|
var sectionEnd = selectorIndex + 1;
|
|
while (sectionEnd < selector.length &&
|
|
(selector.charAt(sectionEnd) !== quote ||
|
|
isEscaped(sectionEnd))) {
|
|
sectionEnd += 1;
|
|
}
|
|
if (selector.charAt(sectionEnd) !== quote) {
|
|
throw new Error("Attribute value didn't end");
|
|
}
|
|
value = unescapeCSS(selector.slice(selectorIndex + 1, sectionEnd));
|
|
selectorIndex = sectionEnd + 1;
|
|
}
|
|
else {
|
|
var valueStart = selectorIndex;
|
|
while (selectorIndex < selector.length &&
|
|
((!isWhitespace(selector.charAt(selectorIndex)) &&
|
|
selector.charAt(selectorIndex) !== "]") ||
|
|
isEscaped(selectorIndex))) {
|
|
selectorIndex += 1;
|
|
}
|
|
value = unescapeCSS(selector.slice(valueStart, selectorIndex));
|
|
}
|
|
stripWhitespace(0);
|
|
// See if we have a force ignore flag
|
|
var forceIgnore = selector.charAt(selectorIndex);
|
|
// If the forceIgnore flag is set (either `i` or `s`), use that value
|
|
if (forceIgnore === "s" || forceIgnore === "S") {
|
|
ignoreCase = false;
|
|
stripWhitespace(1);
|
|
}
|
|
else if (forceIgnore === "i" || forceIgnore === "I") {
|
|
ignoreCase = true;
|
|
stripWhitespace(1);
|
|
}
|
|
}
|
|
// If `xmlMode` is set, there are no rules; otherwise, use the `caseInsensitiveAttributes` list.
|
|
if (!options.xmlMode) {
|
|
// TODO: Skip this for `exists`, as there is no value to compare to.
|
|
ignoreCase !== null && ignoreCase !== void 0 ? ignoreCase : (ignoreCase = caseInsensitiveAttributes.has(name_2));
|
|
}
|
|
if (selector.charAt(selectorIndex) !== "]") {
|
|
throw new Error("Attribute selector didn't terminate");
|
|
}
|
|
selectorIndex += 1;
|
|
var attributeSelector = {
|
|
type: "attribute",
|
|
name: name_2,
|
|
action: action,
|
|
value: value,
|
|
namespace: namespace,
|
|
ignoreCase: ignoreCase,
|
|
};
|
|
tokens.push(attributeSelector);
|
|
}
|
|
else if (firstChar === ":") {
|
|
if (selector.charAt(selectorIndex + 1) === ":") {
|
|
tokens.push({
|
|
type: "pseudo-element",
|
|
name: getName(2).toLowerCase(),
|
|
});
|
|
continue;
|
|
}
|
|
var name_3 = getName(1).toLowerCase();
|
|
var data = null;
|
|
if (selector.charAt(selectorIndex) === "(") {
|
|
if (unpackPseudos.has(name_3)) {
|
|
if (quotes.has(selector.charAt(selectorIndex + 1))) {
|
|
throw new Error("Pseudo-selector " + name_3 + " cannot be quoted");
|
|
}
|
|
data = [];
|
|
selectorIndex = parseSelector(data, selector, options, selectorIndex + 1);
|
|
if (selector.charAt(selectorIndex) !== ")") {
|
|
throw new Error("Missing closing parenthesis in :" + name_3 + " (" + selector + ")");
|
|
}
|
|
selectorIndex += 1;
|
|
}
|
|
else {
|
|
selectorIndex += 1;
|
|
var start = selectorIndex;
|
|
var counter = 1;
|
|
for (; counter > 0 && selectorIndex < selector.length; selectorIndex++) {
|
|
if (selector.charAt(selectorIndex) === "(" &&
|
|
!isEscaped(selectorIndex)) {
|
|
counter++;
|
|
}
|
|
else if (selector.charAt(selectorIndex) === ")" &&
|
|
!isEscaped(selectorIndex)) {
|
|
counter--;
|
|
}
|
|
}
|
|
if (counter) {
|
|
throw new Error("Parenthesis not matched");
|
|
}
|
|
data = selector.slice(start, selectorIndex - 1);
|
|
if (stripQuotesFromPseudos.has(name_3)) {
|
|
var quot = data.charAt(0);
|
|
if (quot === data.slice(-1) && quotes.has(quot)) {
|
|
data = data.slice(1, -1);
|
|
}
|
|
data = unescapeCSS(data);
|
|
}
|
|
}
|
|
}
|
|
tokens.push({ type: "pseudo", name: name_3, data: data });
|
|
}
|
|
else {
|
|
var namespace = null;
|
|
var name_4 = void 0;
|
|
if (firstChar === "*") {
|
|
selectorIndex += 1;
|
|
name_4 = "*";
|
|
}
|
|
else if (reName.test(selector.slice(selectorIndex))) {
|
|
if (selector.charAt(selectorIndex) === "|") {
|
|
namespace = "";
|
|
selectorIndex += 1;
|
|
}
|
|
name_4 = getName(0);
|
|
}
|
|
else {
|
|
/*
|
|
* We have finished parsing the selector.
|
|
* Remove descendant tokens at the end if they exist,
|
|
* and return the last index, so that parsing can be
|
|
* picked up from here.
|
|
*/
|
|
if (tokens.length &&
|
|
tokens[tokens.length - 1].type === "descendant") {
|
|
tokens.pop();
|
|
}
|
|
addToken(subselects, tokens);
|
|
return selectorIndex;
|
|
}
|
|
if (selector.charAt(selectorIndex) === "|") {
|
|
namespace = name_4;
|
|
if (selector.charAt(selectorIndex + 1) === "*") {
|
|
name_4 = "*";
|
|
selectorIndex += 2;
|
|
}
|
|
else {
|
|
name_4 = getName(1);
|
|
}
|
|
}
|
|
if (name_4 === "*") {
|
|
tokens.push({ type: "universal", namespace: namespace });
|
|
}
|
|
else {
|
|
if ((_b = options.lowerCaseTags) !== null && _b !== void 0 ? _b : !options.xmlMode) {
|
|
name_4 = name_4.toLowerCase();
|
|
}
|
|
tokens.push({ type: "tag", name: name_4, namespace: namespace });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
addToken(subselects, tokens);
|
|
return selectorIndex;
|
|
}
|
|
function addToken(subselects, tokens) {
|
|
if (subselects.length > 0 && tokens.length === 0) {
|
|
throw new Error("Empty sub-selector");
|
|
}
|
|
subselects.push(tokens);
|
|
}
|
|
|
|
},{}],34:[function(require,module,exports){
|
|
"use strict";
|
|
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
|
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
|
to[j] = from[i];
|
|
return to;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
var actionTypes = {
|
|
equals: "",
|
|
element: "~",
|
|
start: "^",
|
|
end: "$",
|
|
any: "*",
|
|
not: "!",
|
|
hyphen: "|",
|
|
};
|
|
var charsToEscape = new Set(__spreadArray(__spreadArray([], Object.keys(actionTypes)
|
|
.map(function (typeKey) { return actionTypes[typeKey]; })
|
|
.filter(Boolean)), [
|
|
":",
|
|
"[",
|
|
"]",
|
|
" ",
|
|
"\\",
|
|
"(",
|
|
")",
|
|
"'",
|
|
]));
|
|
/**
|
|
* Turns `selector` back into a string.
|
|
*
|
|
* @param selector Selector to stringify.
|
|
*/
|
|
function stringify(selector) {
|
|
return selector.map(stringifySubselector).join(", ");
|
|
}
|
|
exports.default = stringify;
|
|
function stringifySubselector(token) {
|
|
return token.map(stringifyToken).join("");
|
|
}
|
|
function stringifyToken(token) {
|
|
switch (token.type) {
|
|
// Simple types
|
|
case "child":
|
|
return " > ";
|
|
case "parent":
|
|
return " < ";
|
|
case "sibling":
|
|
return " ~ ";
|
|
case "adjacent":
|
|
return " + ";
|
|
case "descendant":
|
|
return " ";
|
|
case "universal":
|
|
return getNamespace(token.namespace) + "*";
|
|
case "tag":
|
|
return getNamespacedName(token);
|
|
case "pseudo-element":
|
|
return "::" + escapeName(token.name);
|
|
case "pseudo":
|
|
if (token.data === null)
|
|
return ":" + escapeName(token.name);
|
|
if (typeof token.data === "string") {
|
|
return ":" + escapeName(token.name) + "(" + escapeName(token.data) + ")";
|
|
}
|
|
return ":" + escapeName(token.name) + "(" + stringify(token.data) + ")";
|
|
case "attribute": {
|
|
if (token.name === "id" &&
|
|
token.action === "equals" &&
|
|
!token.ignoreCase &&
|
|
!token.namespace) {
|
|
return "#" + escapeName(token.value);
|
|
}
|
|
if (token.name === "class" &&
|
|
token.action === "element" &&
|
|
!token.ignoreCase &&
|
|
!token.namespace) {
|
|
return "." + escapeName(token.value);
|
|
}
|
|
var name_1 = getNamespacedName(token);
|
|
if (token.action === "exists") {
|
|
return "[" + name_1 + "]";
|
|
}
|
|
return "[" + name_1 + actionTypes[token.action] + "='" + escapeName(token.value) + "'" + (token.ignoreCase ? "i" : token.ignoreCase === false ? "s" : "") + "]";
|
|
}
|
|
}
|
|
}
|
|
function getNamespacedName(token) {
|
|
return "" + getNamespace(token.namespace) + escapeName(token.name);
|
|
}
|
|
function getNamespace(namespace) {
|
|
return namespace !== null
|
|
? (namespace === "*" ? "*" : escapeName(namespace)) + "|"
|
|
: "";
|
|
}
|
|
function escapeName(str) {
|
|
return str
|
|
.split("")
|
|
.map(function (c) { return (charsToEscape.has(c) ? "\\" + c : c); })
|
|
.join("");
|
|
}
|
|
|
|
},{}],35:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.attributeNames = exports.elementNames = void 0;
|
|
exports.elementNames = new Map([
|
|
["altglyph", "altGlyph"],
|
|
["altglyphdef", "altGlyphDef"],
|
|
["altglyphitem", "altGlyphItem"],
|
|
["animatecolor", "animateColor"],
|
|
["animatemotion", "animateMotion"],
|
|
["animatetransform", "animateTransform"],
|
|
["clippath", "clipPath"],
|
|
["feblend", "feBlend"],
|
|
["fecolormatrix", "feColorMatrix"],
|
|
["fecomponenttransfer", "feComponentTransfer"],
|
|
["fecomposite", "feComposite"],
|
|
["feconvolvematrix", "feConvolveMatrix"],
|
|
["fediffuselighting", "feDiffuseLighting"],
|
|
["fedisplacementmap", "feDisplacementMap"],
|
|
["fedistantlight", "feDistantLight"],
|
|
["fedropshadow", "feDropShadow"],
|
|
["feflood", "feFlood"],
|
|
["fefunca", "feFuncA"],
|
|
["fefuncb", "feFuncB"],
|
|
["fefuncg", "feFuncG"],
|
|
["fefuncr", "feFuncR"],
|
|
["fegaussianblur", "feGaussianBlur"],
|
|
["feimage", "feImage"],
|
|
["femerge", "feMerge"],
|
|
["femergenode", "feMergeNode"],
|
|
["femorphology", "feMorphology"],
|
|
["feoffset", "feOffset"],
|
|
["fepointlight", "fePointLight"],
|
|
["fespecularlighting", "feSpecularLighting"],
|
|
["fespotlight", "feSpotLight"],
|
|
["fetile", "feTile"],
|
|
["feturbulence", "feTurbulence"],
|
|
["foreignobject", "foreignObject"],
|
|
["glyphref", "glyphRef"],
|
|
["lineargradient", "linearGradient"],
|
|
["radialgradient", "radialGradient"],
|
|
["textpath", "textPath"],
|
|
]);
|
|
exports.attributeNames = new Map([
|
|
["definitionurl", "definitionURL"],
|
|
["attributename", "attributeName"],
|
|
["attributetype", "attributeType"],
|
|
["basefrequency", "baseFrequency"],
|
|
["baseprofile", "baseProfile"],
|
|
["calcmode", "calcMode"],
|
|
["clippathunits", "clipPathUnits"],
|
|
["diffuseconstant", "diffuseConstant"],
|
|
["edgemode", "edgeMode"],
|
|
["filterunits", "filterUnits"],
|
|
["glyphref", "glyphRef"],
|
|
["gradienttransform", "gradientTransform"],
|
|
["gradientunits", "gradientUnits"],
|
|
["kernelmatrix", "kernelMatrix"],
|
|
["kernelunitlength", "kernelUnitLength"],
|
|
["keypoints", "keyPoints"],
|
|
["keysplines", "keySplines"],
|
|
["keytimes", "keyTimes"],
|
|
["lengthadjust", "lengthAdjust"],
|
|
["limitingconeangle", "limitingConeAngle"],
|
|
["markerheight", "markerHeight"],
|
|
["markerunits", "markerUnits"],
|
|
["markerwidth", "markerWidth"],
|
|
["maskcontentunits", "maskContentUnits"],
|
|
["maskunits", "maskUnits"],
|
|
["numoctaves", "numOctaves"],
|
|
["pathlength", "pathLength"],
|
|
["patterncontentunits", "patternContentUnits"],
|
|
["patterntransform", "patternTransform"],
|
|
["patternunits", "patternUnits"],
|
|
["pointsatx", "pointsAtX"],
|
|
["pointsaty", "pointsAtY"],
|
|
["pointsatz", "pointsAtZ"],
|
|
["preservealpha", "preserveAlpha"],
|
|
["preserveaspectratio", "preserveAspectRatio"],
|
|
["primitiveunits", "primitiveUnits"],
|
|
["refx", "refX"],
|
|
["refy", "refY"],
|
|
["repeatcount", "repeatCount"],
|
|
["repeatdur", "repeatDur"],
|
|
["requiredextensions", "requiredExtensions"],
|
|
["requiredfeatures", "requiredFeatures"],
|
|
["specularconstant", "specularConstant"],
|
|
["specularexponent", "specularExponent"],
|
|
["spreadmethod", "spreadMethod"],
|
|
["startoffset", "startOffset"],
|
|
["stddeviation", "stdDeviation"],
|
|
["stitchtiles", "stitchTiles"],
|
|
["surfacescale", "surfaceScale"],
|
|
["systemlanguage", "systemLanguage"],
|
|
["tablevalues", "tableValues"],
|
|
["targetx", "targetX"],
|
|
["targety", "targetY"],
|
|
["textlength", "textLength"],
|
|
["viewbox", "viewBox"],
|
|
["viewtarget", "viewTarget"],
|
|
["xchannelselector", "xChannelSelector"],
|
|
["ychannelselector", "yChannelSelector"],
|
|
["zoomandpan", "zoomAndPan"],
|
|
]);
|
|
|
|
},{}],36:[function(require,module,exports){
|
|
"use strict";
|
|
var __assign = (this && this.__assign) || function () {
|
|
__assign = Object.assign || function(t) {
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
s = arguments[i];
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
t[p] = s[p];
|
|
}
|
|
return t;
|
|
};
|
|
return __assign.apply(this, arguments);
|
|
};
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
/*
|
|
* Module dependencies
|
|
*/
|
|
var ElementType = __importStar(require("domelementtype"));
|
|
var entities_1 = require("entities");
|
|
/**
|
|
* Mixed-case SVG and MathML tags & attributes
|
|
* recognized by the HTML parser.
|
|
*
|
|
* @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inforeign
|
|
*/
|
|
var foreignNames_1 = require("./foreignNames");
|
|
var unencodedElements = new Set([
|
|
"style",
|
|
"script",
|
|
"xmp",
|
|
"iframe",
|
|
"noembed",
|
|
"noframes",
|
|
"plaintext",
|
|
"noscript",
|
|
]);
|
|
/**
|
|
* Format attributes
|
|
*/
|
|
function formatAttributes(attributes, opts) {
|
|
if (!attributes)
|
|
return;
|
|
return Object.keys(attributes)
|
|
.map(function (key) {
|
|
var _a, _b;
|
|
var value = (_a = attributes[key]) !== null && _a !== void 0 ? _a : "";
|
|
if (opts.xmlMode === "foreign") {
|
|
/* Fix up mixed-case attribute names */
|
|
key = (_b = foreignNames_1.attributeNames.get(key)) !== null && _b !== void 0 ? _b : key;
|
|
}
|
|
if (!opts.emptyAttrs && !opts.xmlMode && value === "") {
|
|
return key;
|
|
}
|
|
return key + "=\"" + (opts.decodeEntities !== false
|
|
? entities_1.encodeXML(value)
|
|
: value.replace(/"/g, """)) + "\"";
|
|
})
|
|
.join(" ");
|
|
}
|
|
/**
|
|
* Self-enclosing tags
|
|
*/
|
|
var singleTag = new Set([
|
|
"area",
|
|
"base",
|
|
"basefont",
|
|
"br",
|
|
"col",
|
|
"command",
|
|
"embed",
|
|
"frame",
|
|
"hr",
|
|
"img",
|
|
"input",
|
|
"isindex",
|
|
"keygen",
|
|
"link",
|
|
"meta",
|
|
"param",
|
|
"source",
|
|
"track",
|
|
"wbr",
|
|
]);
|
|
/**
|
|
* Renders a DOM node or an array of DOM nodes to a string.
|
|
*
|
|
* Can be thought of as the equivalent of the `outerHTML` of the passed node(s).
|
|
*
|
|
* @param node Node to be rendered.
|
|
* @param options Changes serialization behavior
|
|
*/
|
|
function render(node, options) {
|
|
if (options === void 0) { options = {}; }
|
|
var nodes = "length" in node ? node : [node];
|
|
var output = "";
|
|
for (var i = 0; i < nodes.length; i++) {
|
|
output += renderNode(nodes[i], options);
|
|
}
|
|
return output;
|
|
}
|
|
exports.default = render;
|
|
function renderNode(node, options) {
|
|
switch (node.type) {
|
|
case ElementType.Root:
|
|
return render(node.children, options);
|
|
case ElementType.Directive:
|
|
case ElementType.Doctype:
|
|
return renderDirective(node);
|
|
case ElementType.Comment:
|
|
return renderComment(node);
|
|
case ElementType.CDATA:
|
|
return renderCdata(node);
|
|
case ElementType.Script:
|
|
case ElementType.Style:
|
|
case ElementType.Tag:
|
|
return renderTag(node, options);
|
|
case ElementType.Text:
|
|
return renderText(node, options);
|
|
}
|
|
}
|
|
var foreignModeIntegrationPoints = new Set([
|
|
"mi",
|
|
"mo",
|
|
"mn",
|
|
"ms",
|
|
"mtext",
|
|
"annotation-xml",
|
|
"foreignObject",
|
|
"desc",
|
|
"title",
|
|
]);
|
|
var foreignElements = new Set(["svg", "math"]);
|
|
function renderTag(elem, opts) {
|
|
var _a;
|
|
// Handle SVG / MathML in HTML
|
|
if (opts.xmlMode === "foreign") {
|
|
/* Fix up mixed-case element names */
|
|
elem.name = (_a = foreignNames_1.elementNames.get(elem.name)) !== null && _a !== void 0 ? _a : elem.name;
|
|
/* Exit foreign mode at integration points */
|
|
if (elem.parent &&
|
|
foreignModeIntegrationPoints.has(elem.parent.name)) {
|
|
opts = __assign(__assign({}, opts), { xmlMode: false });
|
|
}
|
|
}
|
|
if (!opts.xmlMode && foreignElements.has(elem.name)) {
|
|
opts = __assign(__assign({}, opts), { xmlMode: "foreign" });
|
|
}
|
|
var tag = "<" + elem.name;
|
|
var attribs = formatAttributes(elem.attribs, opts);
|
|
if (attribs) {
|
|
tag += " " + attribs;
|
|
}
|
|
if (elem.children.length === 0 &&
|
|
(opts.xmlMode
|
|
? // In XML mode or foreign mode, and user hasn't explicitly turned off self-closing tags
|
|
opts.selfClosingTags !== false
|
|
: // User explicitly asked for self-closing tags, even in HTML mode
|
|
opts.selfClosingTags && singleTag.has(elem.name))) {
|
|
if (!opts.xmlMode)
|
|
tag += " ";
|
|
tag += "/>";
|
|
}
|
|
else {
|
|
tag += ">";
|
|
if (elem.children.length > 0) {
|
|
tag += render(elem.children, opts);
|
|
}
|
|
if (opts.xmlMode || !singleTag.has(elem.name)) {
|
|
tag += "</" + elem.name + ">";
|
|
}
|
|
}
|
|
return tag;
|
|
}
|
|
function renderDirective(elem) {
|
|
return "<" + elem.data + ">";
|
|
}
|
|
function renderText(elem, opts) {
|
|
var data = elem.data || "";
|
|
// If entities weren't decoded, no need to encode them back
|
|
if (opts.decodeEntities !== false &&
|
|
!(!opts.xmlMode &&
|
|
elem.parent &&
|
|
unencodedElements.has(elem.parent.name))) {
|
|
data = entities_1.encodeXML(data);
|
|
}
|
|
return data;
|
|
}
|
|
function renderCdata(elem) {
|
|
return "<![CDATA[" + elem.children[0].data + "]]>";
|
|
}
|
|
function renderComment(elem) {
|
|
return "<!--" + elem.data + "-->";
|
|
}
|
|
|
|
},{"./foreignNames":35,"domelementtype":37,"entities":50}],37:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.Doctype = exports.CDATA = exports.Tag = exports.Style = exports.Script = exports.Comment = exports.Directive = exports.Text = exports.Root = exports.isTag = exports.ElementType = void 0;
|
|
/** Types of elements found in htmlparser2's DOM */
|
|
var ElementType;
|
|
(function (ElementType) {
|
|
/** Type for the root element of a document */
|
|
ElementType["Root"] = "root";
|
|
/** Type for Text */
|
|
ElementType["Text"] = "text";
|
|
/** Type for <? ... ?> */
|
|
ElementType["Directive"] = "directive";
|
|
/** Type for <!-- ... --> */
|
|
ElementType["Comment"] = "comment";
|
|
/** Type for <script> tags */
|
|
ElementType["Script"] = "script";
|
|
/** Type for <style> tags */
|
|
ElementType["Style"] = "style";
|
|
/** Type for Any tag */
|
|
ElementType["Tag"] = "tag";
|
|
/** Type for <![CDATA[ ... ]]> */
|
|
ElementType["CDATA"] = "cdata";
|
|
/** Type for <!doctype ...> */
|
|
ElementType["Doctype"] = "doctype";
|
|
})(ElementType = exports.ElementType || (exports.ElementType = {}));
|
|
/**
|
|
* Tests whether an element is a tag or not.
|
|
*
|
|
* @param elem Element to test
|
|
*/
|
|
function isTag(elem) {
|
|
return (elem.type === ElementType.Tag ||
|
|
elem.type === ElementType.Script ||
|
|
elem.type === ElementType.Style);
|
|
}
|
|
exports.isTag = isTag;
|
|
// Exports for backwards compatibility
|
|
/** Type for the root element of a document */
|
|
exports.Root = ElementType.Root;
|
|
/** Type for Text */
|
|
exports.Text = ElementType.Text;
|
|
/** Type for <? ... ?> */
|
|
exports.Directive = ElementType.Directive;
|
|
/** Type for <!-- ... --> */
|
|
exports.Comment = ElementType.Comment;
|
|
/** Type for <script> tags */
|
|
exports.Script = ElementType.Script;
|
|
/** Type for <style> tags */
|
|
exports.Style = ElementType.Style;
|
|
/** Type for Any tag */
|
|
exports.Tag = ElementType.Tag;
|
|
/** Type for <![CDATA[ ... ]]> */
|
|
exports.CDATA = ElementType.CDATA;
|
|
/** Type for <!doctype ...> */
|
|
exports.Doctype = ElementType.Doctype;
|
|
|
|
},{}],38:[function(require,module,exports){
|
|
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.DomHandler = void 0;
|
|
var domelementtype_1 = require("domelementtype");
|
|
var node_1 = require("./node");
|
|
__exportStar(require("./node"), exports);
|
|
var reWhitespace = /\s+/g;
|
|
// Default options
|
|
var defaultOpts = {
|
|
normalizeWhitespace: false,
|
|
withStartIndices: false,
|
|
withEndIndices: false,
|
|
};
|
|
var DomHandler = /** @class */ (function () {
|
|
/**
|
|
* @param callback Called once parsing has completed.
|
|
* @param options Settings for the handler.
|
|
* @param elementCB Callback whenever a tag is closed.
|
|
*/
|
|
function DomHandler(callback, options, elementCB) {
|
|
/** The elements of the DOM */
|
|
this.dom = [];
|
|
/** The root element for the DOM */
|
|
this.root = new node_1.Document(this.dom);
|
|
/** Indicated whether parsing has been completed. */
|
|
this.done = false;
|
|
/** Stack of open tags. */
|
|
this.tagStack = [this.root];
|
|
/** A data node that is still being written to. */
|
|
this.lastNode = null;
|
|
/** Reference to the parser instance. Used for location information. */
|
|
this.parser = null;
|
|
// Make it possible to skip arguments, for backwards-compatibility
|
|
if (typeof options === "function") {
|
|
elementCB = options;
|
|
options = defaultOpts;
|
|
}
|
|
if (typeof callback === "object") {
|
|
options = callback;
|
|
callback = undefined;
|
|
}
|
|
this.callback = callback !== null && callback !== void 0 ? callback : null;
|
|
this.options = options !== null && options !== void 0 ? options : defaultOpts;
|
|
this.elementCB = elementCB !== null && elementCB !== void 0 ? elementCB : null;
|
|
}
|
|
DomHandler.prototype.onparserinit = function (parser) {
|
|
this.parser = parser;
|
|
};
|
|
// Resets the handler back to starting state
|
|
DomHandler.prototype.onreset = function () {
|
|
var _a;
|
|
this.dom = [];
|
|
this.root = new node_1.Document(this.dom);
|
|
this.done = false;
|
|
this.tagStack = [this.root];
|
|
this.lastNode = null;
|
|
this.parser = (_a = this.parser) !== null && _a !== void 0 ? _a : null;
|
|
};
|
|
// Signals the handler that parsing is done
|
|
DomHandler.prototype.onend = function () {
|
|
if (this.done)
|
|
return;
|
|
this.done = true;
|
|
this.parser = null;
|
|
this.handleCallback(null);
|
|
};
|
|
DomHandler.prototype.onerror = function (error) {
|
|
this.handleCallback(error);
|
|
};
|
|
DomHandler.prototype.onclosetag = function () {
|
|
this.lastNode = null;
|
|
var elem = this.tagStack.pop();
|
|
if (this.options.withEndIndices) {
|
|
elem.endIndex = this.parser.endIndex;
|
|
}
|
|
if (this.elementCB)
|
|
this.elementCB(elem);
|
|
};
|
|
DomHandler.prototype.onopentag = function (name, attribs) {
|
|
var type = this.options.xmlMode ? domelementtype_1.ElementType.Tag : undefined;
|
|
var element = new node_1.Element(name, attribs, undefined, type);
|
|
this.addNode(element);
|
|
this.tagStack.push(element);
|
|
};
|
|
DomHandler.prototype.ontext = function (data) {
|
|
var normalizeWhitespace = this.options.normalizeWhitespace;
|
|
var lastNode = this.lastNode;
|
|
if (lastNode && lastNode.type === domelementtype_1.ElementType.Text) {
|
|
if (normalizeWhitespace) {
|
|
lastNode.data = (lastNode.data + data).replace(reWhitespace, " ");
|
|
}
|
|
else {
|
|
lastNode.data += data;
|
|
}
|
|
}
|
|
else {
|
|
if (normalizeWhitespace) {
|
|
data = data.replace(reWhitespace, " ");
|
|
}
|
|
var node = new node_1.Text(data);
|
|
this.addNode(node);
|
|
this.lastNode = node;
|
|
}
|
|
};
|
|
DomHandler.prototype.oncomment = function (data) {
|
|
if (this.lastNode && this.lastNode.type === domelementtype_1.ElementType.Comment) {
|
|
this.lastNode.data += data;
|
|
return;
|
|
}
|
|
var node = new node_1.Comment(data);
|
|
this.addNode(node);
|
|
this.lastNode = node;
|
|
};
|
|
DomHandler.prototype.oncommentend = function () {
|
|
this.lastNode = null;
|
|
};
|
|
DomHandler.prototype.oncdatastart = function () {
|
|
var text = new node_1.Text("");
|
|
var node = new node_1.NodeWithChildren(domelementtype_1.ElementType.CDATA, [text]);
|
|
this.addNode(node);
|
|
text.parent = node;
|
|
this.lastNode = text;
|
|
};
|
|
DomHandler.prototype.oncdataend = function () {
|
|
this.lastNode = null;
|
|
};
|
|
DomHandler.prototype.onprocessinginstruction = function (name, data) {
|
|
var node = new node_1.ProcessingInstruction(name, data);
|
|
this.addNode(node);
|
|
};
|
|
DomHandler.prototype.handleCallback = function (error) {
|
|
if (typeof this.callback === "function") {
|
|
this.callback(error, this.dom);
|
|
}
|
|
else if (error) {
|
|
throw error;
|
|
}
|
|
};
|
|
DomHandler.prototype.addNode = function (node) {
|
|
var parent = this.tagStack[this.tagStack.length - 1];
|
|
var previousSibling = parent.children[parent.children.length - 1];
|
|
if (this.options.withStartIndices) {
|
|
node.startIndex = this.parser.startIndex;
|
|
}
|
|
if (this.options.withEndIndices) {
|
|
node.endIndex = this.parser.endIndex;
|
|
}
|
|
parent.children.push(node);
|
|
if (previousSibling) {
|
|
node.prev = previousSibling;
|
|
previousSibling.next = node;
|
|
}
|
|
node.parent = parent;
|
|
this.lastNode = null;
|
|
};
|
|
return DomHandler;
|
|
}());
|
|
exports.DomHandler = DomHandler;
|
|
exports.default = DomHandler;
|
|
|
|
},{"./node":39,"domelementtype":37}],39:[function(require,module,exports){
|
|
"use strict";
|
|
var __extends = (this && this.__extends) || (function () {
|
|
var extendStatics = function (d, b) {
|
|
extendStatics = Object.setPrototypeOf ||
|
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
return extendStatics(d, b);
|
|
};
|
|
return function (d, b) {
|
|
if (typeof b !== "function" && b !== null)
|
|
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
extendStatics(d, b);
|
|
function __() { this.constructor = d; }
|
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
};
|
|
})();
|
|
var __assign = (this && this.__assign) || function () {
|
|
__assign = Object.assign || function(t) {
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
s = arguments[i];
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
t[p] = s[p];
|
|
}
|
|
return t;
|
|
};
|
|
return __assign.apply(this, arguments);
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.cloneNode = exports.hasChildren = exports.isDocument = exports.isDirective = exports.isComment = exports.isText = exports.isCDATA = exports.isTag = exports.Element = exports.Document = exports.NodeWithChildren = exports.ProcessingInstruction = exports.Comment = exports.Text = exports.DataNode = exports.Node = void 0;
|
|
var domelementtype_1 = require("domelementtype");
|
|
var nodeTypes = new Map([
|
|
[domelementtype_1.ElementType.Tag, 1],
|
|
[domelementtype_1.ElementType.Script, 1],
|
|
[domelementtype_1.ElementType.Style, 1],
|
|
[domelementtype_1.ElementType.Directive, 1],
|
|
[domelementtype_1.ElementType.Text, 3],
|
|
[domelementtype_1.ElementType.CDATA, 4],
|
|
[domelementtype_1.ElementType.Comment, 8],
|
|
[domelementtype_1.ElementType.Root, 9],
|
|
]);
|
|
/**
|
|
* This object will be used as the prototype for Nodes when creating a
|
|
* DOM-Level-1-compliant structure.
|
|
*/
|
|
var Node = /** @class */ (function () {
|
|
/**
|
|
*
|
|
* @param type The type of the node.
|
|
*/
|
|
function Node(type) {
|
|
this.type = type;
|
|
/** Parent of the node */
|
|
this.parent = null;
|
|
/** Previous sibling */
|
|
this.prev = null;
|
|
/** Next sibling */
|
|
this.next = null;
|
|
/** The start index of the node. Requires `withStartIndices` on the handler to be `true. */
|
|
this.startIndex = null;
|
|
/** The end index of the node. Requires `withEndIndices` on the handler to be `true. */
|
|
this.endIndex = null;
|
|
}
|
|
Object.defineProperty(Node.prototype, "nodeType", {
|
|
// Read-only aliases
|
|
get: function () {
|
|
var _a;
|
|
return (_a = nodeTypes.get(this.type)) !== null && _a !== void 0 ? _a : 1;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(Node.prototype, "parentNode", {
|
|
// Read-write aliases for properties
|
|
get: function () {
|
|
return this.parent;
|
|
},
|
|
set: function (parent) {
|
|
this.parent = parent;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(Node.prototype, "previousSibling", {
|
|
get: function () {
|
|
return this.prev;
|
|
},
|
|
set: function (prev) {
|
|
this.prev = prev;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(Node.prototype, "nextSibling", {
|
|
get: function () {
|
|
return this.next;
|
|
},
|
|
set: function (next) {
|
|
this.next = next;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
/**
|
|
* Clone this node, and optionally its children.
|
|
*
|
|
* @param recursive Clone child nodes as well.
|
|
* @returns A clone of the node.
|
|
*/
|
|
Node.prototype.cloneNode = function (recursive) {
|
|
if (recursive === void 0) { recursive = false; }
|
|
return cloneNode(this, recursive);
|
|
};
|
|
return Node;
|
|
}());
|
|
exports.Node = Node;
|
|
var DataNode = /** @class */ (function (_super) {
|
|
__extends(DataNode, _super);
|
|
/**
|
|
* @param type The type of the node
|
|
* @param data The content of the data node
|
|
*/
|
|
function DataNode(type, data) {
|
|
var _this = _super.call(this, type) || this;
|
|
_this.data = data;
|
|
return _this;
|
|
}
|
|
Object.defineProperty(DataNode.prototype, "nodeValue", {
|
|
get: function () {
|
|
return this.data;
|
|
},
|
|
set: function (data) {
|
|
this.data = data;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
return DataNode;
|
|
}(Node));
|
|
exports.DataNode = DataNode;
|
|
var Text = /** @class */ (function (_super) {
|
|
__extends(Text, _super);
|
|
function Text(data) {
|
|
return _super.call(this, domelementtype_1.ElementType.Text, data) || this;
|
|
}
|
|
return Text;
|
|
}(DataNode));
|
|
exports.Text = Text;
|
|
var Comment = /** @class */ (function (_super) {
|
|
__extends(Comment, _super);
|
|
function Comment(data) {
|
|
return _super.call(this, domelementtype_1.ElementType.Comment, data) || this;
|
|
}
|
|
return Comment;
|
|
}(DataNode));
|
|
exports.Comment = Comment;
|
|
var ProcessingInstruction = /** @class */ (function (_super) {
|
|
__extends(ProcessingInstruction, _super);
|
|
function ProcessingInstruction(name, data) {
|
|
var _this = _super.call(this, domelementtype_1.ElementType.Directive, data) || this;
|
|
_this.name = name;
|
|
return _this;
|
|
}
|
|
return ProcessingInstruction;
|
|
}(DataNode));
|
|
exports.ProcessingInstruction = ProcessingInstruction;
|
|
/**
|
|
* A `Node` that can have children.
|
|
*/
|
|
var NodeWithChildren = /** @class */ (function (_super) {
|
|
__extends(NodeWithChildren, _super);
|
|
/**
|
|
* @param type Type of the node.
|
|
* @param children Children of the node. Only certain node types can have children.
|
|
*/
|
|
function NodeWithChildren(type, children) {
|
|
var _this = _super.call(this, type) || this;
|
|
_this.children = children;
|
|
return _this;
|
|
}
|
|
Object.defineProperty(NodeWithChildren.prototype, "firstChild", {
|
|
// Aliases
|
|
get: function () {
|
|
var _a;
|
|
return (_a = this.children[0]) !== null && _a !== void 0 ? _a : null;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(NodeWithChildren.prototype, "lastChild", {
|
|
get: function () {
|
|
return this.children.length > 0
|
|
? this.children[this.children.length - 1]
|
|
: null;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(NodeWithChildren.prototype, "childNodes", {
|
|
get: function () {
|
|
return this.children;
|
|
},
|
|
set: function (children) {
|
|
this.children = children;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
return NodeWithChildren;
|
|
}(Node));
|
|
exports.NodeWithChildren = NodeWithChildren;
|
|
var Document = /** @class */ (function (_super) {
|
|
__extends(Document, _super);
|
|
function Document(children) {
|
|
return _super.call(this, domelementtype_1.ElementType.Root, children) || this;
|
|
}
|
|
return Document;
|
|
}(NodeWithChildren));
|
|
exports.Document = Document;
|
|
var Element = /** @class */ (function (_super) {
|
|
__extends(Element, _super);
|
|
/**
|
|
* @param name Name of the tag, eg. `div`, `span`.
|
|
* @param attribs Object mapping attribute names to attribute values.
|
|
* @param children Children of the node.
|
|
*/
|
|
function Element(name, attribs, children, type) {
|
|
if (children === void 0) { children = []; }
|
|
if (type === void 0) { type = name === "script"
|
|
? domelementtype_1.ElementType.Script
|
|
: name === "style"
|
|
? domelementtype_1.ElementType.Style
|
|
: domelementtype_1.ElementType.Tag; }
|
|
var _this = _super.call(this, type, children) || this;
|
|
_this.name = name;
|
|
_this.attribs = attribs;
|
|
return _this;
|
|
}
|
|
Object.defineProperty(Element.prototype, "tagName", {
|
|
// DOM Level 1 aliases
|
|
get: function () {
|
|
return this.name;
|
|
},
|
|
set: function (name) {
|
|
this.name = name;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(Element.prototype, "attributes", {
|
|
get: function () {
|
|
var _this = this;
|
|
return Object.keys(this.attribs).map(function (name) {
|
|
var _a, _b;
|
|
return ({
|
|
name: name,
|
|
value: _this.attribs[name],
|
|
namespace: (_a = _this["x-attribsNamespace"]) === null || _a === void 0 ? void 0 : _a[name],
|
|
prefix: (_b = _this["x-attribsPrefix"]) === null || _b === void 0 ? void 0 : _b[name],
|
|
});
|
|
});
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
return Element;
|
|
}(NodeWithChildren));
|
|
exports.Element = Element;
|
|
/**
|
|
* @param node Node to check.
|
|
* @returns `true` if the node is a `Element`, `false` otherwise.
|
|
*/
|
|
function isTag(node) {
|
|
return domelementtype_1.isTag(node);
|
|
}
|
|
exports.isTag = isTag;
|
|
/**
|
|
* @param node Node to check.
|
|
* @returns `true` if the node has the type `CDATA`, `false` otherwise.
|
|
*/
|
|
function isCDATA(node) {
|
|
return node.type === domelementtype_1.ElementType.CDATA;
|
|
}
|
|
exports.isCDATA = isCDATA;
|
|
/**
|
|
* @param node Node to check.
|
|
* @returns `true` if the node has the type `Text`, `false` otherwise.
|
|
*/
|
|
function isText(node) {
|
|
return node.type === domelementtype_1.ElementType.Text;
|
|
}
|
|
exports.isText = isText;
|
|
/**
|
|
* @param node Node to check.
|
|
* @returns `true` if the node has the type `Comment`, `false` otherwise.
|
|
*/
|
|
function isComment(node) {
|
|
return node.type === domelementtype_1.ElementType.Comment;
|
|
}
|
|
exports.isComment = isComment;
|
|
/**
|
|
* @param node Node to check.
|
|
* @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise.
|
|
*/
|
|
function isDirective(node) {
|
|
return node.type === domelementtype_1.ElementType.Directive;
|
|
}
|
|
exports.isDirective = isDirective;
|
|
/**
|
|
* @param node Node to check.
|
|
* @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise.
|
|
*/
|
|
function isDocument(node) {
|
|
return node.type === domelementtype_1.ElementType.Root;
|
|
}
|
|
exports.isDocument = isDocument;
|
|
/**
|
|
* @param node Node to check.
|
|
* @returns `true` if the node is a `NodeWithChildren` (has children), `false` otherwise.
|
|
*/
|
|
function hasChildren(node) {
|
|
return Object.prototype.hasOwnProperty.call(node, "children");
|
|
}
|
|
exports.hasChildren = hasChildren;
|
|
/**
|
|
* Clone a node, and optionally its children.
|
|
*
|
|
* @param recursive Clone child nodes as well.
|
|
* @returns A clone of the node.
|
|
*/
|
|
function cloneNode(node, recursive) {
|
|
if (recursive === void 0) { recursive = false; }
|
|
var result;
|
|
if (isText(node)) {
|
|
result = new Text(node.data);
|
|
}
|
|
else if (isComment(node)) {
|
|
result = new Comment(node.data);
|
|
}
|
|
else if (isTag(node)) {
|
|
var children = recursive ? cloneChildren(node.children) : [];
|
|
var clone_1 = new Element(node.name, __assign({}, node.attribs), children);
|
|
children.forEach(function (child) { return (child.parent = clone_1); });
|
|
if (node["x-attribsNamespace"]) {
|
|
clone_1["x-attribsNamespace"] = __assign({}, node["x-attribsNamespace"]);
|
|
}
|
|
if (node["x-attribsPrefix"]) {
|
|
clone_1["x-attribsPrefix"] = __assign({}, node["x-attribsPrefix"]);
|
|
}
|
|
result = clone_1;
|
|
}
|
|
else if (isCDATA(node)) {
|
|
var children = recursive ? cloneChildren(node.children) : [];
|
|
var clone_2 = new NodeWithChildren(domelementtype_1.ElementType.CDATA, children);
|
|
children.forEach(function (child) { return (child.parent = clone_2); });
|
|
result = clone_2;
|
|
}
|
|
else if (isDocument(node)) {
|
|
var children = recursive ? cloneChildren(node.children) : [];
|
|
var clone_3 = new Document(children);
|
|
children.forEach(function (child) { return (child.parent = clone_3); });
|
|
if (node["x-mode"]) {
|
|
clone_3["x-mode"] = node["x-mode"];
|
|
}
|
|
result = clone_3;
|
|
}
|
|
else if (isDirective(node)) {
|
|
var instruction = new ProcessingInstruction(node.name, node.data);
|
|
if (node["x-name"] != null) {
|
|
instruction["x-name"] = node["x-name"];
|
|
instruction["x-publicId"] = node["x-publicId"];
|
|
instruction["x-systemId"] = node["x-systemId"];
|
|
}
|
|
result = instruction;
|
|
}
|
|
else {
|
|
throw new Error("Not implemented yet: " + node.type);
|
|
}
|
|
result.startIndex = node.startIndex;
|
|
result.endIndex = node.endIndex;
|
|
return result;
|
|
}
|
|
exports.cloneNode = cloneNode;
|
|
function cloneChildren(childs) {
|
|
var children = childs.map(function (child) { return cloneNode(child, true); });
|
|
for (var i = 1; i < children.length; i++) {
|
|
children[i].prev = children[i - 1];
|
|
children[i - 1].next = children[i];
|
|
}
|
|
return children;
|
|
}
|
|
|
|
},{"domelementtype":37}],40:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.uniqueSort = exports.compareDocumentPosition = exports.removeSubsets = void 0;
|
|
var domhandler_1 = require("domhandler");
|
|
/**
|
|
* Given an array of nodes, remove any member that is contained by another.
|
|
*
|
|
* @param nodes Nodes to filter.
|
|
* @returns Remaining nodes that aren't subtrees of each other.
|
|
*/
|
|
function removeSubsets(nodes) {
|
|
var idx = nodes.length;
|
|
/*
|
|
* Check if each node (or one of its ancestors) is already contained in the
|
|
* array.
|
|
*/
|
|
while (--idx >= 0) {
|
|
var node = nodes[idx];
|
|
/*
|
|
* Remove the node if it is not unique.
|
|
* We are going through the array from the end, so we only
|
|
* have to check nodes that preceed the node under consideration in the array.
|
|
*/
|
|
if (idx > 0 && nodes.lastIndexOf(node, idx - 1) >= 0) {
|
|
nodes.splice(idx, 1);
|
|
continue;
|
|
}
|
|
for (var ancestor = node.parent; ancestor; ancestor = ancestor.parent) {
|
|
if (nodes.includes(ancestor)) {
|
|
nodes.splice(idx, 1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return nodes;
|
|
}
|
|
exports.removeSubsets = removeSubsets;
|
|
/**
|
|
* Compare the position of one node against another node in any other document.
|
|
* The return value is a bitmask with the following values:
|
|
*
|
|
* Document order:
|
|
* > There is an ordering, document order, defined on all the nodes in the
|
|
* > document corresponding to the order in which the first character of the
|
|
* > XML representation of each node occurs in the XML representation of the
|
|
* > document after expansion of general entities. Thus, the document element
|
|
* > node will be the first node. Element nodes occur before their children.
|
|
* > Thus, document order orders element nodes in order of the occurrence of
|
|
* > their start-tag in the XML (after expansion of entities). The attribute
|
|
* > nodes of an element occur after the element and before its children. The
|
|
* > relative order of attribute nodes is implementation-dependent./
|
|
*
|
|
* Source:
|
|
* http://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-document-order
|
|
*
|
|
* @param nodeA The first node to use in the comparison
|
|
* @param nodeB The second node to use in the comparison
|
|
* @returns A bitmask describing the input nodes' relative position.
|
|
*
|
|
* See http://dom.spec.whatwg.org/#dom-node-comparedocumentposition for
|
|
* a description of these values.
|
|
*/
|
|
function compareDocumentPosition(nodeA, nodeB) {
|
|
var aParents = [];
|
|
var bParents = [];
|
|
if (nodeA === nodeB) {
|
|
return 0;
|
|
}
|
|
var current = domhandler_1.hasChildren(nodeA) ? nodeA : nodeA.parent;
|
|
while (current) {
|
|
aParents.unshift(current);
|
|
current = current.parent;
|
|
}
|
|
current = domhandler_1.hasChildren(nodeB) ? nodeB : nodeB.parent;
|
|
while (current) {
|
|
bParents.unshift(current);
|
|
current = current.parent;
|
|
}
|
|
var maxIdx = Math.min(aParents.length, bParents.length);
|
|
var idx = 0;
|
|
while (idx < maxIdx && aParents[idx] === bParents[idx]) {
|
|
idx++;
|
|
}
|
|
if (idx === 0) {
|
|
return 1 /* DISCONNECTED */;
|
|
}
|
|
var sharedParent = aParents[idx - 1];
|
|
var siblings = sharedParent.children;
|
|
var aSibling = aParents[idx];
|
|
var bSibling = bParents[idx];
|
|
if (siblings.indexOf(aSibling) > siblings.indexOf(bSibling)) {
|
|
if (sharedParent === nodeB) {
|
|
return 4 /* FOLLOWING */ | 16 /* CONTAINED_BY */;
|
|
}
|
|
return 4 /* FOLLOWING */;
|
|
}
|
|
if (sharedParent === nodeA) {
|
|
return 2 /* PRECEDING */ | 8 /* CONTAINS */;
|
|
}
|
|
return 2 /* PRECEDING */;
|
|
}
|
|
exports.compareDocumentPosition = compareDocumentPosition;
|
|
/**
|
|
* Sort an array of nodes based on their relative position in the document and
|
|
* remove any duplicate nodes. If the array contains nodes that do not belong
|
|
* to the same document, sort order is unspecified.
|
|
*
|
|
* @param nodes Array of DOM nodes.
|
|
* @returns Collection of unique nodes, sorted in document order.
|
|
*/
|
|
function uniqueSort(nodes) {
|
|
nodes = nodes.filter(function (node, i, arr) { return !arr.includes(node, i + 1); });
|
|
nodes.sort(function (a, b) {
|
|
var relative = compareDocumentPosition(a, b);
|
|
if (relative & 2 /* PRECEDING */) {
|
|
return -1;
|
|
}
|
|
else if (relative & 4 /* FOLLOWING */) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
});
|
|
return nodes;
|
|
}
|
|
exports.uniqueSort = uniqueSort;
|
|
|
|
},{"domhandler":38}],41:[function(require,module,exports){
|
|
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.hasChildren = exports.isDocument = exports.isComment = exports.isText = exports.isCDATA = exports.isTag = void 0;
|
|
__exportStar(require("./stringify"), exports);
|
|
__exportStar(require("./traversal"), exports);
|
|
__exportStar(require("./manipulation"), exports);
|
|
__exportStar(require("./querying"), exports);
|
|
__exportStar(require("./legacy"), exports);
|
|
__exportStar(require("./helpers"), exports);
|
|
var domhandler_1 = require("domhandler");
|
|
Object.defineProperty(exports, "isTag", { enumerable: true, get: function () { return domhandler_1.isTag; } });
|
|
Object.defineProperty(exports, "isCDATA", { enumerable: true, get: function () { return domhandler_1.isCDATA; } });
|
|
Object.defineProperty(exports, "isText", { enumerable: true, get: function () { return domhandler_1.isText; } });
|
|
Object.defineProperty(exports, "isComment", { enumerable: true, get: function () { return domhandler_1.isComment; } });
|
|
Object.defineProperty(exports, "isDocument", { enumerable: true, get: function () { return domhandler_1.isDocument; } });
|
|
Object.defineProperty(exports, "hasChildren", { enumerable: true, get: function () { return domhandler_1.hasChildren; } });
|
|
|
|
},{"./helpers":40,"./legacy":42,"./manipulation":43,"./querying":44,"./stringify":45,"./traversal":46,"domhandler":38}],42:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.getElementsByTagType = exports.getElementsByTagName = exports.getElementById = exports.getElements = exports.testElement = void 0;
|
|
var domhandler_1 = require("domhandler");
|
|
var querying_1 = require("./querying");
|
|
var Checks = {
|
|
tag_name: function (name) {
|
|
if (typeof name === "function") {
|
|
return function (elem) { return domhandler_1.isTag(elem) && name(elem.name); };
|
|
}
|
|
else if (name === "*") {
|
|
return domhandler_1.isTag;
|
|
}
|
|
return function (elem) { return domhandler_1.isTag(elem) && elem.name === name; };
|
|
},
|
|
tag_type: function (type) {
|
|
if (typeof type === "function") {
|
|
return function (elem) { return type(elem.type); };
|
|
}
|
|
return function (elem) { return elem.type === type; };
|
|
},
|
|
tag_contains: function (data) {
|
|
if (typeof data === "function") {
|
|
return function (elem) { return domhandler_1.isText(elem) && data(elem.data); };
|
|
}
|
|
return function (elem) { return domhandler_1.isText(elem) && elem.data === data; };
|
|
},
|
|
};
|
|
/**
|
|
* @param attrib Attribute to check.
|
|
* @param value Attribute value to look for.
|
|
* @returns A function to check whether the a node has an attribute with a particular value.
|
|
*/
|
|
function getAttribCheck(attrib, value) {
|
|
if (typeof value === "function") {
|
|
return function (elem) { return domhandler_1.isTag(elem) && value(elem.attribs[attrib]); };
|
|
}
|
|
return function (elem) { return domhandler_1.isTag(elem) && elem.attribs[attrib] === value; };
|
|
}
|
|
/**
|
|
* @param a First function to combine.
|
|
* @param b Second function to combine.
|
|
* @returns A function taking a node and returning `true` if either
|
|
* of the input functions returns `true` for the node.
|
|
*/
|
|
function combineFuncs(a, b) {
|
|
return function (elem) { return a(elem) || b(elem); };
|
|
}
|
|
/**
|
|
* @param options An object describing nodes to look for.
|
|
* @returns A function executing all checks in `options` and returning `true`
|
|
* if any of them match a node.
|
|
*/
|
|
function compileTest(options) {
|
|
var funcs = Object.keys(options).map(function (key) {
|
|
var value = options[key];
|
|
return key in Checks
|
|
? Checks[key](value)
|
|
: getAttribCheck(key, value);
|
|
});
|
|
return funcs.length === 0 ? null : funcs.reduce(combineFuncs);
|
|
}
|
|
/**
|
|
* @param options An object describing nodes to look for.
|
|
* @param node The element to test.
|
|
* @returns Whether the element matches the description in `options`.
|
|
*/
|
|
function testElement(options, node) {
|
|
var test = compileTest(options);
|
|
return test ? test(node) : true;
|
|
}
|
|
exports.testElement = testElement;
|
|
/**
|
|
* @param options An object describing nodes to look for.
|
|
* @param nodes Nodes to search through.
|
|
* @param recurse Also consider child nodes.
|
|
* @param limit Maximum number of nodes to return.
|
|
* @returns All nodes that match `options`.
|
|
*/
|
|
function getElements(options, nodes, recurse, limit) {
|
|
if (limit === void 0) { limit = Infinity; }
|
|
var test = compileTest(options);
|
|
return test ? querying_1.filter(test, nodes, recurse, limit) : [];
|
|
}
|
|
exports.getElements = getElements;
|
|
/**
|
|
* @param id The unique ID attribute value to look for.
|
|
* @param nodes Nodes to search through.
|
|
* @param recurse Also consider child nodes.
|
|
* @returns The node with the supplied ID.
|
|
*/
|
|
function getElementById(id, nodes, recurse) {
|
|
if (recurse === void 0) { recurse = true; }
|
|
if (!Array.isArray(nodes))
|
|
nodes = [nodes];
|
|
return querying_1.findOne(getAttribCheck("id", id), nodes, recurse);
|
|
}
|
|
exports.getElementById = getElementById;
|
|
/**
|
|
* @param tagName Tag name to search for.
|
|
* @param nodes Nodes to search through.
|
|
* @param recurse Also consider child nodes.
|
|
* @param limit Maximum number of nodes to return.
|
|
* @returns All nodes with the supplied `tagName`.
|
|
*/
|
|
function getElementsByTagName(tagName, nodes, recurse, limit) {
|
|
if (recurse === void 0) { recurse = true; }
|
|
if (limit === void 0) { limit = Infinity; }
|
|
return querying_1.filter(Checks.tag_name(tagName), nodes, recurse, limit);
|
|
}
|
|
exports.getElementsByTagName = getElementsByTagName;
|
|
/**
|
|
* @param type Element type to look for.
|
|
* @param nodes Nodes to search through.
|
|
* @param recurse Also consider child nodes.
|
|
* @param limit Maximum number of nodes to return.
|
|
* @returns All nodes with the supplied `type`.
|
|
*/
|
|
function getElementsByTagType(type, nodes, recurse, limit) {
|
|
if (recurse === void 0) { recurse = true; }
|
|
if (limit === void 0) { limit = Infinity; }
|
|
return querying_1.filter(Checks.tag_type(type), nodes, recurse, limit);
|
|
}
|
|
exports.getElementsByTagType = getElementsByTagType;
|
|
|
|
},{"./querying":44,"domhandler":38}],43:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.prepend = exports.prependChild = exports.append = exports.appendChild = exports.replaceElement = exports.removeElement = void 0;
|
|
/**
|
|
* Remove an element from the dom
|
|
*
|
|
* @param elem The element to be removed
|
|
*/
|
|
function removeElement(elem) {
|
|
if (elem.prev)
|
|
elem.prev.next = elem.next;
|
|
if (elem.next)
|
|
elem.next.prev = elem.prev;
|
|
if (elem.parent) {
|
|
var childs = elem.parent.children;
|
|
childs.splice(childs.lastIndexOf(elem), 1);
|
|
}
|
|
}
|
|
exports.removeElement = removeElement;
|
|
/**
|
|
* Replace an element in the dom
|
|
*
|
|
* @param elem The element to be replaced
|
|
* @param replacement The element to be added
|
|
*/
|
|
function replaceElement(elem, replacement) {
|
|
var prev = (replacement.prev = elem.prev);
|
|
if (prev) {
|
|
prev.next = replacement;
|
|
}
|
|
var next = (replacement.next = elem.next);
|
|
if (next) {
|
|
next.prev = replacement;
|
|
}
|
|
var parent = (replacement.parent = elem.parent);
|
|
if (parent) {
|
|
var childs = parent.children;
|
|
childs[childs.lastIndexOf(elem)] = replacement;
|
|
}
|
|
}
|
|
exports.replaceElement = replaceElement;
|
|
/**
|
|
* Append a child to an element.
|
|
*
|
|
* @param elem The element to append to.
|
|
* @param child The element to be added as a child.
|
|
*/
|
|
function appendChild(elem, child) {
|
|
removeElement(child);
|
|
child.next = null;
|
|
child.parent = elem;
|
|
if (elem.children.push(child) > 1) {
|
|
var sibling = elem.children[elem.children.length - 2];
|
|
sibling.next = child;
|
|
child.prev = sibling;
|
|
}
|
|
else {
|
|
child.prev = null;
|
|
}
|
|
}
|
|
exports.appendChild = appendChild;
|
|
/**
|
|
* Append an element after another.
|
|
*
|
|
* @param elem The element to append after.
|
|
* @param next The element be added.
|
|
*/
|
|
function append(elem, next) {
|
|
removeElement(next);
|
|
var parent = elem.parent;
|
|
var currNext = elem.next;
|
|
next.next = currNext;
|
|
next.prev = elem;
|
|
elem.next = next;
|
|
next.parent = parent;
|
|
if (currNext) {
|
|
currNext.prev = next;
|
|
if (parent) {
|
|
var childs = parent.children;
|
|
childs.splice(childs.lastIndexOf(currNext), 0, next);
|
|
}
|
|
}
|
|
else if (parent) {
|
|
parent.children.push(next);
|
|
}
|
|
}
|
|
exports.append = append;
|
|
/**
|
|
* Prepend a child to an element.
|
|
*
|
|
* @param elem The element to prepend before.
|
|
* @param child The element to be added as a child.
|
|
*/
|
|
function prependChild(elem, child) {
|
|
removeElement(child);
|
|
child.parent = elem;
|
|
child.prev = null;
|
|
if (elem.children.unshift(child) !== 1) {
|
|
var sibling = elem.children[1];
|
|
sibling.prev = child;
|
|
child.next = sibling;
|
|
}
|
|
else {
|
|
child.next = null;
|
|
}
|
|
}
|
|
exports.prependChild = prependChild;
|
|
/**
|
|
* Prepend an element before another.
|
|
*
|
|
* @param elem The element to prepend before.
|
|
* @param prev The element be added.
|
|
*/
|
|
function prepend(elem, prev) {
|
|
removeElement(prev);
|
|
var parent = elem.parent;
|
|
if (parent) {
|
|
var childs = parent.children;
|
|
childs.splice(childs.indexOf(elem), 0, prev);
|
|
}
|
|
if (elem.prev) {
|
|
elem.prev.next = prev;
|
|
}
|
|
prev.parent = parent;
|
|
prev.prev = elem.prev;
|
|
prev.next = elem;
|
|
elem.prev = prev;
|
|
}
|
|
exports.prepend = prepend;
|
|
|
|
},{}],44:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.findAll = exports.existsOne = exports.findOne = exports.findOneChild = exports.find = exports.filter = void 0;
|
|
var domhandler_1 = require("domhandler");
|
|
/**
|
|
* Search a node and its children for nodes passing a test function.
|
|
*
|
|
* @param test Function to test nodes on.
|
|
* @param node Node to search. Will be included in the result set if it matches.
|
|
* @param recurse Also consider child nodes.
|
|
* @param limit Maximum number of nodes to return.
|
|
* @returns All nodes passing `test`.
|
|
*/
|
|
function filter(test, node, recurse, limit) {
|
|
if (recurse === void 0) { recurse = true; }
|
|
if (limit === void 0) { limit = Infinity; }
|
|
if (!Array.isArray(node))
|
|
node = [node];
|
|
return find(test, node, recurse, limit);
|
|
}
|
|
exports.filter = filter;
|
|
/**
|
|
* Search an array of node and its children for nodes passing a test function.
|
|
*
|
|
* @param test Function to test nodes on.
|
|
* @param nodes Array of nodes to search.
|
|
* @param recurse Also consider child nodes.
|
|
* @param limit Maximum number of nodes to return.
|
|
* @returns All nodes passing `test`.
|
|
*/
|
|
function find(test, nodes, recurse, limit) {
|
|
var result = [];
|
|
for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
|
|
var elem = nodes_1[_i];
|
|
if (test(elem)) {
|
|
result.push(elem);
|
|
if (--limit <= 0)
|
|
break;
|
|
}
|
|
if (recurse && domhandler_1.hasChildren(elem) && elem.children.length > 0) {
|
|
var children = find(test, elem.children, recurse, limit);
|
|
result.push.apply(result, children);
|
|
limit -= children.length;
|
|
if (limit <= 0)
|
|
break;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
exports.find = find;
|
|
/**
|
|
* Finds the first element inside of an array that matches a test function.
|
|
*
|
|
* @param test Function to test nodes on.
|
|
* @param nodes Array of nodes to search.
|
|
* @returns The first node in the array that passes `test`.
|
|
*/
|
|
function findOneChild(test, nodes) {
|
|
return nodes.find(test);
|
|
}
|
|
exports.findOneChild = findOneChild;
|
|
/**
|
|
* Finds one element in a tree that passes a test.
|
|
*
|
|
* @param test Function to test nodes on.
|
|
* @param nodes Array of nodes to search.
|
|
* @param recurse Also consider child nodes.
|
|
* @returns The first child node that passes `test`.
|
|
*/
|
|
function findOne(test, nodes, recurse) {
|
|
if (recurse === void 0) { recurse = true; }
|
|
var elem = null;
|
|
for (var i = 0; i < nodes.length && !elem; i++) {
|
|
var checked = nodes[i];
|
|
if (!domhandler_1.isTag(checked)) {
|
|
continue;
|
|
}
|
|
else if (test(checked)) {
|
|
elem = checked;
|
|
}
|
|
else if (recurse && checked.children.length > 0) {
|
|
elem = findOne(test, checked.children);
|
|
}
|
|
}
|
|
return elem;
|
|
}
|
|
exports.findOne = findOne;
|
|
/**
|
|
* @param test Function to test nodes on.
|
|
* @param nodes Array of nodes to search.
|
|
* @returns Whether a tree of nodes contains at least one node passing a test.
|
|
*/
|
|
function existsOne(test, nodes) {
|
|
return nodes.some(function (checked) {
|
|
return domhandler_1.isTag(checked) &&
|
|
(test(checked) ||
|
|
(checked.children.length > 0 &&
|
|
existsOne(test, checked.children)));
|
|
});
|
|
}
|
|
exports.existsOne = existsOne;
|
|
/**
|
|
* Search and array of nodes and its children for nodes passing a test function.
|
|
*
|
|
* Same as `find`, only with less options, leading to reduced complexity.
|
|
*
|
|
* @param test Function to test nodes on.
|
|
* @param nodes Array of nodes to search.
|
|
* @returns All nodes passing `test`.
|
|
*/
|
|
function findAll(test, nodes) {
|
|
var _a;
|
|
var result = [];
|
|
var stack = nodes.filter(domhandler_1.isTag);
|
|
var elem;
|
|
while ((elem = stack.shift())) {
|
|
var children = (_a = elem.children) === null || _a === void 0 ? void 0 : _a.filter(domhandler_1.isTag);
|
|
if (children && children.length > 0) {
|
|
stack.unshift.apply(stack, children);
|
|
}
|
|
if (test(elem))
|
|
result.push(elem);
|
|
}
|
|
return result;
|
|
}
|
|
exports.findAll = findAll;
|
|
|
|
},{"domhandler":38}],45:[function(require,module,exports){
|
|
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.getText = exports.getInnerHTML = exports.getOuterHTML = void 0;
|
|
var domhandler_1 = require("domhandler");
|
|
var dom_serializer_1 = __importDefault(require("dom-serializer"));
|
|
/**
|
|
* @param node Node to get the outer HTML of.
|
|
* @param options Options for serialization.
|
|
* @deprecated Use the `dom-serializer` module directly.
|
|
* @returns `node`'s outer HTML.
|
|
*/
|
|
function getOuterHTML(node, options) {
|
|
return dom_serializer_1.default(node, options);
|
|
}
|
|
exports.getOuterHTML = getOuterHTML;
|
|
/**
|
|
* @param node Node to get the inner HTML of.
|
|
* @param options Options for serialization.
|
|
* @deprecated Use the `dom-serializer` module directly.
|
|
* @returns `node`'s inner HTML.
|
|
*/
|
|
function getInnerHTML(node, options) {
|
|
return domhandler_1.hasChildren(node)
|
|
? node.children.map(function (node) { return getOuterHTML(node, options); }).join("")
|
|
: "";
|
|
}
|
|
exports.getInnerHTML = getInnerHTML;
|
|
/**
|
|
* Get a node's inner text.
|
|
*
|
|
* @param node Node to get the inner text of.
|
|
* @returns `node`'s inner text.
|
|
*/
|
|
function getText(node) {
|
|
if (Array.isArray(node))
|
|
return node.map(getText).join("");
|
|
if (domhandler_1.isTag(node))
|
|
return node.name === "br" ? "\n" : getText(node.children);
|
|
if (domhandler_1.isCDATA(node))
|
|
return getText(node.children);
|
|
if (domhandler_1.isText(node))
|
|
return node.data;
|
|
return "";
|
|
}
|
|
exports.getText = getText;
|
|
|
|
},{"dom-serializer":36,"domhandler":38}],46:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.prevElementSibling = exports.nextElementSibling = exports.getName = exports.hasAttrib = exports.getAttributeValue = exports.getSiblings = exports.getParent = exports.getChildren = void 0;
|
|
var domhandler_1 = require("domhandler");
|
|
var emptyArray = [];
|
|
/**
|
|
* Get a node's children.
|
|
*
|
|
* @param elem Node to get the children of.
|
|
* @returns `elem`'s children, or an empty array.
|
|
*/
|
|
function getChildren(elem) {
|
|
var _a;
|
|
return (_a = elem.children) !== null && _a !== void 0 ? _a : emptyArray;
|
|
}
|
|
exports.getChildren = getChildren;
|
|
/**
|
|
* Get a node's parent.
|
|
*
|
|
* @param elem Node to get the parent of.
|
|
* @returns `elem`'s parent node.
|
|
*/
|
|
function getParent(elem) {
|
|
return elem.parent || null;
|
|
}
|
|
exports.getParent = getParent;
|
|
/**
|
|
* Gets an elements siblings, including the element itself.
|
|
*
|
|
* Attempts to get the children through the element's parent first.
|
|
* If we don't have a parent (the element is a root node),
|
|
* we walk the element's `prev` & `next` to get all remaining nodes.
|
|
*
|
|
* @param elem Element to get the siblings of.
|
|
* @returns `elem`'s siblings.
|
|
*/
|
|
function getSiblings(elem) {
|
|
var _a, _b;
|
|
var parent = getParent(elem);
|
|
if (parent != null)
|
|
return getChildren(parent);
|
|
var siblings = [elem];
|
|
var prev = elem.prev, next = elem.next;
|
|
while (prev != null) {
|
|
siblings.unshift(prev);
|
|
(_a = prev, prev = _a.prev);
|
|
}
|
|
while (next != null) {
|
|
siblings.push(next);
|
|
(_b = next, next = _b.next);
|
|
}
|
|
return siblings;
|
|
}
|
|
exports.getSiblings = getSiblings;
|
|
/**
|
|
* Gets an attribute from an element.
|
|
*
|
|
* @param elem Element to check.
|
|
* @param name Attribute name to retrieve.
|
|
* @returns The element's attribute value, or `undefined`.
|
|
*/
|
|
function getAttributeValue(elem, name) {
|
|
var _a;
|
|
return (_a = elem.attribs) === null || _a === void 0 ? void 0 : _a[name];
|
|
}
|
|
exports.getAttributeValue = getAttributeValue;
|
|
/**
|
|
* Checks whether an element has an attribute.
|
|
*
|
|
* @param elem Element to check.
|
|
* @param name Attribute name to look for.
|
|
* @returns Returns whether `elem` has the attribute `name`.
|
|
*/
|
|
function hasAttrib(elem, name) {
|
|
return (elem.attribs != null &&
|
|
Object.prototype.hasOwnProperty.call(elem.attribs, name) &&
|
|
elem.attribs[name] != null);
|
|
}
|
|
exports.hasAttrib = hasAttrib;
|
|
/**
|
|
* Get the tag name of an element.
|
|
*
|
|
* @param elem The element to get the name for.
|
|
* @returns The tag name of `elem`.
|
|
*/
|
|
function getName(elem) {
|
|
return elem.name;
|
|
}
|
|
exports.getName = getName;
|
|
/**
|
|
* Returns the next element sibling of a node.
|
|
*
|
|
* @param elem The element to get the next sibling of.
|
|
* @returns `elem`'s next sibling that is a tag.
|
|
*/
|
|
function nextElementSibling(elem) {
|
|
var _a;
|
|
var next = elem.next;
|
|
while (next !== null && !domhandler_1.isTag(next))
|
|
(_a = next, next = _a.next);
|
|
return next;
|
|
}
|
|
exports.nextElementSibling = nextElementSibling;
|
|
/**
|
|
* Returns the previous element sibling of a node.
|
|
*
|
|
* @param elem The element to get the previous sibling of.
|
|
* @returns `elem`'s previous sibling that is a tag.
|
|
*/
|
|
function prevElementSibling(elem) {
|
|
var _a;
|
|
var prev = elem.prev;
|
|
while (prev !== null && !domhandler_1.isTag(prev))
|
|
(_a = prev, prev = _a.prev);
|
|
return prev;
|
|
}
|
|
exports.prevElementSibling = prevElementSibling;
|
|
|
|
},{"domhandler":38}],47:[function(require,module,exports){
|
|
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.decodeHTML = exports.decodeHTMLStrict = exports.decodeXML = void 0;
|
|
var entities_json_1 = __importDefault(require("./maps/entities.json"));
|
|
var legacy_json_1 = __importDefault(require("./maps/legacy.json"));
|
|
var xml_json_1 = __importDefault(require("./maps/xml.json"));
|
|
var decode_codepoint_1 = __importDefault(require("./decode_codepoint"));
|
|
var strictEntityRe = /&(?:[a-zA-Z0-9]+|#[xX][\da-fA-F]+|#\d+);/g;
|
|
exports.decodeXML = getStrictDecoder(xml_json_1.default);
|
|
exports.decodeHTMLStrict = getStrictDecoder(entities_json_1.default);
|
|
function getStrictDecoder(map) {
|
|
var replace = getReplacer(map);
|
|
return function (str) { return String(str).replace(strictEntityRe, replace); };
|
|
}
|
|
var sorter = function (a, b) { return (a < b ? 1 : -1); };
|
|
exports.decodeHTML = (function () {
|
|
var legacy = Object.keys(legacy_json_1.default).sort(sorter);
|
|
var keys = Object.keys(entities_json_1.default).sort(sorter);
|
|
for (var i = 0, j = 0; i < keys.length; i++) {
|
|
if (legacy[j] === keys[i]) {
|
|
keys[i] += ";?";
|
|
j++;
|
|
}
|
|
else {
|
|
keys[i] += ";";
|
|
}
|
|
}
|
|
var re = new RegExp("&(?:" + keys.join("|") + "|#[xX][\\da-fA-F]+;?|#\\d+;?)", "g");
|
|
var replace = getReplacer(entities_json_1.default);
|
|
function replacer(str) {
|
|
if (str.substr(-1) !== ";")
|
|
str += ";";
|
|
return replace(str);
|
|
}
|
|
// TODO consider creating a merged map
|
|
return function (str) { return String(str).replace(re, replacer); };
|
|
})();
|
|
function getReplacer(map) {
|
|
return function replace(str) {
|
|
if (str.charAt(1) === "#") {
|
|
var secondChar = str.charAt(2);
|
|
if (secondChar === "X" || secondChar === "x") {
|
|
return decode_codepoint_1.default(parseInt(str.substr(3), 16));
|
|
}
|
|
return decode_codepoint_1.default(parseInt(str.substr(2), 10));
|
|
}
|
|
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
return map[str.slice(1, -1)] || str;
|
|
};
|
|
}
|
|
|
|
},{"./decode_codepoint":48,"./maps/entities.json":52,"./maps/legacy.json":53,"./maps/xml.json":54}],48:[function(require,module,exports){
|
|
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
var decode_json_1 = __importDefault(require("./maps/decode.json"));
|
|
// Adapted from https://github.com/mathiasbynens/he/blob/master/src/he.js#L94-L119
|
|
var fromCodePoint =
|
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
String.fromCodePoint ||
|
|
function (codePoint) {
|
|
var output = "";
|
|
if (codePoint > 0xffff) {
|
|
codePoint -= 0x10000;
|
|
output += String.fromCharCode(((codePoint >>> 10) & 0x3ff) | 0xd800);
|
|
codePoint = 0xdc00 | (codePoint & 0x3ff);
|
|
}
|
|
output += String.fromCharCode(codePoint);
|
|
return output;
|
|
};
|
|
function decodeCodePoint(codePoint) {
|
|
if ((codePoint >= 0xd800 && codePoint <= 0xdfff) || codePoint > 0x10ffff) {
|
|
return "\uFFFD";
|
|
}
|
|
if (codePoint in decode_json_1.default) {
|
|
codePoint = decode_json_1.default[codePoint];
|
|
}
|
|
return fromCodePoint(codePoint);
|
|
}
|
|
exports.default = decodeCodePoint;
|
|
|
|
},{"./maps/decode.json":51}],49:[function(require,module,exports){
|
|
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.escapeUTF8 = exports.escape = exports.encodeNonAsciiHTML = exports.encodeHTML = exports.encodeXML = void 0;
|
|
var xml_json_1 = __importDefault(require("./maps/xml.json"));
|
|
var inverseXML = getInverseObj(xml_json_1.default);
|
|
var xmlReplacer = getInverseReplacer(inverseXML);
|
|
/**
|
|
* Encodes all non-ASCII characters, as well as characters not valid in XML
|
|
* documents using XML entities.
|
|
*
|
|
* If a character has no equivalent entity, a
|
|
* numeric hexadecimal reference (eg. `ü`) will be used.
|
|
*/
|
|
exports.encodeXML = getASCIIEncoder(inverseXML);
|
|
var entities_json_1 = __importDefault(require("./maps/entities.json"));
|
|
var inverseHTML = getInverseObj(entities_json_1.default);
|
|
var htmlReplacer = getInverseReplacer(inverseHTML);
|
|
/**
|
|
* Encodes all entities and non-ASCII characters in the input.
|
|
*
|
|
* This includes characters that are valid ASCII characters in HTML documents.
|
|
* For example `#` will be encoded as `#`. To get a more compact output,
|
|
* consider using the `encodeNonAsciiHTML` function.
|
|
*
|
|
* If a character has no equivalent entity, a
|
|
* numeric hexadecimal reference (eg. `ü`) will be used.
|
|
*/
|
|
exports.encodeHTML = getInverse(inverseHTML, htmlReplacer);
|
|
/**
|
|
* Encodes all non-ASCII characters, as well as characters not valid in HTML
|
|
* documents using HTML entities.
|
|
*
|
|
* If a character has no equivalent entity, a
|
|
* numeric hexadecimal reference (eg. `ü`) will be used.
|
|
*/
|
|
exports.encodeNonAsciiHTML = getASCIIEncoder(inverseHTML);
|
|
function getInverseObj(obj) {
|
|
return Object.keys(obj)
|
|
.sort()
|
|
.reduce(function (inverse, name) {
|
|
inverse[obj[name]] = "&" + name + ";";
|
|
return inverse;
|
|
}, {});
|
|
}
|
|
function getInverseReplacer(inverse) {
|
|
var single = [];
|
|
var multiple = [];
|
|
for (var _i = 0, _a = Object.keys(inverse); _i < _a.length; _i++) {
|
|
var k = _a[_i];
|
|
if (k.length === 1) {
|
|
// Add value to single array
|
|
single.push("\\" + k);
|
|
}
|
|
else {
|
|
// Add value to multiple array
|
|
multiple.push(k);
|
|
}
|
|
}
|
|
// Add ranges to single characters.
|
|
single.sort();
|
|
for (var start = 0; start < single.length - 1; start++) {
|
|
// Find the end of a run of characters
|
|
var end = start;
|
|
while (end < single.length - 1 &&
|
|
single[end].charCodeAt(1) + 1 === single[end + 1].charCodeAt(1)) {
|
|
end += 1;
|
|
}
|
|
var count = 1 + end - start;
|
|
// We want to replace at least three characters
|
|
if (count < 3)
|
|
continue;
|
|
single.splice(start, count, single[start] + "-" + single[end]);
|
|
}
|
|
multiple.unshift("[" + single.join("") + "]");
|
|
return new RegExp(multiple.join("|"), "g");
|
|
}
|
|
// /[^\0-\x7F]/gu
|
|
var reNonASCII = /(?:[\x80-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g;
|
|
var getCodePoint =
|
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
String.prototype.codePointAt != null
|
|
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
function (str) { return str.codePointAt(0); }
|
|
: // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
|
|
function (c) {
|
|
return (c.charCodeAt(0) - 0xd800) * 0x400 +
|
|
c.charCodeAt(1) -
|
|
0xdc00 +
|
|
0x10000;
|
|
};
|
|
function singleCharReplacer(c) {
|
|
return "&#x" + (c.length > 1 ? getCodePoint(c) : c.charCodeAt(0))
|
|
.toString(16)
|
|
.toUpperCase() + ";";
|
|
}
|
|
function getInverse(inverse, re) {
|
|
return function (data) {
|
|
return data
|
|
.replace(re, function (name) { return inverse[name]; })
|
|
.replace(reNonASCII, singleCharReplacer);
|
|
};
|
|
}
|
|
var reEscapeChars = new RegExp(xmlReplacer.source + "|" + reNonASCII.source, "g");
|
|
/**
|
|
* Encodes all non-ASCII characters, as well as characters not valid in XML
|
|
* documents using numeric hexadecimal reference (eg. `ü`).
|
|
*
|
|
* Have a look at `escapeUTF8` if you want a more concise output at the expense
|
|
* of reduced transportability.
|
|
*
|
|
* @param data String to escape.
|
|
*/
|
|
function escape(data) {
|
|
return data.replace(reEscapeChars, singleCharReplacer);
|
|
}
|
|
exports.escape = escape;
|
|
/**
|
|
* Encodes all characters not valid in XML documents using numeric hexadecimal
|
|
* reference (eg. `ü`).
|
|
*
|
|
* Note that the output will be character-set dependent.
|
|
*
|
|
* @param data String to escape.
|
|
*/
|
|
function escapeUTF8(data) {
|
|
return data.replace(xmlReplacer, singleCharReplacer);
|
|
}
|
|
exports.escapeUTF8 = escapeUTF8;
|
|
function getASCIIEncoder(obj) {
|
|
return function (data) {
|
|
return data.replace(reEscapeChars, function (c) { return obj[c] || singleCharReplacer(c); });
|
|
};
|
|
}
|
|
|
|
},{"./maps/entities.json":52,"./maps/xml.json":54}],50:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.decodeXMLStrict = exports.decodeHTML5Strict = exports.decodeHTML4Strict = exports.decodeHTML5 = exports.decodeHTML4 = exports.decodeHTMLStrict = exports.decodeHTML = exports.decodeXML = exports.encodeHTML5 = exports.encodeHTML4 = exports.escapeUTF8 = exports.escape = exports.encodeNonAsciiHTML = exports.encodeHTML = exports.encodeXML = exports.encode = exports.decodeStrict = exports.decode = void 0;
|
|
var decode_1 = require("./decode");
|
|
var encode_1 = require("./encode");
|
|
/**
|
|
* Decodes a string with entities.
|
|
*
|
|
* @param data String to decode.
|
|
* @param level Optional level to decode at. 0 = XML, 1 = HTML. Default is 0.
|
|
* @deprecated Use `decodeXML` or `decodeHTML` directly.
|
|
*/
|
|
function decode(data, level) {
|
|
return (!level || level <= 0 ? decode_1.decodeXML : decode_1.decodeHTML)(data);
|
|
}
|
|
exports.decode = decode;
|
|
/**
|
|
* Decodes a string with entities. Does not allow missing trailing semicolons for entities.
|
|
*
|
|
* @param data String to decode.
|
|
* @param level Optional level to decode at. 0 = XML, 1 = HTML. Default is 0.
|
|
* @deprecated Use `decodeHTMLStrict` or `decodeXML` directly.
|
|
*/
|
|
function decodeStrict(data, level) {
|
|
return (!level || level <= 0 ? decode_1.decodeXML : decode_1.decodeHTMLStrict)(data);
|
|
}
|
|
exports.decodeStrict = decodeStrict;
|
|
/**
|
|
* Encodes a string with entities.
|
|
*
|
|
* @param data String to encode.
|
|
* @param level Optional level to encode at. 0 = XML, 1 = HTML. Default is 0.
|
|
* @deprecated Use `encodeHTML`, `encodeXML` or `encodeNonAsciiHTML` directly.
|
|
*/
|
|
function encode(data, level) {
|
|
return (!level || level <= 0 ? encode_1.encodeXML : encode_1.encodeHTML)(data);
|
|
}
|
|
exports.encode = encode;
|
|
var encode_2 = require("./encode");
|
|
Object.defineProperty(exports, "encodeXML", { enumerable: true, get: function () { return encode_2.encodeXML; } });
|
|
Object.defineProperty(exports, "encodeHTML", { enumerable: true, get: function () { return encode_2.encodeHTML; } });
|
|
Object.defineProperty(exports, "encodeNonAsciiHTML", { enumerable: true, get: function () { return encode_2.encodeNonAsciiHTML; } });
|
|
Object.defineProperty(exports, "escape", { enumerable: true, get: function () { return encode_2.escape; } });
|
|
Object.defineProperty(exports, "escapeUTF8", { enumerable: true, get: function () { return encode_2.escapeUTF8; } });
|
|
// Legacy aliases (deprecated)
|
|
Object.defineProperty(exports, "encodeHTML4", { enumerable: true, get: function () { return encode_2.encodeHTML; } });
|
|
Object.defineProperty(exports, "encodeHTML5", { enumerable: true, get: function () { return encode_2.encodeHTML; } });
|
|
var decode_2 = require("./decode");
|
|
Object.defineProperty(exports, "decodeXML", { enumerable: true, get: function () { return decode_2.decodeXML; } });
|
|
Object.defineProperty(exports, "decodeHTML", { enumerable: true, get: function () { return decode_2.decodeHTML; } });
|
|
Object.defineProperty(exports, "decodeHTMLStrict", { enumerable: true, get: function () { return decode_2.decodeHTMLStrict; } });
|
|
// Legacy aliases (deprecated)
|
|
Object.defineProperty(exports, "decodeHTML4", { enumerable: true, get: function () { return decode_2.decodeHTML; } });
|
|
Object.defineProperty(exports, "decodeHTML5", { enumerable: true, get: function () { return decode_2.decodeHTML; } });
|
|
Object.defineProperty(exports, "decodeHTML4Strict", { enumerable: true, get: function () { return decode_2.decodeHTMLStrict; } });
|
|
Object.defineProperty(exports, "decodeHTML5Strict", { enumerable: true, get: function () { return decode_2.decodeHTMLStrict; } });
|
|
Object.defineProperty(exports, "decodeXMLStrict", { enumerable: true, get: function () { return decode_2.decodeXML; } });
|
|
|
|
},{"./decode":47,"./encode":49}],51:[function(require,module,exports){
|
|
module.exports={"0":65533,"128":8364,"130":8218,"131":402,"132":8222,"133":8230,"134":8224,"135":8225,"136":710,"137":8240,"138":352,"139":8249,"140":338,"142":381,"145":8216,"146":8217,"147":8220,"148":8221,"149":8226,"150":8211,"151":8212,"152":732,"153":8482,"154":353,"155":8250,"156":339,"158":382,"159":376}
|
|
|
|
},{}],52:[function(require,module,exports){
|
|
module.exports={"Aacute":"Á","aacute":"á","Abreve":"Ă","abreve":"ă","ac":"∾","acd":"∿","acE":"∾̳","Acirc":"Â","acirc":"â","acute":"´","Acy":"А","acy":"а","AElig":"Æ","aelig":"æ","af":"","Afr":"𝔄","afr":"𝔞","Agrave":"À","agrave":"à","alefsym":"ℵ","aleph":"ℵ","Alpha":"Α","alpha":"α","Amacr":"Ā","amacr":"ā","amalg":"⨿","amp":"&","AMP":"&","andand":"⩕","And":"⩓","and":"∧","andd":"⩜","andslope":"⩘","andv":"⩚","ang":"∠","ange":"⦤","angle":"∠","angmsdaa":"⦨","angmsdab":"⦩","angmsdac":"⦪","angmsdad":"⦫","angmsdae":"⦬","angmsdaf":"⦭","angmsdag":"⦮","angmsdah":"⦯","angmsd":"∡","angrt":"∟","angrtvb":"⊾","angrtvbd":"⦝","angsph":"∢","angst":"Å","angzarr":"⍼","Aogon":"Ą","aogon":"ą","Aopf":"𝔸","aopf":"𝕒","apacir":"⩯","ap":"≈","apE":"⩰","ape":"≊","apid":"≋","apos":"'","ApplyFunction":"","approx":"≈","approxeq":"≊","Aring":"Å","aring":"å","Ascr":"𝒜","ascr":"𝒶","Assign":"≔","ast":"*","asymp":"≈","asympeq":"≍","Atilde":"Ã","atilde":"ã","Auml":"Ä","auml":"ä","awconint":"∳","awint":"⨑","backcong":"≌","backepsilon":"϶","backprime":"‵","backsim":"∽","backsimeq":"⋍","Backslash":"∖","Barv":"⫧","barvee":"⊽","barwed":"⌅","Barwed":"⌆","barwedge":"⌅","bbrk":"⎵","bbrktbrk":"⎶","bcong":"≌","Bcy":"Б","bcy":"б","bdquo":"„","becaus":"∵","because":"∵","Because":"∵","bemptyv":"⦰","bepsi":"϶","bernou":"ℬ","Bernoullis":"ℬ","Beta":"Β","beta":"β","beth":"ℶ","between":"≬","Bfr":"𝔅","bfr":"𝔟","bigcap":"⋂","bigcirc":"◯","bigcup":"⋃","bigodot":"⨀","bigoplus":"⨁","bigotimes":"⨂","bigsqcup":"⨆","bigstar":"★","bigtriangledown":"▽","bigtriangleup":"△","biguplus":"⨄","bigvee":"⋁","bigwedge":"⋀","bkarow":"⤍","blacklozenge":"⧫","blacksquare":"▪","blacktriangle":"▴","blacktriangledown":"▾","blacktriangleleft":"◂","blacktriangleright":"▸","blank":"␣","blk12":"▒","blk14":"░","blk34":"▓","block":"█","bne":"=⃥","bnequiv":"≡⃥","bNot":"⫭","bnot":"⌐","Bopf":"𝔹","bopf":"𝕓","bot":"⊥","bottom":"⊥","bowtie":"⋈","boxbox":"⧉","boxdl":"┐","boxdL":"╕","boxDl":"╖","boxDL":"╗","boxdr":"┌","boxdR":"╒","boxDr":"╓","boxDR":"╔","boxh":"─","boxH":"═","boxhd":"┬","boxHd":"╤","boxhD":"╥","boxHD":"╦","boxhu":"┴","boxHu":"╧","boxhU":"╨","boxHU":"╩","boxminus":"⊟","boxplus":"⊞","boxtimes":"⊠","boxul":"┘","boxuL":"╛","boxUl":"╜","boxUL":"╝","boxur":"└","boxuR":"╘","boxUr":"╙","boxUR":"╚","boxv":"│","boxV":"║","boxvh":"┼","boxvH":"╪","boxVh":"╫","boxVH":"╬","boxvl":"┤","boxvL":"╡","boxVl":"╢","boxVL":"╣","boxvr":"├","boxvR":"╞","boxVr":"╟","boxVR":"╠","bprime":"‵","breve":"˘","Breve":"˘","brvbar":"¦","bscr":"𝒷","Bscr":"ℬ","bsemi":"⁏","bsim":"∽","bsime":"⋍","bsolb":"⧅","bsol":"\\","bsolhsub":"⟈","bull":"•","bullet":"•","bump":"≎","bumpE":"⪮","bumpe":"≏","Bumpeq":"≎","bumpeq":"≏","Cacute":"Ć","cacute":"ć","capand":"⩄","capbrcup":"⩉","capcap":"⩋","cap":"∩","Cap":"⋒","capcup":"⩇","capdot":"⩀","CapitalDifferentialD":"ⅅ","caps":"∩︀","caret":"⁁","caron":"ˇ","Cayleys":"ℭ","ccaps":"⩍","Ccaron":"Č","ccaron":"č","Ccedil":"Ç","ccedil":"ç","Ccirc":"Ĉ","ccirc":"ĉ","Cconint":"∰","ccups":"⩌","ccupssm":"⩐","Cdot":"Ċ","cdot":"ċ","cedil":"¸","Cedilla":"¸","cemptyv":"⦲","cent":"¢","centerdot":"·","CenterDot":"·","cfr":"𝔠","Cfr":"ℭ","CHcy":"Ч","chcy":"ч","check":"✓","checkmark":"✓","Chi":"Χ","chi":"χ","circ":"ˆ","circeq":"≗","circlearrowleft":"↺","circlearrowright":"↻","circledast":"⊛","circledcirc":"⊚","circleddash":"⊝","CircleDot":"⊙","circledR":"®","circledS":"Ⓢ","CircleMinus":"⊖","CirclePlus":"⊕","CircleTimes":"⊗","cir":"○","cirE":"⧃","cire":"≗","cirfnint":"⨐","cirmid":"⫯","cirscir":"⧂","ClockwiseContourIntegral":"∲","CloseCurlyDoubleQuote":"”","CloseCurlyQuote":"’","clubs":"♣","clubsuit":"♣","colon":":","Colon":"∷","Colone":"⩴","colone":"≔","coloneq":"≔","comma":",","commat":"@","comp":"∁","compfn":"∘","complement":"∁","complexes":"ℂ","cong":"≅","congdot":"⩭","Congruent":"≡","conint":"∮","Conint":"∯","ContourIntegral":"∮","copf":"𝕔","Copf":"ℂ","coprod":"∐","Coproduct":"∐","copy":"©","COPY":"©","copysr":"℗","CounterClockwiseContourIntegral":"∳","crarr":"↵","cross":"✗","Cross":"⨯","Cscr":"𝒞","cscr":"𝒸","csub":"⫏","csube":"⫑","csup":"⫐","csupe":"⫒","ctdot":"⋯","cudarrl":"⤸","cudarrr":"⤵","cuepr":"⋞","cuesc":"⋟","cularr":"↶","cularrp":"⤽","cupbrcap":"⩈","cupcap":"⩆","CupCap":"≍","cup":"∪","Cup":"⋓","cupcup":"⩊","cupdot":"⊍","cupor":"⩅","cups":"∪︀","curarr":"↷","curarrm":"⤼","curlyeqprec":"⋞","curlyeqsucc":"⋟","curlyvee":"⋎","curlywedge":"⋏","curren":"¤","curvearrowleft":"↶","curvearrowright":"↷","cuvee":"⋎","cuwed":"⋏","cwconint":"∲","cwint":"∱","cylcty":"⌭","dagger":"†","Dagger":"‡","daleth":"ℸ","darr":"↓","Darr":"↡","dArr":"⇓","dash":"‐","Dashv":"⫤","dashv":"⊣","dbkarow":"⤏","dblac":"˝","Dcaron":"Ď","dcaron":"ď","Dcy":"Д","dcy":"д","ddagger":"‡","ddarr":"⇊","DD":"ⅅ","dd":"ⅆ","DDotrahd":"⤑","ddotseq":"⩷","deg":"°","Del":"∇","Delta":"Δ","delta":"δ","demptyv":"⦱","dfisht":"⥿","Dfr":"𝔇","dfr":"𝔡","dHar":"⥥","dharl":"⇃","dharr":"⇂","DiacriticalAcute":"´","DiacriticalDot":"˙","DiacriticalDoubleAcute":"˝","DiacriticalGrave":"`","DiacriticalTilde":"˜","diam":"⋄","diamond":"⋄","Diamond":"⋄","diamondsuit":"♦","diams":"♦","die":"¨","DifferentialD":"ⅆ","digamma":"ϝ","disin":"⋲","div":"÷","divide":"÷","divideontimes":"⋇","divonx":"⋇","DJcy":"Ђ","djcy":"ђ","dlcorn":"⌞","dlcrop":"⌍","dollar":"$","Dopf":"𝔻","dopf":"𝕕","Dot":"¨","dot":"˙","DotDot":"⃜","doteq":"≐","doteqdot":"≑","DotEqual":"≐","dotminus":"∸","dotplus":"∔","dotsquare":"⊡","doublebarwedge":"⌆","DoubleContourIntegral":"∯","DoubleDot":"¨","DoubleDownArrow":"⇓","DoubleLeftArrow":"⇐","DoubleLeftRightArrow":"⇔","DoubleLeftTee":"⫤","DoubleLongLeftArrow":"⟸","DoubleLongLeftRightArrow":"⟺","DoubleLongRightArrow":"⟹","DoubleRightArrow":"⇒","DoubleRightTee":"⊨","DoubleUpArrow":"⇑","DoubleUpDownArrow":"⇕","DoubleVerticalBar":"∥","DownArrowBar":"⤓","downarrow":"↓","DownArrow":"↓","Downarrow":"⇓","DownArrowUpArrow":"⇵","DownBreve":"̑","downdownarrows":"⇊","downharpoonleft":"⇃","downharpoonright":"⇂","DownLeftRightVector":"⥐","DownLeftTeeVector":"⥞","DownLeftVectorBar":"⥖","DownLeftVector":"↽","DownRightTeeVector":"⥟","DownRightVectorBar":"⥗","DownRightVector":"⇁","DownTeeArrow":"↧","DownTee":"⊤","drbkarow":"⤐","drcorn":"⌟","drcrop":"⌌","Dscr":"𝒟","dscr":"𝒹","DScy":"Ѕ","dscy":"ѕ","dsol":"⧶","Dstrok":"Đ","dstrok":"đ","dtdot":"⋱","dtri":"▿","dtrif":"▾","duarr":"⇵","duhar":"⥯","dwangle":"⦦","DZcy":"Џ","dzcy":"џ","dzigrarr":"⟿","Eacute":"É","eacute":"é","easter":"⩮","Ecaron":"Ě","ecaron":"ě","Ecirc":"Ê","ecirc":"ê","ecir":"≖","ecolon":"≕","Ecy":"Э","ecy":"э","eDDot":"⩷","Edot":"Ė","edot":"ė","eDot":"≑","ee":"ⅇ","efDot":"≒","Efr":"𝔈","efr":"𝔢","eg":"⪚","Egrave":"È","egrave":"è","egs":"⪖","egsdot":"⪘","el":"⪙","Element":"∈","elinters":"⏧","ell":"ℓ","els":"⪕","elsdot":"⪗","Emacr":"Ē","emacr":"ē","empty":"∅","emptyset":"∅","EmptySmallSquare":"◻","emptyv":"∅","EmptyVerySmallSquare":"▫","emsp13":" ","emsp14":" ","emsp":" ","ENG":"Ŋ","eng":"ŋ","ensp":" ","Eogon":"Ę","eogon":"ę","Eopf":"𝔼","eopf":"𝕖","epar":"⋕","eparsl":"⧣","eplus":"⩱","epsi":"ε","Epsilon":"Ε","epsilon":"ε","epsiv":"ϵ","eqcirc":"≖","eqcolon":"≕","eqsim":"≂","eqslantgtr":"⪖","eqslantless":"⪕","Equal":"⩵","equals":"=","EqualTilde":"≂","equest":"≟","Equilibrium":"⇌","equiv":"≡","equivDD":"⩸","eqvparsl":"⧥","erarr":"⥱","erDot":"≓","escr":"ℯ","Escr":"ℰ","esdot":"≐","Esim":"⩳","esim":"≂","Eta":"Η","eta":"η","ETH":"Ð","eth":"ð","Euml":"Ë","euml":"ë","euro":"€","excl":"!","exist":"∃","Exists":"∃","expectation":"ℰ","exponentiale":"ⅇ","ExponentialE":"ⅇ","fallingdotseq":"≒","Fcy":"Ф","fcy":"ф","female":"♀","ffilig":"ffi","fflig":"ff","ffllig":"ffl","Ffr":"𝔉","ffr":"𝔣","filig":"fi","FilledSmallSquare":"◼","FilledVerySmallSquare":"▪","fjlig":"fj","flat":"♭","fllig":"fl","fltns":"▱","fnof":"ƒ","Fopf":"𝔽","fopf":"𝕗","forall":"∀","ForAll":"∀","fork":"⋔","forkv":"⫙","Fouriertrf":"ℱ","fpartint":"⨍","frac12":"½","frac13":"⅓","frac14":"¼","frac15":"⅕","frac16":"⅙","frac18":"⅛","frac23":"⅔","frac25":"⅖","frac34":"¾","frac35":"⅗","frac38":"⅜","frac45":"⅘","frac56":"⅚","frac58":"⅝","frac78":"⅞","frasl":"⁄","frown":"⌢","fscr":"𝒻","Fscr":"ℱ","gacute":"ǵ","Gamma":"Γ","gamma":"γ","Gammad":"Ϝ","gammad":"ϝ","gap":"⪆","Gbreve":"Ğ","gbreve":"ğ","Gcedil":"Ģ","Gcirc":"Ĝ","gcirc":"ĝ","Gcy":"Г","gcy":"г","Gdot":"Ġ","gdot":"ġ","ge":"≥","gE":"≧","gEl":"⪌","gel":"⋛","geq":"≥","geqq":"≧","geqslant":"⩾","gescc":"⪩","ges":"⩾","gesdot":"⪀","gesdoto":"⪂","gesdotol":"⪄","gesl":"⋛︀","gesles":"⪔","Gfr":"𝔊","gfr":"𝔤","gg":"≫","Gg":"⋙","ggg":"⋙","gimel":"ℷ","GJcy":"Ѓ","gjcy":"ѓ","gla":"⪥","gl":"≷","glE":"⪒","glj":"⪤","gnap":"⪊","gnapprox":"⪊","gne":"⪈","gnE":"≩","gneq":"⪈","gneqq":"≩","gnsim":"⋧","Gopf":"𝔾","gopf":"𝕘","grave":"`","GreaterEqual":"≥","GreaterEqualLess":"⋛","GreaterFullEqual":"≧","GreaterGreater":"⪢","GreaterLess":"≷","GreaterSlantEqual":"⩾","GreaterTilde":"≳","Gscr":"𝒢","gscr":"ℊ","gsim":"≳","gsime":"⪎","gsiml":"⪐","gtcc":"⪧","gtcir":"⩺","gt":">","GT":">","Gt":"≫","gtdot":"⋗","gtlPar":"⦕","gtquest":"⩼","gtrapprox":"⪆","gtrarr":"⥸","gtrdot":"⋗","gtreqless":"⋛","gtreqqless":"⪌","gtrless":"≷","gtrsim":"≳","gvertneqq":"≩︀","gvnE":"≩︀","Hacek":"ˇ","hairsp":" ","half":"½","hamilt":"ℋ","HARDcy":"Ъ","hardcy":"ъ","harrcir":"⥈","harr":"↔","hArr":"⇔","harrw":"↭","Hat":"^","hbar":"ℏ","Hcirc":"Ĥ","hcirc":"ĥ","hearts":"♥","heartsuit":"♥","hellip":"…","hercon":"⊹","hfr":"𝔥","Hfr":"ℌ","HilbertSpace":"ℋ","hksearow":"⤥","hkswarow":"⤦","hoarr":"⇿","homtht":"∻","hookleftarrow":"↩","hookrightarrow":"↪","hopf":"𝕙","Hopf":"ℍ","horbar":"―","HorizontalLine":"─","hscr":"𝒽","Hscr":"ℋ","hslash":"ℏ","Hstrok":"Ħ","hstrok":"ħ","HumpDownHump":"≎","HumpEqual":"≏","hybull":"⁃","hyphen":"‐","Iacute":"Í","iacute":"í","ic":"","Icirc":"Î","icirc":"î","Icy":"И","icy":"и","Idot":"İ","IEcy":"Е","iecy":"е","iexcl":"¡","iff":"⇔","ifr":"𝔦","Ifr":"ℑ","Igrave":"Ì","igrave":"ì","ii":"ⅈ","iiiint":"⨌","iiint":"∭","iinfin":"⧜","iiota":"℩","IJlig":"IJ","ijlig":"ij","Imacr":"Ī","imacr":"ī","image":"ℑ","ImaginaryI":"ⅈ","imagline":"ℐ","imagpart":"ℑ","imath":"ı","Im":"ℑ","imof":"⊷","imped":"Ƶ","Implies":"⇒","incare":"℅","in":"∈","infin":"∞","infintie":"⧝","inodot":"ı","intcal":"⊺","int":"∫","Int":"∬","integers":"ℤ","Integral":"∫","intercal":"⊺","Intersection":"⋂","intlarhk":"⨗","intprod":"⨼","InvisibleComma":"","InvisibleTimes":"","IOcy":"Ё","iocy":"ё","Iogon":"Į","iogon":"į","Iopf":"𝕀","iopf":"𝕚","Iota":"Ι","iota":"ι","iprod":"⨼","iquest":"¿","iscr":"𝒾","Iscr":"ℐ","isin":"∈","isindot":"⋵","isinE":"⋹","isins":"⋴","isinsv":"⋳","isinv":"∈","it":"","Itilde":"Ĩ","itilde":"ĩ","Iukcy":"І","iukcy":"і","Iuml":"Ï","iuml":"ï","Jcirc":"Ĵ","jcirc":"ĵ","Jcy":"Й","jcy":"й","Jfr":"𝔍","jfr":"𝔧","jmath":"ȷ","Jopf":"𝕁","jopf":"𝕛","Jscr":"𝒥","jscr":"𝒿","Jsercy":"Ј","jsercy":"ј","Jukcy":"Є","jukcy":"є","Kappa":"Κ","kappa":"κ","kappav":"ϰ","Kcedil":"Ķ","kcedil":"ķ","Kcy":"К","kcy":"к","Kfr":"𝔎","kfr":"𝔨","kgreen":"ĸ","KHcy":"Х","khcy":"х","KJcy":"Ќ","kjcy":"ќ","Kopf":"𝕂","kopf":"𝕜","Kscr":"𝒦","kscr":"𝓀","lAarr":"⇚","Lacute":"Ĺ","lacute":"ĺ","laemptyv":"⦴","lagran":"ℒ","Lambda":"Λ","lambda":"λ","lang":"⟨","Lang":"⟪","langd":"⦑","langle":"⟨","lap":"⪅","Laplacetrf":"ℒ","laquo":"«","larrb":"⇤","larrbfs":"⤟","larr":"←","Larr":"↞","lArr":"⇐","larrfs":"⤝","larrhk":"↩","larrlp":"↫","larrpl":"⤹","larrsim":"⥳","larrtl":"↢","latail":"⤙","lAtail":"⤛","lat":"⪫","late":"⪭","lates":"⪭︀","lbarr":"⤌","lBarr":"⤎","lbbrk":"❲","lbrace":"{","lbrack":"[","lbrke":"⦋","lbrksld":"⦏","lbrkslu":"⦍","Lcaron":"Ľ","lcaron":"ľ","Lcedil":"Ļ","lcedil":"ļ","lceil":"⌈","lcub":"{","Lcy":"Л","lcy":"л","ldca":"⤶","ldquo":"“","ldquor":"„","ldrdhar":"⥧","ldrushar":"⥋","ldsh":"↲","le":"≤","lE":"≦","LeftAngleBracket":"⟨","LeftArrowBar":"⇤","leftarrow":"←","LeftArrow":"←","Leftarrow":"⇐","LeftArrowRightArrow":"⇆","leftarrowtail":"↢","LeftCeiling":"⌈","LeftDoubleBracket":"⟦","LeftDownTeeVector":"⥡","LeftDownVectorBar":"⥙","LeftDownVector":"⇃","LeftFloor":"⌊","leftharpoondown":"↽","leftharpoonup":"↼","leftleftarrows":"⇇","leftrightarrow":"↔","LeftRightArrow":"↔","Leftrightarrow":"⇔","leftrightarrows":"⇆","leftrightharpoons":"⇋","leftrightsquigarrow":"↭","LeftRightVector":"⥎","LeftTeeArrow":"↤","LeftTee":"⊣","LeftTeeVector":"⥚","leftthreetimes":"⋋","LeftTriangleBar":"⧏","LeftTriangle":"⊲","LeftTriangleEqual":"⊴","LeftUpDownVector":"⥑","LeftUpTeeVector":"⥠","LeftUpVectorBar":"⥘","LeftUpVector":"↿","LeftVectorBar":"⥒","LeftVector":"↼","lEg":"⪋","leg":"⋚","leq":"≤","leqq":"≦","leqslant":"⩽","lescc":"⪨","les":"⩽","lesdot":"⩿","lesdoto":"⪁","lesdotor":"⪃","lesg":"⋚︀","lesges":"⪓","lessapprox":"⪅","lessdot":"⋖","lesseqgtr":"⋚","lesseqqgtr":"⪋","LessEqualGreater":"⋚","LessFullEqual":"≦","LessGreater":"≶","lessgtr":"≶","LessLess":"⪡","lesssim":"≲","LessSlantEqual":"⩽","LessTilde":"≲","lfisht":"⥼","lfloor":"⌊","Lfr":"𝔏","lfr":"𝔩","lg":"≶","lgE":"⪑","lHar":"⥢","lhard":"↽","lharu":"↼","lharul":"⥪","lhblk":"▄","LJcy":"Љ","ljcy":"љ","llarr":"⇇","ll":"≪","Ll":"⋘","llcorner":"⌞","Lleftarrow":"⇚","llhard":"⥫","lltri":"◺","Lmidot":"Ŀ","lmidot":"ŀ","lmoustache":"⎰","lmoust":"⎰","lnap":"⪉","lnapprox":"⪉","lne":"⪇","lnE":"≨","lneq":"⪇","lneqq":"≨","lnsim":"⋦","loang":"⟬","loarr":"⇽","lobrk":"⟦","longleftarrow":"⟵","LongLeftArrow":"⟵","Longleftarrow":"⟸","longleftrightarrow":"⟷","LongLeftRightArrow":"⟷","Longleftrightarrow":"⟺","longmapsto":"⟼","longrightarrow":"⟶","LongRightArrow":"⟶","Longrightarrow":"⟹","looparrowleft":"↫","looparrowright":"↬","lopar":"⦅","Lopf":"𝕃","lopf":"𝕝","loplus":"⨭","lotimes":"⨴","lowast":"∗","lowbar":"_","LowerLeftArrow":"↙","LowerRightArrow":"↘","loz":"◊","lozenge":"◊","lozf":"⧫","lpar":"(","lparlt":"⦓","lrarr":"⇆","lrcorner":"⌟","lrhar":"⇋","lrhard":"⥭","lrm":"","lrtri":"⊿","lsaquo":"‹","lscr":"𝓁","Lscr":"ℒ","lsh":"↰","Lsh":"↰","lsim":"≲","lsime":"⪍","lsimg":"⪏","lsqb":"[","lsquo":"‘","lsquor":"‚","Lstrok":"Ł","lstrok":"ł","ltcc":"⪦","ltcir":"⩹","lt":"<","LT":"<","Lt":"≪","ltdot":"⋖","lthree":"⋋","ltimes":"⋉","ltlarr":"⥶","ltquest":"⩻","ltri":"◃","ltrie":"⊴","ltrif":"◂","ltrPar":"⦖","lurdshar":"⥊","luruhar":"⥦","lvertneqq":"≨︀","lvnE":"≨︀","macr":"¯","male":"♂","malt":"✠","maltese":"✠","Map":"⤅","map":"↦","mapsto":"↦","mapstodown":"↧","mapstoleft":"↤","mapstoup":"↥","marker":"▮","mcomma":"⨩","Mcy":"М","mcy":"м","mdash":"—","mDDot":"∺","measuredangle":"∡","MediumSpace":" ","Mellintrf":"ℳ","Mfr":"𝔐","mfr":"𝔪","mho":"℧","micro":"µ","midast":"*","midcir":"⫰","mid":"∣","middot":"·","minusb":"⊟","minus":"−","minusd":"∸","minusdu":"⨪","MinusPlus":"∓","mlcp":"⫛","mldr":"…","mnplus":"∓","models":"⊧","Mopf":"𝕄","mopf":"𝕞","mp":"∓","mscr":"𝓂","Mscr":"ℳ","mstpos":"∾","Mu":"Μ","mu":"μ","multimap":"⊸","mumap":"⊸","nabla":"∇","Nacute":"Ń","nacute":"ń","nang":"∠⃒","nap":"≉","napE":"⩰̸","napid":"≋̸","napos":"ʼn","napprox":"≉","natural":"♮","naturals":"ℕ","natur":"♮","nbsp":" ","nbump":"≎̸","nbumpe":"≏̸","ncap":"⩃","Ncaron":"Ň","ncaron":"ň","Ncedil":"Ņ","ncedil":"ņ","ncong":"≇","ncongdot":"⩭̸","ncup":"⩂","Ncy":"Н","ncy":"н","ndash":"–","nearhk":"⤤","nearr":"↗","neArr":"⇗","nearrow":"↗","ne":"≠","nedot":"≐̸","NegativeMediumSpace":"","NegativeThickSpace":"","NegativeThinSpace":"","NegativeVeryThinSpace":"","nequiv":"≢","nesear":"⤨","nesim":"≂̸","NestedGreaterGreater":"≫","NestedLessLess":"≪","NewLine":"\n","nexist":"∄","nexists":"∄","Nfr":"𝔑","nfr":"𝔫","ngE":"≧̸","nge":"≱","ngeq":"≱","ngeqq":"≧̸","ngeqslant":"⩾̸","nges":"⩾̸","nGg":"⋙̸","ngsim":"≵","nGt":"≫⃒","ngt":"≯","ngtr":"≯","nGtv":"≫̸","nharr":"↮","nhArr":"⇎","nhpar":"⫲","ni":"∋","nis":"⋼","nisd":"⋺","niv":"∋","NJcy":"Њ","njcy":"њ","nlarr":"↚","nlArr":"⇍","nldr":"‥","nlE":"≦̸","nle":"≰","nleftarrow":"↚","nLeftarrow":"⇍","nleftrightarrow":"↮","nLeftrightarrow":"⇎","nleq":"≰","nleqq":"≦̸","nleqslant":"⩽̸","nles":"⩽̸","nless":"≮","nLl":"⋘̸","nlsim":"≴","nLt":"≪⃒","nlt":"≮","nltri":"⋪","nltrie":"⋬","nLtv":"≪̸","nmid":"∤","NoBreak":"","NonBreakingSpace":" ","nopf":"𝕟","Nopf":"ℕ","Not":"⫬","not":"¬","NotCongruent":"≢","NotCupCap":"≭","NotDoubleVerticalBar":"∦","NotElement":"∉","NotEqual":"≠","NotEqualTilde":"≂̸","NotExists":"∄","NotGreater":"≯","NotGreaterEqual":"≱","NotGreaterFullEqual":"≧̸","NotGreaterGreater":"≫̸","NotGreaterLess":"≹","NotGreaterSlantEqual":"⩾̸","NotGreaterTilde":"≵","NotHumpDownHump":"≎̸","NotHumpEqual":"≏̸","notin":"∉","notindot":"⋵̸","notinE":"⋹̸","notinva":"∉","notinvb":"⋷","notinvc":"⋶","NotLeftTriangleBar":"⧏̸","NotLeftTriangle":"⋪","NotLeftTriangleEqual":"⋬","NotLess":"≮","NotLessEqual":"≰","NotLessGreater":"≸","NotLessLess":"≪̸","NotLessSlantEqual":"⩽̸","NotLessTilde":"≴","NotNestedGreaterGreater":"⪢̸","NotNestedLessLess":"⪡̸","notni":"∌","notniva":"∌","notnivb":"⋾","notnivc":"⋽","NotPrecedes":"⊀","NotPrecedesEqual":"⪯̸","NotPrecedesSlantEqual":"⋠","NotReverseElement":"∌","NotRightTriangleBar":"⧐̸","NotRightTriangle":"⋫","NotRightTriangleEqual":"⋭","NotSquareSubset":"⊏̸","NotSquareSubsetEqual":"⋢","NotSquareSuperset":"⊐̸","NotSquareSupersetEqual":"⋣","NotSubset":"⊂⃒","NotSubsetEqual":"⊈","NotSucceeds":"⊁","NotSucceedsEqual":"⪰̸","NotSucceedsSlantEqual":"⋡","NotSucceedsTilde":"≿̸","NotSuperset":"⊃⃒","NotSupersetEqual":"⊉","NotTilde":"≁","NotTildeEqual":"≄","NotTildeFullEqual":"≇","NotTildeTilde":"≉","NotVerticalBar":"∤","nparallel":"∦","npar":"∦","nparsl":"⫽⃥","npart":"∂̸","npolint":"⨔","npr":"⊀","nprcue":"⋠","nprec":"⊀","npreceq":"⪯̸","npre":"⪯̸","nrarrc":"⤳̸","nrarr":"↛","nrArr":"⇏","nrarrw":"↝̸","nrightarrow":"↛","nRightarrow":"⇏","nrtri":"⋫","nrtrie":"⋭","nsc":"⊁","nsccue":"⋡","nsce":"⪰̸","Nscr":"𝒩","nscr":"𝓃","nshortmid":"∤","nshortparallel":"∦","nsim":"≁","nsime":"≄","nsimeq":"≄","nsmid":"∤","nspar":"∦","nsqsube":"⋢","nsqsupe":"⋣","nsub":"⊄","nsubE":"⫅̸","nsube":"⊈","nsubset":"⊂⃒","nsubseteq":"⊈","nsubseteqq":"⫅̸","nsucc":"⊁","nsucceq":"⪰̸","nsup":"⊅","nsupE":"⫆̸","nsupe":"⊉","nsupset":"⊃⃒","nsupseteq":"⊉","nsupseteqq":"⫆̸","ntgl":"≹","Ntilde":"Ñ","ntilde":"ñ","ntlg":"≸","ntriangleleft":"⋪","ntrianglelefteq":"⋬","ntriangleright":"⋫","ntrianglerighteq":"⋭","Nu":"Ν","nu":"ν","num":"#","numero":"№","numsp":" ","nvap":"≍⃒","nvdash":"⊬","nvDash":"⊭","nVdash":"⊮","nVDash":"⊯","nvge":"≥⃒","nvgt":">⃒","nvHarr":"⤄","nvinfin":"⧞","nvlArr":"⤂","nvle":"≤⃒","nvlt":"<⃒","nvltrie":"⊴⃒","nvrArr":"⤃","nvrtrie":"⊵⃒","nvsim":"∼⃒","nwarhk":"⤣","nwarr":"↖","nwArr":"⇖","nwarrow":"↖","nwnear":"⤧","Oacute":"Ó","oacute":"ó","oast":"⊛","Ocirc":"Ô","ocirc":"ô","ocir":"⊚","Ocy":"О","ocy":"о","odash":"⊝","Odblac":"Ő","odblac":"ő","odiv":"⨸","odot":"⊙","odsold":"⦼","OElig":"Œ","oelig":"œ","ofcir":"⦿","Ofr":"𝔒","ofr":"𝔬","ogon":"˛","Ograve":"Ò","ograve":"ò","ogt":"⧁","ohbar":"⦵","ohm":"Ω","oint":"∮","olarr":"↺","olcir":"⦾","olcross":"⦻","oline":"‾","olt":"⧀","Omacr":"Ō","omacr":"ō","Omega":"Ω","omega":"ω","Omicron":"Ο","omicron":"ο","omid":"⦶","ominus":"⊖","Oopf":"𝕆","oopf":"𝕠","opar":"⦷","OpenCurlyDoubleQuote":"“","OpenCurlyQuote":"‘","operp":"⦹","oplus":"⊕","orarr":"↻","Or":"⩔","or":"∨","ord":"⩝","order":"ℴ","orderof":"ℴ","ordf":"ª","ordm":"º","origof":"⊶","oror":"⩖","orslope":"⩗","orv":"⩛","oS":"Ⓢ","Oscr":"𝒪","oscr":"ℴ","Oslash":"Ø","oslash":"ø","osol":"⊘","Otilde":"Õ","otilde":"õ","otimesas":"⨶","Otimes":"⨷","otimes":"⊗","Ouml":"Ö","ouml":"ö","ovbar":"⌽","OverBar":"‾","OverBrace":"⏞","OverBracket":"⎴","OverParenthesis":"⏜","para":"¶","parallel":"∥","par":"∥","parsim":"⫳","parsl":"⫽","part":"∂","PartialD":"∂","Pcy":"П","pcy":"п","percnt":"%","period":".","permil":"‰","perp":"⊥","pertenk":"‱","Pfr":"𝔓","pfr":"𝔭","Phi":"Φ","phi":"φ","phiv":"ϕ","phmmat":"ℳ","phone":"☎","Pi":"Π","pi":"π","pitchfork":"⋔","piv":"ϖ","planck":"ℏ","planckh":"ℎ","plankv":"ℏ","plusacir":"⨣","plusb":"⊞","pluscir":"⨢","plus":"+","plusdo":"∔","plusdu":"⨥","pluse":"⩲","PlusMinus":"±","plusmn":"±","plussim":"⨦","plustwo":"⨧","pm":"±","Poincareplane":"ℌ","pointint":"⨕","popf":"𝕡","Popf":"ℙ","pound":"£","prap":"⪷","Pr":"⪻","pr":"≺","prcue":"≼","precapprox":"⪷","prec":"≺","preccurlyeq":"≼","Precedes":"≺","PrecedesEqual":"⪯","PrecedesSlantEqual":"≼","PrecedesTilde":"≾","preceq":"⪯","precnapprox":"⪹","precneqq":"⪵","precnsim":"⋨","pre":"⪯","prE":"⪳","precsim":"≾","prime":"′","Prime":"″","primes":"ℙ","prnap":"⪹","prnE":"⪵","prnsim":"⋨","prod":"∏","Product":"∏","profalar":"⌮","profline":"⌒","profsurf":"⌓","prop":"∝","Proportional":"∝","Proportion":"∷","propto":"∝","prsim":"≾","prurel":"⊰","Pscr":"𝒫","pscr":"𝓅","Psi":"Ψ","psi":"ψ","puncsp":" ","Qfr":"𝔔","qfr":"𝔮","qint":"⨌","qopf":"𝕢","Qopf":"ℚ","qprime":"⁗","Qscr":"𝒬","qscr":"𝓆","quaternions":"ℍ","quatint":"⨖","quest":"?","questeq":"≟","quot":"\"","QUOT":"\"","rAarr":"⇛","race":"∽̱","Racute":"Ŕ","racute":"ŕ","radic":"√","raemptyv":"⦳","rang":"⟩","Rang":"⟫","rangd":"⦒","range":"⦥","rangle":"⟩","raquo":"»","rarrap":"⥵","rarrb":"⇥","rarrbfs":"⤠","rarrc":"⤳","rarr":"→","Rarr":"↠","rArr":"⇒","rarrfs":"⤞","rarrhk":"↪","rarrlp":"↬","rarrpl":"⥅","rarrsim":"⥴","Rarrtl":"⤖","rarrtl":"↣","rarrw":"↝","ratail":"⤚","rAtail":"⤜","ratio":"∶","rationals":"ℚ","rbarr":"⤍","rBarr":"⤏","RBarr":"⤐","rbbrk":"❳","rbrace":"}","rbrack":"]","rbrke":"⦌","rbrksld":"⦎","rbrkslu":"⦐","Rcaron":"Ř","rcaron":"ř","Rcedil":"Ŗ","rcedil":"ŗ","rceil":"⌉","rcub":"}","Rcy":"Р","rcy":"р","rdca":"⤷","rdldhar":"⥩","rdquo":"”","rdquor":"”","rdsh":"↳","real":"ℜ","realine":"ℛ","realpart":"ℜ","reals":"ℝ","Re":"ℜ","rect":"▭","reg":"®","REG":"®","ReverseElement":"∋","ReverseEquilibrium":"⇋","ReverseUpEquilibrium":"⥯","rfisht":"⥽","rfloor":"⌋","rfr":"𝔯","Rfr":"ℜ","rHar":"⥤","rhard":"⇁","rharu":"⇀","rharul":"⥬","Rho":"Ρ","rho":"ρ","rhov":"ϱ","RightAngleBracket":"⟩","RightArrowBar":"⇥","rightarrow":"→","RightArrow":"→","Rightarrow":"⇒","RightArrowLeftArrow":"⇄","rightarrowtail":"↣","RightCeiling":"⌉","RightDoubleBracket":"⟧","RightDownTeeVector":"⥝","RightDownVectorBar":"⥕","RightDownVector":"⇂","RightFloor":"⌋","rightharpoondown":"⇁","rightharpoonup":"⇀","rightleftarrows":"⇄","rightleftharpoons":"⇌","rightrightarrows":"⇉","rightsquigarrow":"↝","RightTeeArrow":"↦","RightTee":"⊢","RightTeeVector":"⥛","rightthreetimes":"⋌","RightTriangleBar":"⧐","RightTriangle":"⊳","RightTriangleEqual":"⊵","RightUpDownVector":"⥏","RightUpTeeVector":"⥜","RightUpVectorBar":"⥔","RightUpVector":"↾","RightVectorBar":"⥓","RightVector":"⇀","ring":"˚","risingdotseq":"≓","rlarr":"⇄","rlhar":"⇌","rlm":"","rmoustache":"⎱","rmoust":"⎱","rnmid":"⫮","roang":"⟭","roarr":"⇾","robrk":"⟧","ropar":"⦆","ropf":"𝕣","Ropf":"ℝ","roplus":"⨮","rotimes":"⨵","RoundImplies":"⥰","rpar":")","rpargt":"⦔","rppolint":"⨒","rrarr":"⇉","Rrightarrow":"⇛","rsaquo":"›","rscr":"𝓇","Rscr":"ℛ","rsh":"↱","Rsh":"↱","rsqb":"]","rsquo":"’","rsquor":"’","rthree":"⋌","rtimes":"⋊","rtri":"▹","rtrie":"⊵","rtrif":"▸","rtriltri":"⧎","RuleDelayed":"⧴","ruluhar":"⥨","rx":"℞","Sacute":"Ś","sacute":"ś","sbquo":"‚","scap":"⪸","Scaron":"Š","scaron":"š","Sc":"⪼","sc":"≻","sccue":"≽","sce":"⪰","scE":"⪴","Scedil":"Ş","scedil":"ş","Scirc":"Ŝ","scirc":"ŝ","scnap":"⪺","scnE":"⪶","scnsim":"⋩","scpolint":"⨓","scsim":"≿","Scy":"С","scy":"с","sdotb":"⊡","sdot":"⋅","sdote":"⩦","searhk":"⤥","searr":"↘","seArr":"⇘","searrow":"↘","sect":"§","semi":";","seswar":"⤩","setminus":"∖","setmn":"∖","sext":"✶","Sfr":"𝔖","sfr":"𝔰","sfrown":"⌢","sharp":"♯","SHCHcy":"Щ","shchcy":"щ","SHcy":"Ш","shcy":"ш","ShortDownArrow":"↓","ShortLeftArrow":"←","shortmid":"∣","shortparallel":"∥","ShortRightArrow":"→","ShortUpArrow":"↑","shy":"","Sigma":"Σ","sigma":"σ","sigmaf":"ς","sigmav":"ς","sim":"∼","simdot":"⩪","sime":"≃","simeq":"≃","simg":"⪞","simgE":"⪠","siml":"⪝","simlE":"⪟","simne":"≆","simplus":"⨤","simrarr":"⥲","slarr":"←","SmallCircle":"∘","smallsetminus":"∖","smashp":"⨳","smeparsl":"⧤","smid":"∣","smile":"⌣","smt":"⪪","smte":"⪬","smtes":"⪬︀","SOFTcy":"Ь","softcy":"ь","solbar":"⌿","solb":"⧄","sol":"/","Sopf":"𝕊","sopf":"𝕤","spades":"♠","spadesuit":"♠","spar":"∥","sqcap":"⊓","sqcaps":"⊓︀","sqcup":"⊔","sqcups":"⊔︀","Sqrt":"√","sqsub":"⊏","sqsube":"⊑","sqsubset":"⊏","sqsubseteq":"⊑","sqsup":"⊐","sqsupe":"⊒","sqsupset":"⊐","sqsupseteq":"⊒","square":"□","Square":"□","SquareIntersection":"⊓","SquareSubset":"⊏","SquareSubsetEqual":"⊑","SquareSuperset":"⊐","SquareSupersetEqual":"⊒","SquareUnion":"⊔","squarf":"▪","squ":"□","squf":"▪","srarr":"→","Sscr":"𝒮","sscr":"𝓈","ssetmn":"∖","ssmile":"⌣","sstarf":"⋆","Star":"⋆","star":"☆","starf":"★","straightepsilon":"ϵ","straightphi":"ϕ","strns":"¯","sub":"⊂","Sub":"⋐","subdot":"⪽","subE":"⫅","sube":"⊆","subedot":"⫃","submult":"⫁","subnE":"⫋","subne":"⊊","subplus":"⪿","subrarr":"⥹","subset":"⊂","Subset":"⋐","subseteq":"⊆","subseteqq":"⫅","SubsetEqual":"⊆","subsetneq":"⊊","subsetneqq":"⫋","subsim":"⫇","subsub":"⫕","subsup":"⫓","succapprox":"⪸","succ":"≻","succcurlyeq":"≽","Succeeds":"≻","SucceedsEqual":"⪰","SucceedsSlantEqual":"≽","SucceedsTilde":"≿","succeq":"⪰","succnapprox":"⪺","succneqq":"⪶","succnsim":"⋩","succsim":"≿","SuchThat":"∋","sum":"∑","Sum":"∑","sung":"♪","sup1":"¹","sup2":"²","sup3":"³","sup":"⊃","Sup":"⋑","supdot":"⪾","supdsub":"⫘","supE":"⫆","supe":"⊇","supedot":"⫄","Superset":"⊃","SupersetEqual":"⊇","suphsol":"⟉","suphsub":"⫗","suplarr":"⥻","supmult":"⫂","supnE":"⫌","supne":"⊋","supplus":"⫀","supset":"⊃","Supset":"⋑","supseteq":"⊇","supseteqq":"⫆","supsetneq":"⊋","supsetneqq":"⫌","supsim":"⫈","supsub":"⫔","supsup":"⫖","swarhk":"⤦","swarr":"↙","swArr":"⇙","swarrow":"↙","swnwar":"⤪","szlig":"ß","Tab":"\t","target":"⌖","Tau":"Τ","tau":"τ","tbrk":"⎴","Tcaron":"Ť","tcaron":"ť","Tcedil":"Ţ","tcedil":"ţ","Tcy":"Т","tcy":"т","tdot":"⃛","telrec":"⌕","Tfr":"𝔗","tfr":"𝔱","there4":"∴","therefore":"∴","Therefore":"∴","Theta":"Θ","theta":"θ","thetasym":"ϑ","thetav":"ϑ","thickapprox":"≈","thicksim":"∼","ThickSpace":" ","ThinSpace":" ","thinsp":" ","thkap":"≈","thksim":"∼","THORN":"Þ","thorn":"þ","tilde":"˜","Tilde":"∼","TildeEqual":"≃","TildeFullEqual":"≅","TildeTilde":"≈","timesbar":"⨱","timesb":"⊠","times":"×","timesd":"⨰","tint":"∭","toea":"⤨","topbot":"⌶","topcir":"⫱","top":"⊤","Topf":"𝕋","topf":"𝕥","topfork":"⫚","tosa":"⤩","tprime":"‴","trade":"™","TRADE":"™","triangle":"▵","triangledown":"▿","triangleleft":"◃","trianglelefteq":"⊴","triangleq":"≜","triangleright":"▹","trianglerighteq":"⊵","tridot":"◬","trie":"≜","triminus":"⨺","TripleDot":"⃛","triplus":"⨹","trisb":"⧍","tritime":"⨻","trpezium":"⏢","Tscr":"𝒯","tscr":"𝓉","TScy":"Ц","tscy":"ц","TSHcy":"Ћ","tshcy":"ћ","Tstrok":"Ŧ","tstrok":"ŧ","twixt":"≬","twoheadleftarrow":"↞","twoheadrightarrow":"↠","Uacute":"Ú","uacute":"ú","uarr":"↑","Uarr":"↟","uArr":"⇑","Uarrocir":"⥉","Ubrcy":"Ў","ubrcy":"ў","Ubreve":"Ŭ","ubreve":"ŭ","Ucirc":"Û","ucirc":"û","Ucy":"У","ucy":"у","udarr":"⇅","Udblac":"Ű","udblac":"ű","udhar":"⥮","ufisht":"⥾","Ufr":"𝔘","ufr":"𝔲","Ugrave":"Ù","ugrave":"ù","uHar":"⥣","uharl":"↿","uharr":"↾","uhblk":"▀","ulcorn":"⌜","ulcorner":"⌜","ulcrop":"⌏","ultri":"◸","Umacr":"Ū","umacr":"ū","uml":"¨","UnderBar":"_","UnderBrace":"⏟","UnderBracket":"⎵","UnderParenthesis":"⏝","Union":"⋃","UnionPlus":"⊎","Uogon":"Ų","uogon":"ų","Uopf":"𝕌","uopf":"𝕦","UpArrowBar":"⤒","uparrow":"↑","UpArrow":"↑","Uparrow":"⇑","UpArrowDownArrow":"⇅","updownarrow":"↕","UpDownArrow":"↕","Updownarrow":"⇕","UpEquilibrium":"⥮","upharpoonleft":"↿","upharpoonright":"↾","uplus":"⊎","UpperLeftArrow":"↖","UpperRightArrow":"↗","upsi":"υ","Upsi":"ϒ","upsih":"ϒ","Upsilon":"Υ","upsilon":"υ","UpTeeArrow":"↥","UpTee":"⊥","upuparrows":"⇈","urcorn":"⌝","urcorner":"⌝","urcrop":"⌎","Uring":"Ů","uring":"ů","urtri":"◹","Uscr":"𝒰","uscr":"𝓊","utdot":"⋰","Utilde":"Ũ","utilde":"ũ","utri":"▵","utrif":"▴","uuarr":"⇈","Uuml":"Ü","uuml":"ü","uwangle":"⦧","vangrt":"⦜","varepsilon":"ϵ","varkappa":"ϰ","varnothing":"∅","varphi":"ϕ","varpi":"ϖ","varpropto":"∝","varr":"↕","vArr":"⇕","varrho":"ϱ","varsigma":"ς","varsubsetneq":"⊊︀","varsubsetneqq":"⫋︀","varsupsetneq":"⊋︀","varsupsetneqq":"⫌︀","vartheta":"ϑ","vartriangleleft":"⊲","vartriangleright":"⊳","vBar":"⫨","Vbar":"⫫","vBarv":"⫩","Vcy":"В","vcy":"в","vdash":"⊢","vDash":"⊨","Vdash":"⊩","VDash":"⊫","Vdashl":"⫦","veebar":"⊻","vee":"∨","Vee":"⋁","veeeq":"≚","vellip":"⋮","verbar":"|","Verbar":"‖","vert":"|","Vert":"‖","VerticalBar":"∣","VerticalLine":"|","VerticalSeparator":"❘","VerticalTilde":"≀","VeryThinSpace":" ","Vfr":"𝔙","vfr":"𝔳","vltri":"⊲","vnsub":"⊂⃒","vnsup":"⊃⃒","Vopf":"𝕍","vopf":"𝕧","vprop":"∝","vrtri":"⊳","Vscr":"𝒱","vscr":"𝓋","vsubnE":"⫋︀","vsubne":"⊊︀","vsupnE":"⫌︀","vsupne":"⊋︀","Vvdash":"⊪","vzigzag":"⦚","Wcirc":"Ŵ","wcirc":"ŵ","wedbar":"⩟","wedge":"∧","Wedge":"⋀","wedgeq":"≙","weierp":"℘","Wfr":"𝔚","wfr":"𝔴","Wopf":"𝕎","wopf":"𝕨","wp":"℘","wr":"≀","wreath":"≀","Wscr":"𝒲","wscr":"𝓌","xcap":"⋂","xcirc":"◯","xcup":"⋃","xdtri":"▽","Xfr":"𝔛","xfr":"𝔵","xharr":"⟷","xhArr":"⟺","Xi":"Ξ","xi":"ξ","xlarr":"⟵","xlArr":"⟸","xmap":"⟼","xnis":"⋻","xodot":"⨀","Xopf":"𝕏","xopf":"𝕩","xoplus":"⨁","xotime":"⨂","xrarr":"⟶","xrArr":"⟹","Xscr":"𝒳","xscr":"𝓍","xsqcup":"⨆","xuplus":"⨄","xutri":"△","xvee":"⋁","xwedge":"⋀","Yacute":"Ý","yacute":"ý","YAcy":"Я","yacy":"я","Ycirc":"Ŷ","ycirc":"ŷ","Ycy":"Ы","ycy":"ы","yen":"¥","Yfr":"𝔜","yfr":"𝔶","YIcy":"Ї","yicy":"ї","Yopf":"𝕐","yopf":"𝕪","Yscr":"𝒴","yscr":"𝓎","YUcy":"Ю","yucy":"ю","yuml":"ÿ","Yuml":"Ÿ","Zacute":"Ź","zacute":"ź","Zcaron":"Ž","zcaron":"ž","Zcy":"З","zcy":"з","Zdot":"Ż","zdot":"ż","zeetrf":"ℨ","ZeroWidthSpace":"","Zeta":"Ζ","zeta":"ζ","zfr":"𝔷","Zfr":"ℨ","ZHcy":"Ж","zhcy":"ж","zigrarr":"⇝","zopf":"𝕫","Zopf":"ℤ","Zscr":"𝒵","zscr":"𝓏","zwj":"","zwnj":""}
|
|
|
|
},{}],53:[function(require,module,exports){
|
|
module.exports={"Aacute":"Á","aacute":"á","Acirc":"Â","acirc":"â","acute":"´","AElig":"Æ","aelig":"æ","Agrave":"À","agrave":"à","amp":"&","AMP":"&","Aring":"Å","aring":"å","Atilde":"Ã","atilde":"ã","Auml":"Ä","auml":"ä","brvbar":"¦","Ccedil":"Ç","ccedil":"ç","cedil":"¸","cent":"¢","copy":"©","COPY":"©","curren":"¤","deg":"°","divide":"÷","Eacute":"É","eacute":"é","Ecirc":"Ê","ecirc":"ê","Egrave":"È","egrave":"è","ETH":"Ð","eth":"ð","Euml":"Ë","euml":"ë","frac12":"½","frac14":"¼","frac34":"¾","gt":">","GT":">","Iacute":"Í","iacute":"í","Icirc":"Î","icirc":"î","iexcl":"¡","Igrave":"Ì","igrave":"ì","iquest":"¿","Iuml":"Ï","iuml":"ï","laquo":"«","lt":"<","LT":"<","macr":"¯","micro":"µ","middot":"·","nbsp":" ","not":"¬","Ntilde":"Ñ","ntilde":"ñ","Oacute":"Ó","oacute":"ó","Ocirc":"Ô","ocirc":"ô","Ograve":"Ò","ograve":"ò","ordf":"ª","ordm":"º","Oslash":"Ø","oslash":"ø","Otilde":"Õ","otilde":"õ","Ouml":"Ö","ouml":"ö","para":"¶","plusmn":"±","pound":"£","quot":"\"","QUOT":"\"","raquo":"»","reg":"®","REG":"®","sect":"§","shy":"","sup1":"¹","sup2":"²","sup3":"³","szlig":"ß","THORN":"Þ","thorn":"þ","times":"×","Uacute":"Ú","uacute":"ú","Ucirc":"Û","ucirc":"û","Ugrave":"Ù","ugrave":"ù","uml":"¨","Uuml":"Ü","uuml":"ü","Yacute":"Ý","yacute":"ý","yen":"¥","yuml":"ÿ"}
|
|
|
|
},{}],54:[function(require,module,exports){
|
|
module.exports={"amp":"&","apos":"'","gt":">","lt":"<","quot":"\""}
|
|
|
|
},{}],55:[function(require,module,exports){
|
|
"use strict";
|
|
var __extends = (this && this.__extends) || (function () {
|
|
var extendStatics = function (d, b) {
|
|
extendStatics = Object.setPrototypeOf ||
|
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
return extendStatics(d, b);
|
|
};
|
|
return function (d, b) {
|
|
if (typeof b !== "function" && b !== null)
|
|
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
extendStatics(d, b);
|
|
function __() { this.constructor = d; }
|
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
};
|
|
})();
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.parseFeed = exports.FeedHandler = void 0;
|
|
var domhandler_1 = __importDefault(require("domhandler"));
|
|
var DomUtils = __importStar(require("domutils"));
|
|
var Parser_1 = require("./Parser");
|
|
var FeedItemMediaMedium;
|
|
(function (FeedItemMediaMedium) {
|
|
FeedItemMediaMedium[FeedItemMediaMedium["image"] = 0] = "image";
|
|
FeedItemMediaMedium[FeedItemMediaMedium["audio"] = 1] = "audio";
|
|
FeedItemMediaMedium[FeedItemMediaMedium["video"] = 2] = "video";
|
|
FeedItemMediaMedium[FeedItemMediaMedium["document"] = 3] = "document";
|
|
FeedItemMediaMedium[FeedItemMediaMedium["executable"] = 4] = "executable";
|
|
})(FeedItemMediaMedium || (FeedItemMediaMedium = {}));
|
|
var FeedItemMediaExpression;
|
|
(function (FeedItemMediaExpression) {
|
|
FeedItemMediaExpression[FeedItemMediaExpression["sample"] = 0] = "sample";
|
|
FeedItemMediaExpression[FeedItemMediaExpression["full"] = 1] = "full";
|
|
FeedItemMediaExpression[FeedItemMediaExpression["nonstop"] = 2] = "nonstop";
|
|
})(FeedItemMediaExpression || (FeedItemMediaExpression = {}));
|
|
// TODO: Consume data as it is coming in
|
|
var FeedHandler = /** @class */ (function (_super) {
|
|
__extends(FeedHandler, _super);
|
|
/**
|
|
*
|
|
* @param callback
|
|
* @param options
|
|
*/
|
|
function FeedHandler(callback, options) {
|
|
var _this = this;
|
|
if (typeof callback === "object") {
|
|
callback = undefined;
|
|
options = callback;
|
|
}
|
|
_this = _super.call(this, callback, options) || this;
|
|
return _this;
|
|
}
|
|
FeedHandler.prototype.onend = function () {
|
|
var _a, _b;
|
|
var feedRoot = getOneElement(isValidFeed, this.dom);
|
|
if (!feedRoot) {
|
|
this.handleCallback(new Error("couldn't find root of feed"));
|
|
return;
|
|
}
|
|
var feed = {};
|
|
if (feedRoot.name === "feed") {
|
|
var childs = feedRoot.children;
|
|
feed.type = "atom";
|
|
addConditionally(feed, "id", "id", childs);
|
|
addConditionally(feed, "title", "title", childs);
|
|
var href = getAttribute("href", getOneElement("link", childs));
|
|
if (href) {
|
|
feed.link = href;
|
|
}
|
|
addConditionally(feed, "description", "subtitle", childs);
|
|
var updated = fetch("updated", childs);
|
|
if (updated) {
|
|
feed.updated = new Date(updated);
|
|
}
|
|
addConditionally(feed, "author", "email", childs, true);
|
|
feed.items = getElements("entry", childs).map(function (item) {
|
|
var entry = {};
|
|
var children = item.children;
|
|
addConditionally(entry, "id", "id", children);
|
|
addConditionally(entry, "title", "title", children);
|
|
var href = getAttribute("href", getOneElement("link", children));
|
|
if (href) {
|
|
entry.link = href;
|
|
}
|
|
var description = fetch("summary", children) || fetch("content", children);
|
|
if (description) {
|
|
entry.description = description;
|
|
}
|
|
var pubDate = fetch("updated", children);
|
|
if (pubDate) {
|
|
entry.pubDate = new Date(pubDate);
|
|
}
|
|
entry.media = getMediaElements(children);
|
|
return entry;
|
|
});
|
|
}
|
|
else {
|
|
var childs = (_b = (_a = getOneElement("channel", feedRoot.children)) === null || _a === void 0 ? void 0 : _a.children) !== null && _b !== void 0 ? _b : [];
|
|
feed.type = feedRoot.name.substr(0, 3);
|
|
feed.id = "";
|
|
addConditionally(feed, "title", "title", childs);
|
|
addConditionally(feed, "link", "link", childs);
|
|
addConditionally(feed, "description", "description", childs);
|
|
var updated = fetch("lastBuildDate", childs);
|
|
if (updated) {
|
|
feed.updated = new Date(updated);
|
|
}
|
|
addConditionally(feed, "author", "managingEditor", childs, true);
|
|
feed.items = getElements("item", feedRoot.children).map(function (item) {
|
|
var entry = {};
|
|
var children = item.children;
|
|
addConditionally(entry, "id", "guid", children);
|
|
addConditionally(entry, "title", "title", children);
|
|
addConditionally(entry, "link", "link", children);
|
|
addConditionally(entry, "description", "description", children);
|
|
var pubDate = fetch("pubDate", children);
|
|
if (pubDate)
|
|
entry.pubDate = new Date(pubDate);
|
|
entry.media = getMediaElements(children);
|
|
return entry;
|
|
});
|
|
}
|
|
this.feed = feed;
|
|
this.handleCallback(null);
|
|
};
|
|
return FeedHandler;
|
|
}(domhandler_1.default));
|
|
exports.FeedHandler = FeedHandler;
|
|
function getMediaElements(where) {
|
|
return getElements("media:content", where).map(function (elem) {
|
|
var media = {
|
|
medium: elem.attribs.medium,
|
|
isDefault: !!elem.attribs.isDefault,
|
|
};
|
|
if (elem.attribs.url) {
|
|
media.url = elem.attribs.url;
|
|
}
|
|
if (elem.attribs.fileSize) {
|
|
media.fileSize = parseInt(elem.attribs.fileSize, 10);
|
|
}
|
|
if (elem.attribs.type) {
|
|
media.type = elem.attribs.type;
|
|
}
|
|
if (elem.attribs.expression) {
|
|
media.expression = elem.attribs
|
|
.expression;
|
|
}
|
|
if (elem.attribs.bitrate) {
|
|
media.bitrate = parseInt(elem.attribs.bitrate, 10);
|
|
}
|
|
if (elem.attribs.framerate) {
|
|
media.framerate = parseInt(elem.attribs.framerate, 10);
|
|
}
|
|
if (elem.attribs.samplingrate) {
|
|
media.samplingrate = parseInt(elem.attribs.samplingrate, 10);
|
|
}
|
|
if (elem.attribs.channels) {
|
|
media.channels = parseInt(elem.attribs.channels, 10);
|
|
}
|
|
if (elem.attribs.duration) {
|
|
media.duration = parseInt(elem.attribs.duration, 10);
|
|
}
|
|
if (elem.attribs.height) {
|
|
media.height = parseInt(elem.attribs.height, 10);
|
|
}
|
|
if (elem.attribs.width) {
|
|
media.width = parseInt(elem.attribs.width, 10);
|
|
}
|
|
if (elem.attribs.lang) {
|
|
media.lang = elem.attribs.lang;
|
|
}
|
|
return media;
|
|
});
|
|
}
|
|
function getElements(tagName, where) {
|
|
return DomUtils.getElementsByTagName(tagName, where, true);
|
|
}
|
|
function getOneElement(tagName, node) {
|
|
return DomUtils.getElementsByTagName(tagName, node, true, 1)[0];
|
|
}
|
|
function fetch(tagName, where, recurse) {
|
|
if (recurse === void 0) { recurse = false; }
|
|
return DomUtils.getText(DomUtils.getElementsByTagName(tagName, where, recurse, 1)).trim();
|
|
}
|
|
function getAttribute(name, elem) {
|
|
if (!elem) {
|
|
return null;
|
|
}
|
|
var attribs = elem.attribs;
|
|
return attribs[name];
|
|
}
|
|
function addConditionally(obj, prop, what, where, recurse) {
|
|
if (recurse === void 0) { recurse = false; }
|
|
var tmp = fetch(what, where, recurse);
|
|
if (tmp)
|
|
obj[prop] = tmp;
|
|
}
|
|
function isValidFeed(value) {
|
|
return value === "rss" || value === "feed" || value === "rdf:RDF";
|
|
}
|
|
/**
|
|
* Parse a feed.
|
|
*
|
|
* @param feed The feed that should be parsed, as a string.
|
|
* @param options Optionally, options for parsing. When using this option, you should set `xmlMode` to `true`.
|
|
*/
|
|
function parseFeed(feed, options) {
|
|
if (options === void 0) { options = { xmlMode: true }; }
|
|
var handler = new FeedHandler(options);
|
|
new Parser_1.Parser(handler, options).end(feed);
|
|
return handler.feed;
|
|
}
|
|
exports.parseFeed = parseFeed;
|
|
|
|
},{"./Parser":56,"domhandler":38,"domutils":41}],56:[function(require,module,exports){
|
|
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.Parser = void 0;
|
|
var Tokenizer_1 = __importDefault(require("./Tokenizer"));
|
|
var formTags = new Set([
|
|
"input",
|
|
"option",
|
|
"optgroup",
|
|
"select",
|
|
"button",
|
|
"datalist",
|
|
"textarea",
|
|
]);
|
|
var pTag = new Set(["p"]);
|
|
var openImpliesClose = {
|
|
tr: new Set(["tr", "th", "td"]),
|
|
th: new Set(["th"]),
|
|
td: new Set(["thead", "th", "td"]),
|
|
body: new Set(["head", "link", "script"]),
|
|
li: new Set(["li"]),
|
|
p: pTag,
|
|
h1: pTag,
|
|
h2: pTag,
|
|
h3: pTag,
|
|
h4: pTag,
|
|
h5: pTag,
|
|
h6: pTag,
|
|
select: formTags,
|
|
input: formTags,
|
|
output: formTags,
|
|
button: formTags,
|
|
datalist: formTags,
|
|
textarea: formTags,
|
|
option: new Set(["option"]),
|
|
optgroup: new Set(["optgroup", "option"]),
|
|
dd: new Set(["dt", "dd"]),
|
|
dt: new Set(["dt", "dd"]),
|
|
address: pTag,
|
|
article: pTag,
|
|
aside: pTag,
|
|
blockquote: pTag,
|
|
details: pTag,
|
|
div: pTag,
|
|
dl: pTag,
|
|
fieldset: pTag,
|
|
figcaption: pTag,
|
|
figure: pTag,
|
|
footer: pTag,
|
|
form: pTag,
|
|
header: pTag,
|
|
hr: pTag,
|
|
main: pTag,
|
|
nav: pTag,
|
|
ol: pTag,
|
|
pre: pTag,
|
|
section: pTag,
|
|
table: pTag,
|
|
ul: pTag,
|
|
rt: new Set(["rt", "rp"]),
|
|
rp: new Set(["rt", "rp"]),
|
|
tbody: new Set(["thead", "tbody"]),
|
|
tfoot: new Set(["thead", "tbody"]),
|
|
};
|
|
var voidElements = new Set([
|
|
"area",
|
|
"base",
|
|
"basefont",
|
|
"br",
|
|
"col",
|
|
"command",
|
|
"embed",
|
|
"frame",
|
|
"hr",
|
|
"img",
|
|
"input",
|
|
"isindex",
|
|
"keygen",
|
|
"link",
|
|
"meta",
|
|
"param",
|
|
"source",
|
|
"track",
|
|
"wbr",
|
|
]);
|
|
var foreignContextElements = new Set(["math", "svg"]);
|
|
var htmlIntegrationElements = new Set([
|
|
"mi",
|
|
"mo",
|
|
"mn",
|
|
"ms",
|
|
"mtext",
|
|
"annotation-xml",
|
|
"foreignObject",
|
|
"desc",
|
|
"title",
|
|
]);
|
|
var reNameEnd = /\s|\//;
|
|
var Parser = /** @class */ (function () {
|
|
function Parser(cbs, options) {
|
|
if (options === void 0) { options = {}; }
|
|
var _a, _b, _c, _d, _e;
|
|
/** The start index of the last event. */
|
|
this.startIndex = 0;
|
|
/** The end index of the last event. */
|
|
this.endIndex = null;
|
|
this.tagname = "";
|
|
this.attribname = "";
|
|
this.attribvalue = "";
|
|
this.attribs = null;
|
|
this.stack = [];
|
|
this.foreignContext = [];
|
|
this.options = options;
|
|
this.cbs = cbs !== null && cbs !== void 0 ? cbs : {};
|
|
this.lowerCaseTagNames = (_a = options.lowerCaseTags) !== null && _a !== void 0 ? _a : !options.xmlMode;
|
|
this.lowerCaseAttributeNames =
|
|
(_b = options.lowerCaseAttributeNames) !== null && _b !== void 0 ? _b : !options.xmlMode;
|
|
this.tokenizer = new ((_c = options.Tokenizer) !== null && _c !== void 0 ? _c : Tokenizer_1.default)(this.options, this);
|
|
(_e = (_d = this.cbs).onparserinit) === null || _e === void 0 ? void 0 : _e.call(_d, this);
|
|
}
|
|
Parser.prototype.updatePosition = function (initialOffset) {
|
|
if (this.endIndex === null) {
|
|
if (this.tokenizer.sectionStart <= initialOffset) {
|
|
this.startIndex = 0;
|
|
}
|
|
else {
|
|
this.startIndex = this.tokenizer.sectionStart - initialOffset;
|
|
}
|
|
}
|
|
else {
|
|
this.startIndex = this.endIndex + 1;
|
|
}
|
|
this.endIndex = this.tokenizer.getAbsoluteIndex();
|
|
};
|
|
// Tokenizer event handlers
|
|
Parser.prototype.ontext = function (data) {
|
|
var _a, _b;
|
|
this.updatePosition(1);
|
|
this.endIndex--;
|
|
(_b = (_a = this.cbs).ontext) === null || _b === void 0 ? void 0 : _b.call(_a, data);
|
|
};
|
|
Parser.prototype.onopentagname = function (name) {
|
|
var _a, _b;
|
|
if (this.lowerCaseTagNames) {
|
|
name = name.toLowerCase();
|
|
}
|
|
this.tagname = name;
|
|
if (!this.options.xmlMode &&
|
|
Object.prototype.hasOwnProperty.call(openImpliesClose, name)) {
|
|
var el = void 0;
|
|
while (this.stack.length > 0 &&
|
|
openImpliesClose[name].has((el = this.stack[this.stack.length - 1]))) {
|
|
this.onclosetag(el);
|
|
}
|
|
}
|
|
if (this.options.xmlMode || !voidElements.has(name)) {
|
|
this.stack.push(name);
|
|
if (foreignContextElements.has(name)) {
|
|
this.foreignContext.push(true);
|
|
}
|
|
else if (htmlIntegrationElements.has(name)) {
|
|
this.foreignContext.push(false);
|
|
}
|
|
}
|
|
(_b = (_a = this.cbs).onopentagname) === null || _b === void 0 ? void 0 : _b.call(_a, name);
|
|
if (this.cbs.onopentag)
|
|
this.attribs = {};
|
|
};
|
|
Parser.prototype.onopentagend = function () {
|
|
var _a, _b;
|
|
this.updatePosition(1);
|
|
if (this.attribs) {
|
|
(_b = (_a = this.cbs).onopentag) === null || _b === void 0 ? void 0 : _b.call(_a, this.tagname, this.attribs);
|
|
this.attribs = null;
|
|
}
|
|
if (!this.options.xmlMode &&
|
|
this.cbs.onclosetag &&
|
|
voidElements.has(this.tagname)) {
|
|
this.cbs.onclosetag(this.tagname);
|
|
}
|
|
this.tagname = "";
|
|
};
|
|
Parser.prototype.onclosetag = function (name) {
|
|
this.updatePosition(1);
|
|
if (this.lowerCaseTagNames) {
|
|
name = name.toLowerCase();
|
|
}
|
|
if (foreignContextElements.has(name) ||
|
|
htmlIntegrationElements.has(name)) {
|
|
this.foreignContext.pop();
|
|
}
|
|
if (this.stack.length &&
|
|
(this.options.xmlMode || !voidElements.has(name))) {
|
|
var pos = this.stack.lastIndexOf(name);
|
|
if (pos !== -1) {
|
|
if (this.cbs.onclosetag) {
|
|
pos = this.stack.length - pos;
|
|
while (pos--) {
|
|
// We know the stack has sufficient elements.
|
|
this.cbs.onclosetag(this.stack.pop());
|
|
}
|
|
}
|
|
else
|
|
this.stack.length = pos;
|
|
}
|
|
else if (name === "p" && !this.options.xmlMode) {
|
|
this.onopentagname(name);
|
|
this.closeCurrentTag();
|
|
}
|
|
}
|
|
else if (!this.options.xmlMode && (name === "br" || name === "p")) {
|
|
this.onopentagname(name);
|
|
this.closeCurrentTag();
|
|
}
|
|
};
|
|
Parser.prototype.onselfclosingtag = function () {
|
|
if (this.options.xmlMode ||
|
|
this.options.recognizeSelfClosing ||
|
|
this.foreignContext[this.foreignContext.length - 1]) {
|
|
this.closeCurrentTag();
|
|
}
|
|
else {
|
|
this.onopentagend();
|
|
}
|
|
};
|
|
Parser.prototype.closeCurrentTag = function () {
|
|
var _a, _b;
|
|
var name = this.tagname;
|
|
this.onopentagend();
|
|
/*
|
|
* Self-closing tags will be on the top of the stack
|
|
* (cheaper check than in onclosetag)
|
|
*/
|
|
if (this.stack[this.stack.length - 1] === name) {
|
|
(_b = (_a = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a, name);
|
|
this.stack.pop();
|
|
}
|
|
};
|
|
Parser.prototype.onattribname = function (name) {
|
|
if (this.lowerCaseAttributeNames) {
|
|
name = name.toLowerCase();
|
|
}
|
|
this.attribname = name;
|
|
};
|
|
Parser.prototype.onattribdata = function (value) {
|
|
this.attribvalue += value;
|
|
};
|
|
Parser.prototype.onattribend = function (quote) {
|
|
var _a, _b;
|
|
(_b = (_a = this.cbs).onattribute) === null || _b === void 0 ? void 0 : _b.call(_a, this.attribname, this.attribvalue, quote);
|
|
if (this.attribs &&
|
|
!Object.prototype.hasOwnProperty.call(this.attribs, this.attribname)) {
|
|
this.attribs[this.attribname] = this.attribvalue;
|
|
}
|
|
this.attribname = "";
|
|
this.attribvalue = "";
|
|
};
|
|
Parser.prototype.getInstructionName = function (value) {
|
|
var idx = value.search(reNameEnd);
|
|
var name = idx < 0 ? value : value.substr(0, idx);
|
|
if (this.lowerCaseTagNames) {
|
|
name = name.toLowerCase();
|
|
}
|
|
return name;
|
|
};
|
|
Parser.prototype.ondeclaration = function (value) {
|
|
if (this.cbs.onprocessinginstruction) {
|
|
var name_1 = this.getInstructionName(value);
|
|
this.cbs.onprocessinginstruction("!" + name_1, "!" + value);
|
|
}
|
|
};
|
|
Parser.prototype.onprocessinginstruction = function (value) {
|
|
if (this.cbs.onprocessinginstruction) {
|
|
var name_2 = this.getInstructionName(value);
|
|
this.cbs.onprocessinginstruction("?" + name_2, "?" + value);
|
|
}
|
|
};
|
|
Parser.prototype.oncomment = function (value) {
|
|
var _a, _b, _c, _d;
|
|
this.updatePosition(4);
|
|
(_b = (_a = this.cbs).oncomment) === null || _b === void 0 ? void 0 : _b.call(_a, value);
|
|
(_d = (_c = this.cbs).oncommentend) === null || _d === void 0 ? void 0 : _d.call(_c);
|
|
};
|
|
Parser.prototype.oncdata = function (value) {
|
|
var _a, _b, _c, _d, _e, _f;
|
|
this.updatePosition(1);
|
|
if (this.options.xmlMode || this.options.recognizeCDATA) {
|
|
(_b = (_a = this.cbs).oncdatastart) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
(_d = (_c = this.cbs).ontext) === null || _d === void 0 ? void 0 : _d.call(_c, value);
|
|
(_f = (_e = this.cbs).oncdataend) === null || _f === void 0 ? void 0 : _f.call(_e);
|
|
}
|
|
else {
|
|
this.oncomment("[CDATA[" + value + "]]");
|
|
}
|
|
};
|
|
Parser.prototype.onerror = function (err) {
|
|
var _a, _b;
|
|
(_b = (_a = this.cbs).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, err);
|
|
};
|
|
Parser.prototype.onend = function () {
|
|
var _a, _b;
|
|
if (this.cbs.onclosetag) {
|
|
for (var i = this.stack.length; i > 0; this.cbs.onclosetag(this.stack[--i]))
|
|
;
|
|
}
|
|
(_b = (_a = this.cbs).onend) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
};
|
|
/**
|
|
* Resets the parser to a blank state, ready to parse a new HTML document
|
|
*/
|
|
Parser.prototype.reset = function () {
|
|
var _a, _b, _c, _d;
|
|
(_b = (_a = this.cbs).onreset) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
this.tokenizer.reset();
|
|
this.tagname = "";
|
|
this.attribname = "";
|
|
this.attribs = null;
|
|
this.stack = [];
|
|
(_d = (_c = this.cbs).onparserinit) === null || _d === void 0 ? void 0 : _d.call(_c, this);
|
|
};
|
|
/**
|
|
* Resets the parser, then parses a complete document and
|
|
* pushes it to the handler.
|
|
*
|
|
* @param data Document to parse.
|
|
*/
|
|
Parser.prototype.parseComplete = function (data) {
|
|
this.reset();
|
|
this.end(data);
|
|
};
|
|
/**
|
|
* Parses a chunk of data and calls the corresponding callbacks.
|
|
*
|
|
* @param chunk Chunk to parse.
|
|
*/
|
|
Parser.prototype.write = function (chunk) {
|
|
this.tokenizer.write(chunk);
|
|
};
|
|
/**
|
|
* Parses the end of the buffer and clears the stack, calls onend.
|
|
*
|
|
* @param chunk Optional final chunk to parse.
|
|
*/
|
|
Parser.prototype.end = function (chunk) {
|
|
this.tokenizer.end(chunk);
|
|
};
|
|
/**
|
|
* Pauses parsing. The parser won't emit events until `resume` is called.
|
|
*/
|
|
Parser.prototype.pause = function () {
|
|
this.tokenizer.pause();
|
|
};
|
|
/**
|
|
* Resumes parsing after `pause` was called.
|
|
*/
|
|
Parser.prototype.resume = function () {
|
|
this.tokenizer.resume();
|
|
};
|
|
/**
|
|
* Alias of `write`, for backwards compatibility.
|
|
*
|
|
* @param chunk Chunk to parse.
|
|
* @deprecated
|
|
*/
|
|
Parser.prototype.parseChunk = function (chunk) {
|
|
this.write(chunk);
|
|
};
|
|
/**
|
|
* Alias of `end`, for backwards compatibility.
|
|
*
|
|
* @param chunk Optional final chunk to parse.
|
|
* @deprecated
|
|
*/
|
|
Parser.prototype.done = function (chunk) {
|
|
this.end(chunk);
|
|
};
|
|
return Parser;
|
|
}());
|
|
exports.Parser = Parser;
|
|
|
|
},{"./Tokenizer":57}],57:[function(require,module,exports){
|
|
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
var decode_codepoint_1 = __importDefault(require("entities/lib/decode_codepoint"));
|
|
var entities_json_1 = __importDefault(require("entities/lib/maps/entities.json"));
|
|
var legacy_json_1 = __importDefault(require("entities/lib/maps/legacy.json"));
|
|
var xml_json_1 = __importDefault(require("entities/lib/maps/xml.json"));
|
|
function whitespace(c) {
|
|
return c === " " || c === "\n" || c === "\t" || c === "\f" || c === "\r";
|
|
}
|
|
function isASCIIAlpha(c) {
|
|
return (c >= "a" && c <= "z") || (c >= "A" && c <= "Z");
|
|
}
|
|
function ifElseState(upper, SUCCESS, FAILURE) {
|
|
var lower = upper.toLowerCase();
|
|
if (upper === lower) {
|
|
return function (t, c) {
|
|
if (c === lower) {
|
|
t._state = SUCCESS;
|
|
}
|
|
else {
|
|
t._state = FAILURE;
|
|
t._index--;
|
|
}
|
|
};
|
|
}
|
|
return function (t, c) {
|
|
if (c === lower || c === upper) {
|
|
t._state = SUCCESS;
|
|
}
|
|
else {
|
|
t._state = FAILURE;
|
|
t._index--;
|
|
}
|
|
};
|
|
}
|
|
function consumeSpecialNameChar(upper, NEXT_STATE) {
|
|
var lower = upper.toLowerCase();
|
|
return function (t, c) {
|
|
if (c === lower || c === upper) {
|
|
t._state = NEXT_STATE;
|
|
}
|
|
else {
|
|
t._state = 3 /* InTagName */;
|
|
t._index--; // Consume the token again
|
|
}
|
|
};
|
|
}
|
|
var stateBeforeCdata1 = ifElseState("C", 24 /* BeforeCdata2 */, 16 /* InDeclaration */);
|
|
var stateBeforeCdata2 = ifElseState("D", 25 /* BeforeCdata3 */, 16 /* InDeclaration */);
|
|
var stateBeforeCdata3 = ifElseState("A", 26 /* BeforeCdata4 */, 16 /* InDeclaration */);
|
|
var stateBeforeCdata4 = ifElseState("T", 27 /* BeforeCdata5 */, 16 /* InDeclaration */);
|
|
var stateBeforeCdata5 = ifElseState("A", 28 /* BeforeCdata6 */, 16 /* InDeclaration */);
|
|
var stateBeforeScript1 = consumeSpecialNameChar("R", 35 /* BeforeScript2 */);
|
|
var stateBeforeScript2 = consumeSpecialNameChar("I", 36 /* BeforeScript3 */);
|
|
var stateBeforeScript3 = consumeSpecialNameChar("P", 37 /* BeforeScript4 */);
|
|
var stateBeforeScript4 = consumeSpecialNameChar("T", 38 /* BeforeScript5 */);
|
|
var stateAfterScript1 = ifElseState("R", 40 /* AfterScript2 */, 1 /* Text */);
|
|
var stateAfterScript2 = ifElseState("I", 41 /* AfterScript3 */, 1 /* Text */);
|
|
var stateAfterScript3 = ifElseState("P", 42 /* AfterScript4 */, 1 /* Text */);
|
|
var stateAfterScript4 = ifElseState("T", 43 /* AfterScript5 */, 1 /* Text */);
|
|
var stateBeforeStyle1 = consumeSpecialNameChar("Y", 45 /* BeforeStyle2 */);
|
|
var stateBeforeStyle2 = consumeSpecialNameChar("L", 46 /* BeforeStyle3 */);
|
|
var stateBeforeStyle3 = consumeSpecialNameChar("E", 47 /* BeforeStyle4 */);
|
|
var stateAfterStyle1 = ifElseState("Y", 49 /* AfterStyle2 */, 1 /* Text */);
|
|
var stateAfterStyle2 = ifElseState("L", 50 /* AfterStyle3 */, 1 /* Text */);
|
|
var stateAfterStyle3 = ifElseState("E", 51 /* AfterStyle4 */, 1 /* Text */);
|
|
var stateBeforeSpecialT = consumeSpecialNameChar("I", 54 /* BeforeTitle1 */);
|
|
var stateBeforeTitle1 = consumeSpecialNameChar("T", 55 /* BeforeTitle2 */);
|
|
var stateBeforeTitle2 = consumeSpecialNameChar("L", 56 /* BeforeTitle3 */);
|
|
var stateBeforeTitle3 = consumeSpecialNameChar("E", 57 /* BeforeTitle4 */);
|
|
var stateAfterSpecialTEnd = ifElseState("I", 58 /* AfterTitle1 */, 1 /* Text */);
|
|
var stateAfterTitle1 = ifElseState("T", 59 /* AfterTitle2 */, 1 /* Text */);
|
|
var stateAfterTitle2 = ifElseState("L", 60 /* AfterTitle3 */, 1 /* Text */);
|
|
var stateAfterTitle3 = ifElseState("E", 61 /* AfterTitle4 */, 1 /* Text */);
|
|
var stateBeforeEntity = ifElseState("#", 63 /* BeforeNumericEntity */, 64 /* InNamedEntity */);
|
|
var stateBeforeNumericEntity = ifElseState("X", 66 /* InHexEntity */, 65 /* InNumericEntity */);
|
|
var Tokenizer = /** @class */ (function () {
|
|
function Tokenizer(options, cbs) {
|
|
var _a;
|
|
/** The current state the tokenizer is in. */
|
|
this._state = 1 /* Text */;
|
|
/** The read buffer. */
|
|
this.buffer = "";
|
|
/** The beginning of the section that is currently being read. */
|
|
this.sectionStart = 0;
|
|
/** The index within the buffer that we are currently looking at. */
|
|
this._index = 0;
|
|
/**
|
|
* Data that has already been processed will be removed from the buffer occasionally.
|
|
* `_bufferOffset` keeps track of how many characters have been removed, to make sure position information is accurate.
|
|
*/
|
|
this.bufferOffset = 0;
|
|
/** Some behavior, eg. when decoding entities, is done while we are in another state. This keeps track of the other state type. */
|
|
this.baseState = 1 /* Text */;
|
|
/** For special parsing behavior inside of script and style tags. */
|
|
this.special = 1 /* None */;
|
|
/** Indicates whether the tokenizer has been paused. */
|
|
this.running = true;
|
|
/** Indicates whether the tokenizer has finished running / `.end` has been called. */
|
|
this.ended = false;
|
|
this.cbs = cbs;
|
|
this.xmlMode = !!(options === null || options === void 0 ? void 0 : options.xmlMode);
|
|
this.decodeEntities = (_a = options === null || options === void 0 ? void 0 : options.decodeEntities) !== null && _a !== void 0 ? _a : true;
|
|
}
|
|
Tokenizer.prototype.reset = function () {
|
|
this._state = 1 /* Text */;
|
|
this.buffer = "";
|
|
this.sectionStart = 0;
|
|
this._index = 0;
|
|
this.bufferOffset = 0;
|
|
this.baseState = 1 /* Text */;
|
|
this.special = 1 /* None */;
|
|
this.running = true;
|
|
this.ended = false;
|
|
};
|
|
Tokenizer.prototype.write = function (chunk) {
|
|
if (this.ended)
|
|
this.cbs.onerror(Error(".write() after done!"));
|
|
this.buffer += chunk;
|
|
this.parse();
|
|
};
|
|
Tokenizer.prototype.end = function (chunk) {
|
|
if (this.ended)
|
|
this.cbs.onerror(Error(".end() after done!"));
|
|
if (chunk)
|
|
this.write(chunk);
|
|
this.ended = true;
|
|
if (this.running)
|
|
this.finish();
|
|
};
|
|
Tokenizer.prototype.pause = function () {
|
|
this.running = false;
|
|
};
|
|
Tokenizer.prototype.resume = function () {
|
|
this.running = true;
|
|
if (this._index < this.buffer.length) {
|
|
this.parse();
|
|
}
|
|
if (this.ended) {
|
|
this.finish();
|
|
}
|
|
};
|
|
/**
|
|
* The current index within all of the written data.
|
|
*/
|
|
Tokenizer.prototype.getAbsoluteIndex = function () {
|
|
return this.bufferOffset + this._index;
|
|
};
|
|
Tokenizer.prototype.stateText = function (c) {
|
|
if (c === "<") {
|
|
if (this._index > this.sectionStart) {
|
|
this.cbs.ontext(this.getSection());
|
|
}
|
|
this._state = 2 /* BeforeTagName */;
|
|
this.sectionStart = this._index;
|
|
}
|
|
else if (this.decodeEntities &&
|
|
c === "&" &&
|
|
(this.special === 1 /* None */ || this.special === 4 /* Title */)) {
|
|
if (this._index > this.sectionStart) {
|
|
this.cbs.ontext(this.getSection());
|
|
}
|
|
this.baseState = 1 /* Text */;
|
|
this._state = 62 /* BeforeEntity */;
|
|
this.sectionStart = this._index;
|
|
}
|
|
};
|
|
/**
|
|
* HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a tag name.
|
|
*
|
|
* XML allows a lot more characters here (@see https://www.w3.org/TR/REC-xml/#NT-NameStartChar).
|
|
* We allow anything that wouldn't end the tag.
|
|
*/
|
|
Tokenizer.prototype.isTagStartChar = function (c) {
|
|
return (isASCIIAlpha(c) ||
|
|
(this.xmlMode && !whitespace(c) && c !== "/" && c !== ">"));
|
|
};
|
|
Tokenizer.prototype.stateBeforeTagName = function (c) {
|
|
if (c === "/") {
|
|
this._state = 5 /* BeforeClosingTagName */;
|
|
}
|
|
else if (c === "<") {
|
|
this.cbs.ontext(this.getSection());
|
|
this.sectionStart = this._index;
|
|
}
|
|
else if (c === ">" ||
|
|
this.special !== 1 /* None */ ||
|
|
whitespace(c)) {
|
|
this._state = 1 /* Text */;
|
|
}
|
|
else if (c === "!") {
|
|
this._state = 15 /* BeforeDeclaration */;
|
|
this.sectionStart = this._index + 1;
|
|
}
|
|
else if (c === "?") {
|
|
this._state = 17 /* InProcessingInstruction */;
|
|
this.sectionStart = this._index + 1;
|
|
}
|
|
else if (!this.isTagStartChar(c)) {
|
|
this._state = 1 /* Text */;
|
|
}
|
|
else {
|
|
this._state =
|
|
!this.xmlMode && (c === "s" || c === "S")
|
|
? 32 /* BeforeSpecialS */
|
|
: !this.xmlMode && (c === "t" || c === "T")
|
|
? 52 /* BeforeSpecialT */
|
|
: 3 /* InTagName */;
|
|
this.sectionStart = this._index;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateInTagName = function (c) {
|
|
if (c === "/" || c === ">" || whitespace(c)) {
|
|
this.emitToken("onopentagname");
|
|
this._state = 8 /* BeforeAttributeName */;
|
|
this._index--;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateBeforeClosingTagName = function (c) {
|
|
if (whitespace(c)) {
|
|
// Ignore
|
|
}
|
|
else if (c === ">") {
|
|
this._state = 1 /* Text */;
|
|
}
|
|
else if (this.special !== 1 /* None */) {
|
|
if (this.special !== 4 /* Title */ && (c === "s" || c === "S")) {
|
|
this._state = 33 /* BeforeSpecialSEnd */;
|
|
}
|
|
else if (this.special === 4 /* Title */ &&
|
|
(c === "t" || c === "T")) {
|
|
this._state = 53 /* BeforeSpecialTEnd */;
|
|
}
|
|
else {
|
|
this._state = 1 /* Text */;
|
|
this._index--;
|
|
}
|
|
}
|
|
else if (!this.isTagStartChar(c)) {
|
|
this._state = 20 /* InSpecialComment */;
|
|
this.sectionStart = this._index;
|
|
}
|
|
else {
|
|
this._state = 6 /* InClosingTagName */;
|
|
this.sectionStart = this._index;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateInClosingTagName = function (c) {
|
|
if (c === ">" || whitespace(c)) {
|
|
this.emitToken("onclosetag");
|
|
this._state = 7 /* AfterClosingTagName */;
|
|
this._index--;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateAfterClosingTagName = function (c) {
|
|
// Skip everything until ">"
|
|
if (c === ">") {
|
|
this._state = 1 /* Text */;
|
|
this.sectionStart = this._index + 1;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateBeforeAttributeName = function (c) {
|
|
if (c === ">") {
|
|
this.cbs.onopentagend();
|
|
this._state = 1 /* Text */;
|
|
this.sectionStart = this._index + 1;
|
|
}
|
|
else if (c === "/") {
|
|
this._state = 4 /* InSelfClosingTag */;
|
|
}
|
|
else if (!whitespace(c)) {
|
|
this._state = 9 /* InAttributeName */;
|
|
this.sectionStart = this._index;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateInSelfClosingTag = function (c) {
|
|
if (c === ">") {
|
|
this.cbs.onselfclosingtag();
|
|
this._state = 1 /* Text */;
|
|
this.sectionStart = this._index + 1;
|
|
this.special = 1 /* None */; // Reset special state, in case of self-closing special tags
|
|
}
|
|
else if (!whitespace(c)) {
|
|
this._state = 8 /* BeforeAttributeName */;
|
|
this._index--;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateInAttributeName = function (c) {
|
|
if (c === "=" || c === "/" || c === ">" || whitespace(c)) {
|
|
this.cbs.onattribname(this.getSection());
|
|
this.sectionStart = -1;
|
|
this._state = 10 /* AfterAttributeName */;
|
|
this._index--;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateAfterAttributeName = function (c) {
|
|
if (c === "=") {
|
|
this._state = 11 /* BeforeAttributeValue */;
|
|
}
|
|
else if (c === "/" || c === ">") {
|
|
this.cbs.onattribend(undefined);
|
|
this._state = 8 /* BeforeAttributeName */;
|
|
this._index--;
|
|
}
|
|
else if (!whitespace(c)) {
|
|
this.cbs.onattribend(undefined);
|
|
this._state = 9 /* InAttributeName */;
|
|
this.sectionStart = this._index;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateBeforeAttributeValue = function (c) {
|
|
if (c === '"') {
|
|
this._state = 12 /* InAttributeValueDq */;
|
|
this.sectionStart = this._index + 1;
|
|
}
|
|
else if (c === "'") {
|
|
this._state = 13 /* InAttributeValueSq */;
|
|
this.sectionStart = this._index + 1;
|
|
}
|
|
else if (!whitespace(c)) {
|
|
this._state = 14 /* InAttributeValueNq */;
|
|
this.sectionStart = this._index;
|
|
this._index--; // Reconsume token
|
|
}
|
|
};
|
|
Tokenizer.prototype.handleInAttributeValue = function (c, quote) {
|
|
if (c === quote) {
|
|
this.emitToken("onattribdata");
|
|
this.cbs.onattribend(quote);
|
|
this._state = 8 /* BeforeAttributeName */;
|
|
}
|
|
else if (this.decodeEntities && c === "&") {
|
|
this.emitToken("onattribdata");
|
|
this.baseState = this._state;
|
|
this._state = 62 /* BeforeEntity */;
|
|
this.sectionStart = this._index;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateInAttributeValueDoubleQuotes = function (c) {
|
|
this.handleInAttributeValue(c, '"');
|
|
};
|
|
Tokenizer.prototype.stateInAttributeValueSingleQuotes = function (c) {
|
|
this.handleInAttributeValue(c, "'");
|
|
};
|
|
Tokenizer.prototype.stateInAttributeValueNoQuotes = function (c) {
|
|
if (whitespace(c) || c === ">") {
|
|
this.emitToken("onattribdata");
|
|
this.cbs.onattribend(null);
|
|
this._state = 8 /* BeforeAttributeName */;
|
|
this._index--;
|
|
}
|
|
else if (this.decodeEntities && c === "&") {
|
|
this.emitToken("onattribdata");
|
|
this.baseState = this._state;
|
|
this._state = 62 /* BeforeEntity */;
|
|
this.sectionStart = this._index;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateBeforeDeclaration = function (c) {
|
|
this._state =
|
|
c === "["
|
|
? 23 /* BeforeCdata1 */
|
|
: c === "-"
|
|
? 18 /* BeforeComment */
|
|
: 16 /* InDeclaration */;
|
|
};
|
|
Tokenizer.prototype.stateInDeclaration = function (c) {
|
|
if (c === ">") {
|
|
this.cbs.ondeclaration(this.getSection());
|
|
this._state = 1 /* Text */;
|
|
this.sectionStart = this._index + 1;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateInProcessingInstruction = function (c) {
|
|
if (c === ">") {
|
|
this.cbs.onprocessinginstruction(this.getSection());
|
|
this._state = 1 /* Text */;
|
|
this.sectionStart = this._index + 1;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateBeforeComment = function (c) {
|
|
if (c === "-") {
|
|
this._state = 19 /* InComment */;
|
|
this.sectionStart = this._index + 1;
|
|
}
|
|
else {
|
|
this._state = 16 /* InDeclaration */;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateInComment = function (c) {
|
|
if (c === "-")
|
|
this._state = 21 /* AfterComment1 */;
|
|
};
|
|
Tokenizer.prototype.stateInSpecialComment = function (c) {
|
|
if (c === ">") {
|
|
this.cbs.oncomment(this.buffer.substring(this.sectionStart, this._index));
|
|
this._state = 1 /* Text */;
|
|
this.sectionStart = this._index + 1;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateAfterComment1 = function (c) {
|
|
if (c === "-") {
|
|
this._state = 22 /* AfterComment2 */;
|
|
}
|
|
else {
|
|
this._state = 19 /* InComment */;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateAfterComment2 = function (c) {
|
|
if (c === ">") {
|
|
// Remove 2 trailing chars
|
|
this.cbs.oncomment(this.buffer.substring(this.sectionStart, this._index - 2));
|
|
this._state = 1 /* Text */;
|
|
this.sectionStart = this._index + 1;
|
|
}
|
|
else if (c !== "-") {
|
|
this._state = 19 /* InComment */;
|
|
}
|
|
// Else: stay in AFTER_COMMENT_2 (`--->`)
|
|
};
|
|
Tokenizer.prototype.stateBeforeCdata6 = function (c) {
|
|
if (c === "[") {
|
|
this._state = 29 /* InCdata */;
|
|
this.sectionStart = this._index + 1;
|
|
}
|
|
else {
|
|
this._state = 16 /* InDeclaration */;
|
|
this._index--;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateInCdata = function (c) {
|
|
if (c === "]")
|
|
this._state = 30 /* AfterCdata1 */;
|
|
};
|
|
Tokenizer.prototype.stateAfterCdata1 = function (c) {
|
|
if (c === "]")
|
|
this._state = 31 /* AfterCdata2 */;
|
|
else
|
|
this._state = 29 /* InCdata */;
|
|
};
|
|
Tokenizer.prototype.stateAfterCdata2 = function (c) {
|
|
if (c === ">") {
|
|
// Remove 2 trailing chars
|
|
this.cbs.oncdata(this.buffer.substring(this.sectionStart, this._index - 2));
|
|
this._state = 1 /* Text */;
|
|
this.sectionStart = this._index + 1;
|
|
}
|
|
else if (c !== "]") {
|
|
this._state = 29 /* InCdata */;
|
|
}
|
|
// Else: stay in AFTER_CDATA_2 (`]]]>`)
|
|
};
|
|
Tokenizer.prototype.stateBeforeSpecialS = function (c) {
|
|
if (c === "c" || c === "C") {
|
|
this._state = 34 /* BeforeScript1 */;
|
|
}
|
|
else if (c === "t" || c === "T") {
|
|
this._state = 44 /* BeforeStyle1 */;
|
|
}
|
|
else {
|
|
this._state = 3 /* InTagName */;
|
|
this._index--; // Consume the token again
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateBeforeSpecialSEnd = function (c) {
|
|
if (this.special === 2 /* Script */ && (c === "c" || c === "C")) {
|
|
this._state = 39 /* AfterScript1 */;
|
|
}
|
|
else if (this.special === 3 /* Style */ && (c === "t" || c === "T")) {
|
|
this._state = 48 /* AfterStyle1 */;
|
|
}
|
|
else
|
|
this._state = 1 /* Text */;
|
|
};
|
|
Tokenizer.prototype.stateBeforeSpecialLast = function (c, special) {
|
|
if (c === "/" || c === ">" || whitespace(c)) {
|
|
this.special = special;
|
|
}
|
|
this._state = 3 /* InTagName */;
|
|
this._index--; // Consume the token again
|
|
};
|
|
Tokenizer.prototype.stateAfterSpecialLast = function (c, sectionStartOffset) {
|
|
if (c === ">" || whitespace(c)) {
|
|
this.special = 1 /* None */;
|
|
this._state = 6 /* InClosingTagName */;
|
|
this.sectionStart = this._index - sectionStartOffset;
|
|
this._index--; // Reconsume the token
|
|
}
|
|
else
|
|
this._state = 1 /* Text */;
|
|
};
|
|
// For entities terminated with a semicolon
|
|
Tokenizer.prototype.parseFixedEntity = function (map) {
|
|
if (map === void 0) { map = this.xmlMode ? xml_json_1.default : entities_json_1.default; }
|
|
// Offset = 1
|
|
if (this.sectionStart + 1 < this._index) {
|
|
var entity = this.buffer.substring(this.sectionStart + 1, this._index);
|
|
if (Object.prototype.hasOwnProperty.call(map, entity)) {
|
|
this.emitPartial(map[entity]);
|
|
this.sectionStart = this._index + 1;
|
|
}
|
|
}
|
|
};
|
|
// Parses legacy entities (without trailing semicolon)
|
|
Tokenizer.prototype.parseLegacyEntity = function () {
|
|
var start = this.sectionStart + 1;
|
|
// The max length of legacy entities is 6
|
|
var limit = Math.min(this._index - start, 6);
|
|
while (limit >= 2) {
|
|
// The min length of legacy entities is 2
|
|
var entity = this.buffer.substr(start, limit);
|
|
if (Object.prototype.hasOwnProperty.call(legacy_json_1.default, entity)) {
|
|
this.emitPartial(legacy_json_1.default[entity]);
|
|
this.sectionStart += limit + 1;
|
|
return;
|
|
}
|
|
limit--;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateInNamedEntity = function (c) {
|
|
if (c === ";") {
|
|
this.parseFixedEntity();
|
|
// Retry as legacy entity if entity wasn't parsed
|
|
if (this.baseState === 1 /* Text */ &&
|
|
this.sectionStart + 1 < this._index &&
|
|
!this.xmlMode) {
|
|
this.parseLegacyEntity();
|
|
}
|
|
this._state = this.baseState;
|
|
}
|
|
else if ((c < "0" || c > "9") && !isASCIIAlpha(c)) {
|
|
if (this.xmlMode || this.sectionStart + 1 === this._index) {
|
|
// Ignore
|
|
}
|
|
else if (this.baseState !== 1 /* Text */) {
|
|
if (c !== "=") {
|
|
// Parse as legacy entity, without allowing additional characters.
|
|
this.parseFixedEntity(legacy_json_1.default);
|
|
}
|
|
}
|
|
else {
|
|
this.parseLegacyEntity();
|
|
}
|
|
this._state = this.baseState;
|
|
this._index--;
|
|
}
|
|
};
|
|
Tokenizer.prototype.decodeNumericEntity = function (offset, base, strict) {
|
|
var sectionStart = this.sectionStart + offset;
|
|
if (sectionStart !== this._index) {
|
|
// Parse entity
|
|
var entity = this.buffer.substring(sectionStart, this._index);
|
|
var parsed = parseInt(entity, base);
|
|
this.emitPartial(decode_codepoint_1.default(parsed));
|
|
this.sectionStart = strict ? this._index + 1 : this._index;
|
|
}
|
|
this._state = this.baseState;
|
|
};
|
|
Tokenizer.prototype.stateInNumericEntity = function (c) {
|
|
if (c === ";") {
|
|
this.decodeNumericEntity(2, 10, true);
|
|
}
|
|
else if (c < "0" || c > "9") {
|
|
if (!this.xmlMode) {
|
|
this.decodeNumericEntity(2, 10, false);
|
|
}
|
|
else {
|
|
this._state = this.baseState;
|
|
}
|
|
this._index--;
|
|
}
|
|
};
|
|
Tokenizer.prototype.stateInHexEntity = function (c) {
|
|
if (c === ";") {
|
|
this.decodeNumericEntity(3, 16, true);
|
|
}
|
|
else if ((c < "a" || c > "f") &&
|
|
(c < "A" || c > "F") &&
|
|
(c < "0" || c > "9")) {
|
|
if (!this.xmlMode) {
|
|
this.decodeNumericEntity(3, 16, false);
|
|
}
|
|
else {
|
|
this._state = this.baseState;
|
|
}
|
|
this._index--;
|
|
}
|
|
};
|
|
Tokenizer.prototype.cleanup = function () {
|
|
if (this.sectionStart < 0) {
|
|
this.buffer = "";
|
|
this.bufferOffset += this._index;
|
|
this._index = 0;
|
|
}
|
|
else if (this.running) {
|
|
if (this._state === 1 /* Text */) {
|
|
if (this.sectionStart !== this._index) {
|
|
this.cbs.ontext(this.buffer.substr(this.sectionStart));
|
|
}
|
|
this.buffer = "";
|
|
this.bufferOffset += this._index;
|
|
this._index = 0;
|
|
}
|
|
else if (this.sectionStart === this._index) {
|
|
// The section just started
|
|
this.buffer = "";
|
|
this.bufferOffset += this._index;
|
|
this._index = 0;
|
|
}
|
|
else {
|
|
// Remove everything unnecessary
|
|
this.buffer = this.buffer.substr(this.sectionStart);
|
|
this._index -= this.sectionStart;
|
|
this.bufferOffset += this.sectionStart;
|
|
}
|
|
this.sectionStart = 0;
|
|
}
|
|
};
|
|
/**
|
|
* Iterates through the buffer, calling the function corresponding to the current state.
|
|
*
|
|
* States that are more likely to be hit are higher up, as a performance improvement.
|
|
*/
|
|
Tokenizer.prototype.parse = function () {
|
|
while (this._index < this.buffer.length && this.running) {
|
|
var c = this.buffer.charAt(this._index);
|
|
if (this._state === 1 /* Text */) {
|
|
this.stateText(c);
|
|
}
|
|
else if (this._state === 12 /* InAttributeValueDq */) {
|
|
this.stateInAttributeValueDoubleQuotes(c);
|
|
}
|
|
else if (this._state === 9 /* InAttributeName */) {
|
|
this.stateInAttributeName(c);
|
|
}
|
|
else if (this._state === 19 /* InComment */) {
|
|
this.stateInComment(c);
|
|
}
|
|
else if (this._state === 20 /* InSpecialComment */) {
|
|
this.stateInSpecialComment(c);
|
|
}
|
|
else if (this._state === 8 /* BeforeAttributeName */) {
|
|
this.stateBeforeAttributeName(c);
|
|
}
|
|
else if (this._state === 3 /* InTagName */) {
|
|
this.stateInTagName(c);
|
|
}
|
|
else if (this._state === 6 /* InClosingTagName */) {
|
|
this.stateInClosingTagName(c);
|
|
}
|
|
else if (this._state === 2 /* BeforeTagName */) {
|
|
this.stateBeforeTagName(c);
|
|
}
|
|
else if (this._state === 10 /* AfterAttributeName */) {
|
|
this.stateAfterAttributeName(c);
|
|
}
|
|
else if (this._state === 13 /* InAttributeValueSq */) {
|
|
this.stateInAttributeValueSingleQuotes(c);
|
|
}
|
|
else if (this._state === 11 /* BeforeAttributeValue */) {
|
|
this.stateBeforeAttributeValue(c);
|
|
}
|
|
else if (this._state === 5 /* BeforeClosingTagName */) {
|
|
this.stateBeforeClosingTagName(c);
|
|
}
|
|
else if (this._state === 7 /* AfterClosingTagName */) {
|
|
this.stateAfterClosingTagName(c);
|
|
}
|
|
else if (this._state === 32 /* BeforeSpecialS */) {
|
|
this.stateBeforeSpecialS(c);
|
|
}
|
|
else if (this._state === 21 /* AfterComment1 */) {
|
|
this.stateAfterComment1(c);
|
|
}
|
|
else if (this._state === 14 /* InAttributeValueNq */) {
|
|
this.stateInAttributeValueNoQuotes(c);
|
|
}
|
|
else if (this._state === 4 /* InSelfClosingTag */) {
|
|
this.stateInSelfClosingTag(c);
|
|
}
|
|
else if (this._state === 16 /* InDeclaration */) {
|
|
this.stateInDeclaration(c);
|
|
}
|
|
else if (this._state === 15 /* BeforeDeclaration */) {
|
|
this.stateBeforeDeclaration(c);
|
|
}
|
|
else if (this._state === 22 /* AfterComment2 */) {
|
|
this.stateAfterComment2(c);
|
|
}
|
|
else if (this._state === 18 /* BeforeComment */) {
|
|
this.stateBeforeComment(c);
|
|
}
|
|
else if (this._state === 33 /* BeforeSpecialSEnd */) {
|
|
this.stateBeforeSpecialSEnd(c);
|
|
}
|
|
else if (this._state === 53 /* BeforeSpecialTEnd */) {
|
|
stateAfterSpecialTEnd(this, c);
|
|
}
|
|
else if (this._state === 39 /* AfterScript1 */) {
|
|
stateAfterScript1(this, c);
|
|
}
|
|
else if (this._state === 40 /* AfterScript2 */) {
|
|
stateAfterScript2(this, c);
|
|
}
|
|
else if (this._state === 41 /* AfterScript3 */) {
|
|
stateAfterScript3(this, c);
|
|
}
|
|
else if (this._state === 34 /* BeforeScript1 */) {
|
|
stateBeforeScript1(this, c);
|
|
}
|
|
else if (this._state === 35 /* BeforeScript2 */) {
|
|
stateBeforeScript2(this, c);
|
|
}
|
|
else if (this._state === 36 /* BeforeScript3 */) {
|
|
stateBeforeScript3(this, c);
|
|
}
|
|
else if (this._state === 37 /* BeforeScript4 */) {
|
|
stateBeforeScript4(this, c);
|
|
}
|
|
else if (this._state === 38 /* BeforeScript5 */) {
|
|
this.stateBeforeSpecialLast(c, 2 /* Script */);
|
|
}
|
|
else if (this._state === 42 /* AfterScript4 */) {
|
|
stateAfterScript4(this, c);
|
|
}
|
|
else if (this._state === 43 /* AfterScript5 */) {
|
|
this.stateAfterSpecialLast(c, 6);
|
|
}
|
|
else if (this._state === 44 /* BeforeStyle1 */) {
|
|
stateBeforeStyle1(this, c);
|
|
}
|
|
else if (this._state === 29 /* InCdata */) {
|
|
this.stateInCdata(c);
|
|
}
|
|
else if (this._state === 45 /* BeforeStyle2 */) {
|
|
stateBeforeStyle2(this, c);
|
|
}
|
|
else if (this._state === 46 /* BeforeStyle3 */) {
|
|
stateBeforeStyle3(this, c);
|
|
}
|
|
else if (this._state === 47 /* BeforeStyle4 */) {
|
|
this.stateBeforeSpecialLast(c, 3 /* Style */);
|
|
}
|
|
else if (this._state === 48 /* AfterStyle1 */) {
|
|
stateAfterStyle1(this, c);
|
|
}
|
|
else if (this._state === 49 /* AfterStyle2 */) {
|
|
stateAfterStyle2(this, c);
|
|
}
|
|
else if (this._state === 50 /* AfterStyle3 */) {
|
|
stateAfterStyle3(this, c);
|
|
}
|
|
else if (this._state === 51 /* AfterStyle4 */) {
|
|
this.stateAfterSpecialLast(c, 5);
|
|
}
|
|
else if (this._state === 52 /* BeforeSpecialT */) {
|
|
stateBeforeSpecialT(this, c);
|
|
}
|
|
else if (this._state === 54 /* BeforeTitle1 */) {
|
|
stateBeforeTitle1(this, c);
|
|
}
|
|
else if (this._state === 55 /* BeforeTitle2 */) {
|
|
stateBeforeTitle2(this, c);
|
|
}
|
|
else if (this._state === 56 /* BeforeTitle3 */) {
|
|
stateBeforeTitle3(this, c);
|
|
}
|
|
else if (this._state === 57 /* BeforeTitle4 */) {
|
|
this.stateBeforeSpecialLast(c, 4 /* Title */);
|
|
}
|
|
else if (this._state === 58 /* AfterTitle1 */) {
|
|
stateAfterTitle1(this, c);
|
|
}
|
|
else if (this._state === 59 /* AfterTitle2 */) {
|
|
stateAfterTitle2(this, c);
|
|
}
|
|
else if (this._state === 60 /* AfterTitle3 */) {
|
|
stateAfterTitle3(this, c);
|
|
}
|
|
else if (this._state === 61 /* AfterTitle4 */) {
|
|
this.stateAfterSpecialLast(c, 5);
|
|
}
|
|
else if (this._state === 17 /* InProcessingInstruction */) {
|
|
this.stateInProcessingInstruction(c);
|
|
}
|
|
else if (this._state === 64 /* InNamedEntity */) {
|
|
this.stateInNamedEntity(c);
|
|
}
|
|
else if (this._state === 23 /* BeforeCdata1 */) {
|
|
stateBeforeCdata1(this, c);
|
|
}
|
|
else if (this._state === 62 /* BeforeEntity */) {
|
|
stateBeforeEntity(this, c);
|
|
}
|
|
else if (this._state === 24 /* BeforeCdata2 */) {
|
|
stateBeforeCdata2(this, c);
|
|
}
|
|
else if (this._state === 25 /* BeforeCdata3 */) {
|
|
stateBeforeCdata3(this, c);
|
|
}
|
|
else if (this._state === 30 /* AfterCdata1 */) {
|
|
this.stateAfterCdata1(c);
|
|
}
|
|
else if (this._state === 31 /* AfterCdata2 */) {
|
|
this.stateAfterCdata2(c);
|
|
}
|
|
else if (this._state === 26 /* BeforeCdata4 */) {
|
|
stateBeforeCdata4(this, c);
|
|
}
|
|
else if (this._state === 27 /* BeforeCdata5 */) {
|
|
stateBeforeCdata5(this, c);
|
|
}
|
|
else if (this._state === 28 /* BeforeCdata6 */) {
|
|
this.stateBeforeCdata6(c);
|
|
}
|
|
else if (this._state === 66 /* InHexEntity */) {
|
|
this.stateInHexEntity(c);
|
|
}
|
|
else if (this._state === 65 /* InNumericEntity */) {
|
|
this.stateInNumericEntity(c);
|
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
}
|
|
else if (this._state === 63 /* BeforeNumericEntity */) {
|
|
stateBeforeNumericEntity(this, c);
|
|
}
|
|
else {
|
|
this.cbs.onerror(Error("unknown _state"), this._state);
|
|
}
|
|
this._index++;
|
|
}
|
|
this.cleanup();
|
|
};
|
|
Tokenizer.prototype.finish = function () {
|
|
// If there is remaining data, emit it in a reasonable way
|
|
if (this.sectionStart < this._index) {
|
|
this.handleTrailingData();
|
|
}
|
|
this.cbs.onend();
|
|
};
|
|
Tokenizer.prototype.handleTrailingData = function () {
|
|
var data = this.buffer.substr(this.sectionStart);
|
|
if (this._state === 29 /* InCdata */ ||
|
|
this._state === 30 /* AfterCdata1 */ ||
|
|
this._state === 31 /* AfterCdata2 */) {
|
|
this.cbs.oncdata(data);
|
|
}
|
|
else if (this._state === 19 /* InComment */ ||
|
|
this._state === 21 /* AfterComment1 */ ||
|
|
this._state === 22 /* AfterComment2 */) {
|
|
this.cbs.oncomment(data);
|
|
}
|
|
else if (this._state === 64 /* InNamedEntity */ && !this.xmlMode) {
|
|
this.parseLegacyEntity();
|
|
if (this.sectionStart < this._index) {
|
|
this._state = this.baseState;
|
|
this.handleTrailingData();
|
|
}
|
|
}
|
|
else if (this._state === 65 /* InNumericEntity */ && !this.xmlMode) {
|
|
this.decodeNumericEntity(2, 10, false);
|
|
if (this.sectionStart < this._index) {
|
|
this._state = this.baseState;
|
|
this.handleTrailingData();
|
|
}
|
|
}
|
|
else if (this._state === 66 /* InHexEntity */ && !this.xmlMode) {
|
|
this.decodeNumericEntity(3, 16, false);
|
|
if (this.sectionStart < this._index) {
|
|
this._state = this.baseState;
|
|
this.handleTrailingData();
|
|
}
|
|
}
|
|
else if (this._state !== 3 /* InTagName */ &&
|
|
this._state !== 8 /* BeforeAttributeName */ &&
|
|
this._state !== 11 /* BeforeAttributeValue */ &&
|
|
this._state !== 10 /* AfterAttributeName */ &&
|
|
this._state !== 9 /* InAttributeName */ &&
|
|
this._state !== 13 /* InAttributeValueSq */ &&
|
|
this._state !== 12 /* InAttributeValueDq */ &&
|
|
this._state !== 14 /* InAttributeValueNq */ &&
|
|
this._state !== 6 /* InClosingTagName */) {
|
|
this.cbs.ontext(data);
|
|
}
|
|
/*
|
|
* Else, ignore remaining data
|
|
* TODO add a way to remove current tag
|
|
*/
|
|
};
|
|
Tokenizer.prototype.getSection = function () {
|
|
return this.buffer.substring(this.sectionStart, this._index);
|
|
};
|
|
Tokenizer.prototype.emitToken = function (name) {
|
|
this.cbs[name](this.getSection());
|
|
this.sectionStart = -1;
|
|
};
|
|
Tokenizer.prototype.emitPartial = function (value) {
|
|
if (this.baseState !== 1 /* Text */) {
|
|
this.cbs.onattribdata(value); // TODO implement the new event
|
|
}
|
|
else {
|
|
this.cbs.ontext(value);
|
|
}
|
|
};
|
|
return Tokenizer;
|
|
}());
|
|
exports.default = Tokenizer;
|
|
|
|
},{"entities/lib/decode_codepoint":48,"entities/lib/maps/entities.json":52,"entities/lib/maps/legacy.json":53,"entities/lib/maps/xml.json":54}],58:[function(require,module,exports){
|
|
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
};
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.RssHandler = exports.DefaultHandler = exports.DomUtils = exports.ElementType = exports.Tokenizer = exports.createDomStream = exports.parseDOM = exports.parseDocument = exports.DomHandler = exports.Parser = void 0;
|
|
var Parser_1 = require("./Parser");
|
|
Object.defineProperty(exports, "Parser", { enumerable: true, get: function () { return Parser_1.Parser; } });
|
|
var domhandler_1 = require("domhandler");
|
|
Object.defineProperty(exports, "DomHandler", { enumerable: true, get: function () { return domhandler_1.DomHandler; } });
|
|
Object.defineProperty(exports, "DefaultHandler", { enumerable: true, get: function () { return domhandler_1.DomHandler; } });
|
|
// Helper methods
|
|
/**
|
|
* Parses the data, returns the resulting document.
|
|
*
|
|
* @param data The data that should be parsed.
|
|
* @param options Optional options for the parser and DOM builder.
|
|
*/
|
|
function parseDocument(data, options) {
|
|
var handler = new domhandler_1.DomHandler(undefined, options);
|
|
new Parser_1.Parser(handler, options).end(data);
|
|
return handler.root;
|
|
}
|
|
exports.parseDocument = parseDocument;
|
|
/**
|
|
* Parses data, returns an array of the root nodes.
|
|
*
|
|
* Note that the root nodes still have a `Document` node as their parent.
|
|
* Use `parseDocument` to get the `Document` node instead.
|
|
*
|
|
* @param data The data that should be parsed.
|
|
* @param options Optional options for the parser and DOM builder.
|
|
* @deprecated Use `parseDocument` instead.
|
|
*/
|
|
function parseDOM(data, options) {
|
|
return parseDocument(data, options).children;
|
|
}
|
|
exports.parseDOM = parseDOM;
|
|
/**
|
|
* Creates a parser instance, with an attached DOM handler.
|
|
*
|
|
* @param cb A callback that will be called once parsing has been completed.
|
|
* @param options Optional options for the parser and DOM builder.
|
|
* @param elementCb An optional callback that will be called every time a tag has been completed inside of the DOM.
|
|
*/
|
|
function createDomStream(cb, options, elementCb) {
|
|
var handler = new domhandler_1.DomHandler(cb, options, elementCb);
|
|
return new Parser_1.Parser(handler, options);
|
|
}
|
|
exports.createDomStream = createDomStream;
|
|
var Tokenizer_1 = require("./Tokenizer");
|
|
Object.defineProperty(exports, "Tokenizer", { enumerable: true, get: function () { return __importDefault(Tokenizer_1).default; } });
|
|
var ElementType = __importStar(require("domelementtype"));
|
|
exports.ElementType = ElementType;
|
|
/*
|
|
* All of the following exports exist for backwards-compatibility.
|
|
* They should probably be removed eventually.
|
|
*/
|
|
__exportStar(require("./FeedHandler"), exports);
|
|
exports.DomUtils = __importStar(require("domutils"));
|
|
var FeedHandler_1 = require("./FeedHandler");
|
|
Object.defineProperty(exports, "RssHandler", { enumerable: true, get: function () { return FeedHandler_1.FeedHandler; } });
|
|
|
|
},{"./FeedHandler":55,"./Parser":56,"./Tokenizer":57,"domelementtype":37,"domhandler":38,"domutils":41}],59:[function(require,module,exports){
|
|
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
|
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
|
|
var e, m
|
|
var eLen = (nBytes * 8) - mLen - 1
|
|
var eMax = (1 << eLen) - 1
|
|
var eBias = eMax >> 1
|
|
var nBits = -7
|
|
var i = isLE ? (nBytes - 1) : 0
|
|
var d = isLE ? -1 : 1
|
|
var s = buffer[offset + i]
|
|
|
|
i += d
|
|
|
|
e = s & ((1 << (-nBits)) - 1)
|
|
s >>= (-nBits)
|
|
nBits += eLen
|
|
for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
|
|
|
|
m = e & ((1 << (-nBits)) - 1)
|
|
e >>= (-nBits)
|
|
nBits += mLen
|
|
for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
|
|
|
|
if (e === 0) {
|
|
e = 1 - eBias
|
|
} else if (e === eMax) {
|
|
return m ? NaN : ((s ? -1 : 1) * Infinity)
|
|
} else {
|
|
m = m + Math.pow(2, mLen)
|
|
e = e - eBias
|
|
}
|
|
return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
|
|
}
|
|
|
|
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
|
|
var e, m, c
|
|
var eLen = (nBytes * 8) - mLen - 1
|
|
var eMax = (1 << eLen) - 1
|
|
var eBias = eMax >> 1
|
|
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
|
|
var i = isLE ? 0 : (nBytes - 1)
|
|
var d = isLE ? 1 : -1
|
|
var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
|
|
|
|
value = Math.abs(value)
|
|
|
|
if (isNaN(value) || value === Infinity) {
|
|
m = isNaN(value) ? 1 : 0
|
|
e = eMax
|
|
} else {
|
|
e = Math.floor(Math.log(value) / Math.LN2)
|
|
if (value * (c = Math.pow(2, -e)) < 1) {
|
|
e--
|
|
c *= 2
|
|
}
|
|
if (e + eBias >= 1) {
|
|
value += rt / c
|
|
} else {
|
|
value += rt * Math.pow(2, 1 - eBias)
|
|
}
|
|
if (value * c >= 2) {
|
|
e++
|
|
c /= 2
|
|
}
|
|
|
|
if (e + eBias >= eMax) {
|
|
m = 0
|
|
e = eMax
|
|
} else if (e + eBias >= 1) {
|
|
m = ((value * c) - 1) * Math.pow(2, mLen)
|
|
e = e + eBias
|
|
} else {
|
|
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
|
|
e = 0
|
|
}
|
|
}
|
|
|
|
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
|
|
|
|
e = (e << mLen) | m
|
|
eLen += mLen
|
|
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
|
|
|
|
buffer[offset + i - d] |= s * 128
|
|
}
|
|
|
|
},{}],60:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.compile = void 0;
|
|
var boolbase_1 = require("boolbase");
|
|
/**
|
|
* Returns a function that checks if an elements index matches the given rule
|
|
* highly optimized to return the fastest solution.
|
|
*
|
|
* @param parsed A tuple [a, b], as returned by `parse`.
|
|
* @returns A highly optimized function that returns whether an index matches the nth-check.
|
|
* @example
|
|
* const check = nthCheck.compile([2, 3]);
|
|
*
|
|
* check(0); // `false`
|
|
* check(1); // `false`
|
|
* check(2); // `true`
|
|
* check(3); // `false`
|
|
* check(4); // `true`
|
|
* check(5); // `false`
|
|
* check(6); // `true`
|
|
*/
|
|
function compile(parsed) {
|
|
var a = parsed[0];
|
|
// Subtract 1 from `b`, to convert from one- to zero-indexed.
|
|
var b = parsed[1] - 1;
|
|
/*
|
|
* When `b <= 0`, `a * n` won't be lead to any matches for `a < 0`.
|
|
* Besides, the specification states that no elements are
|
|
* matched when `a` and `b` are 0.
|
|
*
|
|
* `b < 0` here as we subtracted 1 from `b` above.
|
|
*/
|
|
if (b < 0 && a <= 0)
|
|
return boolbase_1.falseFunc;
|
|
// When `a` is in the range -1..1, it matches any element (so only `b` is checked).
|
|
if (a === -1)
|
|
return function (index) { return index <= b; };
|
|
if (a === 0)
|
|
return function (index) { return index === b; };
|
|
// When `b <= 0` and `a === 1`, they match any element.
|
|
if (a === 1)
|
|
return b < 0 ? boolbase_1.trueFunc : function (index) { return index >= b; };
|
|
/*
|
|
* Otherwise, modulo can be used to check if there is a match.
|
|
*
|
|
* Modulo doesn't care about the sign, so let's use `a`s absolute value.
|
|
*/
|
|
var absA = Math.abs(a);
|
|
// Get `b mod a`, + a if this is negative.
|
|
var bMod = ((b % absA) + absA) % absA;
|
|
return a > 1
|
|
? function (index) { return index >= b && index % absA === bMod; }
|
|
: function (index) { return index <= b && index % absA === bMod; };
|
|
}
|
|
exports.compile = compile;
|
|
|
|
},{"boolbase":2}],61:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.compile = exports.parse = void 0;
|
|
var parse_1 = require("./parse");
|
|
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return parse_1.parse; } });
|
|
var compile_1 = require("./compile");
|
|
Object.defineProperty(exports, "compile", { enumerable: true, get: function () { return compile_1.compile; } });
|
|
/**
|
|
* Parses and compiles a formula to a highly optimized function.
|
|
* Combination of `parse` and `compile`.
|
|
*
|
|
* If the formula doesn't match any elements,
|
|
* it returns [`boolbase`](https://github.com/fb55/boolbase)'s `falseFunc`.
|
|
* Otherwise, a function accepting an _index_ is returned, which returns
|
|
* whether or not the passed _index_ matches the formula.
|
|
*
|
|
* Note: The nth-rule starts counting at `1`, the returned function at `0`.
|
|
*
|
|
* @param formula The formula to compile.
|
|
* @example
|
|
* const check = nthCheck("2n+3");
|
|
*
|
|
* check(0); // `false`
|
|
* check(1); // `false`
|
|
* check(2); // `true`
|
|
* check(3); // `false`
|
|
* check(4); // `true`
|
|
* check(5); // `false`
|
|
* check(6); // `true`
|
|
*/
|
|
function nthCheck(formula) {
|
|
return compile_1.compile(parse_1.parse(formula));
|
|
}
|
|
exports.default = nthCheck;
|
|
|
|
},{"./compile":60,"./parse":62}],62:[function(require,module,exports){
|
|
"use strict";
|
|
// Following http://www.w3.org/TR/css3-selectors/#nth-child-pseudo
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.parse = void 0;
|
|
// [ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]?
|
|
var RE_NTH_ELEMENT = /^([+-]?\d*n)?\s*(?:([+-]?)\s*(\d+))?$/;
|
|
/**
|
|
* Parses an expression.
|
|
*
|
|
* @throws An `Error` if parsing fails.
|
|
* @returns An array containing the integer step size and the integer offset of the nth rule.
|
|
* @example nthCheck.parse("2n+3"); // returns [2, 3]
|
|
*/
|
|
function parse(formula) {
|
|
formula = formula.trim().toLowerCase();
|
|
if (formula === "even") {
|
|
return [2, 0];
|
|
}
|
|
else if (formula === "odd") {
|
|
return [2, 1];
|
|
}
|
|
var parsed = formula.match(RE_NTH_ELEMENT);
|
|
if (!parsed) {
|
|
throw new Error("n-th rule couldn't be parsed ('" + formula + "')");
|
|
}
|
|
var a;
|
|
if (parsed[1]) {
|
|
a = parseInt(parsed[1], 10);
|
|
if (isNaN(a)) {
|
|
a = parsed[1].startsWith("-") ? -1 : 1;
|
|
}
|
|
}
|
|
else
|
|
a = 0;
|
|
var b = (parsed[2] === "-" ? -1 : 1) *
|
|
(parsed[3] ? parseInt(parsed[3], 10) : 0);
|
|
return [a, b];
|
|
}
|
|
exports.parse = parse;
|
|
|
|
},{}],63:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const doctype = require('parse5/lib/common/doctype');
|
|
const { DOCUMENT_MODE } = require('parse5/lib/common/html');
|
|
|
|
//Conversion tables for DOM Level1 structure emulation
|
|
const nodeTypes = {
|
|
element: 1,
|
|
text: 3,
|
|
cdata: 4,
|
|
comment: 8
|
|
};
|
|
|
|
const nodePropertyShorthands = {
|
|
tagName: 'name',
|
|
childNodes: 'children',
|
|
parentNode: 'parent',
|
|
previousSibling: 'prev',
|
|
nextSibling: 'next',
|
|
nodeValue: 'data'
|
|
};
|
|
|
|
//Node
|
|
class Node {
|
|
constructor(props) {
|
|
for (const key of Object.keys(props)) {
|
|
this[key] = props[key];
|
|
}
|
|
}
|
|
|
|
get firstChild() {
|
|
const children = this.children;
|
|
|
|
return (children && children[0]) || null;
|
|
}
|
|
|
|
get lastChild() {
|
|
const children = this.children;
|
|
|
|
return (children && children[children.length - 1]) || null;
|
|
}
|
|
|
|
get nodeType() {
|
|
return nodeTypes[this.type] || nodeTypes.element;
|
|
}
|
|
}
|
|
|
|
Object.keys(nodePropertyShorthands).forEach(key => {
|
|
const shorthand = nodePropertyShorthands[key];
|
|
|
|
Object.defineProperty(Node.prototype, key, {
|
|
get: function() {
|
|
return this[shorthand] || null;
|
|
},
|
|
set: function(val) {
|
|
this[shorthand] = val;
|
|
return val;
|
|
}
|
|
});
|
|
});
|
|
|
|
//Node construction
|
|
exports.createDocument = function() {
|
|
return new Node({
|
|
type: 'root',
|
|
name: 'root',
|
|
parent: null,
|
|
prev: null,
|
|
next: null,
|
|
children: [],
|
|
'x-mode': DOCUMENT_MODE.NO_QUIRKS
|
|
});
|
|
};
|
|
|
|
exports.createDocumentFragment = function() {
|
|
return new Node({
|
|
type: 'root',
|
|
name: 'root',
|
|
parent: null,
|
|
prev: null,
|
|
next: null,
|
|
children: []
|
|
});
|
|
};
|
|
|
|
exports.createElement = function(tagName, namespaceURI, attrs) {
|
|
const attribs = Object.create(null);
|
|
const attribsNamespace = Object.create(null);
|
|
const attribsPrefix = Object.create(null);
|
|
|
|
for (let i = 0; i < attrs.length; i++) {
|
|
const attrName = attrs[i].name;
|
|
|
|
attribs[attrName] = attrs[i].value;
|
|
attribsNamespace[attrName] = attrs[i].namespace;
|
|
attribsPrefix[attrName] = attrs[i].prefix;
|
|
}
|
|
|
|
return new Node({
|
|
type: tagName === 'script' || tagName === 'style' ? tagName : 'tag',
|
|
name: tagName,
|
|
namespace: namespaceURI,
|
|
attribs: attribs,
|
|
'x-attribsNamespace': attribsNamespace,
|
|
'x-attribsPrefix': attribsPrefix,
|
|
children: [],
|
|
parent: null,
|
|
prev: null,
|
|
next: null
|
|
});
|
|
};
|
|
|
|
exports.createCommentNode = function(data) {
|
|
return new Node({
|
|
type: 'comment',
|
|
data: data,
|
|
parent: null,
|
|
prev: null,
|
|
next: null
|
|
});
|
|
};
|
|
|
|
const createTextNode = function(value) {
|
|
return new Node({
|
|
type: 'text',
|
|
data: value,
|
|
parent: null,
|
|
prev: null,
|
|
next: null
|
|
});
|
|
};
|
|
|
|
//Tree mutation
|
|
const appendChild = (exports.appendChild = function(parentNode, newNode) {
|
|
const prev = parentNode.children[parentNode.children.length - 1];
|
|
|
|
if (prev) {
|
|
prev.next = newNode;
|
|
newNode.prev = prev;
|
|
}
|
|
|
|
parentNode.children.push(newNode);
|
|
newNode.parent = parentNode;
|
|
});
|
|
|
|
const insertBefore = (exports.insertBefore = function(parentNode, newNode, referenceNode) {
|
|
const insertionIdx = parentNode.children.indexOf(referenceNode);
|
|
const prev = referenceNode.prev;
|
|
|
|
if (prev) {
|
|
prev.next = newNode;
|
|
newNode.prev = prev;
|
|
}
|
|
|
|
referenceNode.prev = newNode;
|
|
newNode.next = referenceNode;
|
|
|
|
parentNode.children.splice(insertionIdx, 0, newNode);
|
|
newNode.parent = parentNode;
|
|
});
|
|
|
|
exports.setTemplateContent = function(templateElement, contentElement) {
|
|
appendChild(templateElement, contentElement);
|
|
};
|
|
|
|
exports.getTemplateContent = function(templateElement) {
|
|
return templateElement.children[0];
|
|
};
|
|
|
|
exports.setDocumentType = function(document, name, publicId, systemId) {
|
|
const data = doctype.serializeContent(name, publicId, systemId);
|
|
let doctypeNode = null;
|
|
|
|
for (let i = 0; i < document.children.length; i++) {
|
|
if (document.children[i].type === 'directive' && document.children[i].name === '!doctype') {
|
|
doctypeNode = document.children[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (doctypeNode) {
|
|
doctypeNode.data = data;
|
|
doctypeNode['x-name'] = name;
|
|
doctypeNode['x-publicId'] = publicId;
|
|
doctypeNode['x-systemId'] = systemId;
|
|
} else {
|
|
appendChild(
|
|
document,
|
|
new Node({
|
|
type: 'directive',
|
|
name: '!doctype',
|
|
data: data,
|
|
'x-name': name,
|
|
'x-publicId': publicId,
|
|
'x-systemId': systemId
|
|
})
|
|
);
|
|
}
|
|
};
|
|
|
|
exports.setDocumentMode = function(document, mode) {
|
|
document['x-mode'] = mode;
|
|
};
|
|
|
|
exports.getDocumentMode = function(document) {
|
|
return document['x-mode'];
|
|
};
|
|
|
|
exports.detachNode = function(node) {
|
|
if (node.parent) {
|
|
const idx = node.parent.children.indexOf(node);
|
|
const prev = node.prev;
|
|
const next = node.next;
|
|
|
|
node.prev = null;
|
|
node.next = null;
|
|
|
|
if (prev) {
|
|
prev.next = next;
|
|
}
|
|
|
|
if (next) {
|
|
next.prev = prev;
|
|
}
|
|
|
|
node.parent.children.splice(idx, 1);
|
|
node.parent = null;
|
|
}
|
|
};
|
|
|
|
exports.insertText = function(parentNode, text) {
|
|
const lastChild = parentNode.children[parentNode.children.length - 1];
|
|
|
|
if (lastChild && lastChild.type === 'text') {
|
|
lastChild.data += text;
|
|
} else {
|
|
appendChild(parentNode, createTextNode(text));
|
|
}
|
|
};
|
|
|
|
exports.insertTextBefore = function(parentNode, text, referenceNode) {
|
|
const prevNode = parentNode.children[parentNode.children.indexOf(referenceNode) - 1];
|
|
|
|
if (prevNode && prevNode.type === 'text') {
|
|
prevNode.data += text;
|
|
} else {
|
|
insertBefore(parentNode, createTextNode(text), referenceNode);
|
|
}
|
|
};
|
|
|
|
exports.adoptAttributes = function(recipient, attrs) {
|
|
for (let i = 0; i < attrs.length; i++) {
|
|
const attrName = attrs[i].name;
|
|
|
|
if (typeof recipient.attribs[attrName] === 'undefined') {
|
|
recipient.attribs[attrName] = attrs[i].value;
|
|
recipient['x-attribsNamespace'][attrName] = attrs[i].namespace;
|
|
recipient['x-attribsPrefix'][attrName] = attrs[i].prefix;
|
|
}
|
|
}
|
|
};
|
|
|
|
//Tree traversing
|
|
exports.getFirstChild = function(node) {
|
|
return node.children[0];
|
|
};
|
|
|
|
exports.getChildNodes = function(node) {
|
|
return node.children;
|
|
};
|
|
|
|
exports.getParentNode = function(node) {
|
|
return node.parent;
|
|
};
|
|
|
|
exports.getAttrList = function(element) {
|
|
const attrList = [];
|
|
|
|
for (const name in element.attribs) {
|
|
attrList.push({
|
|
name: name,
|
|
value: element.attribs[name],
|
|
namespace: element['x-attribsNamespace'][name],
|
|
prefix: element['x-attribsPrefix'][name]
|
|
});
|
|
}
|
|
|
|
return attrList;
|
|
};
|
|
|
|
//Node data
|
|
exports.getTagName = function(element) {
|
|
return element.name;
|
|
};
|
|
|
|
exports.getNamespaceURI = function(element) {
|
|
return element.namespace;
|
|
};
|
|
|
|
exports.getTextNodeContent = function(textNode) {
|
|
return textNode.data;
|
|
};
|
|
|
|
exports.getCommentNodeContent = function(commentNode) {
|
|
return commentNode.data;
|
|
};
|
|
|
|
exports.getDocumentTypeNodeName = function(doctypeNode) {
|
|
return doctypeNode['x-name'];
|
|
};
|
|
|
|
exports.getDocumentTypeNodePublicId = function(doctypeNode) {
|
|
return doctypeNode['x-publicId'];
|
|
};
|
|
|
|
exports.getDocumentTypeNodeSystemId = function(doctypeNode) {
|
|
return doctypeNode['x-systemId'];
|
|
};
|
|
|
|
//Node types
|
|
exports.isTextNode = function(node) {
|
|
return node.type === 'text';
|
|
};
|
|
|
|
exports.isCommentNode = function(node) {
|
|
return node.type === 'comment';
|
|
};
|
|
|
|
exports.isDocumentTypeNode = function(node) {
|
|
return node.type === 'directive' && node.name === '!doctype';
|
|
};
|
|
|
|
exports.isElementNode = function(node) {
|
|
return !!node.attribs;
|
|
};
|
|
|
|
// Source code location
|
|
exports.setNodeSourceCodeLocation = function(node, location) {
|
|
node.sourceCodeLocation = location;
|
|
};
|
|
|
|
exports.getNodeSourceCodeLocation = function(node) {
|
|
return node.sourceCodeLocation;
|
|
};
|
|
|
|
exports.updateNodeSourceCodeLocation = function(node, endLocation) {
|
|
node.sourceCodeLocation = Object.assign(node.sourceCodeLocation, endLocation);
|
|
};
|
|
|
|
},{"parse5/lib/common/doctype":64,"parse5/lib/common/html":67}],64:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const { DOCUMENT_MODE } = require('./html');
|
|
|
|
//Const
|
|
const VALID_DOCTYPE_NAME = 'html';
|
|
const VALID_SYSTEM_ID = 'about:legacy-compat';
|
|
const QUIRKS_MODE_SYSTEM_ID = 'http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd';
|
|
|
|
const QUIRKS_MODE_PUBLIC_ID_PREFIXES = [
|
|
'+//silmaril//dtd html pro v0r11 19970101//',
|
|
'-//as//dtd html 3.0 aswedit + extensions//',
|
|
'-//advasoft ltd//dtd html 3.0 aswedit + extensions//',
|
|
'-//ietf//dtd html 2.0 level 1//',
|
|
'-//ietf//dtd html 2.0 level 2//',
|
|
'-//ietf//dtd html 2.0 strict level 1//',
|
|
'-//ietf//dtd html 2.0 strict level 2//',
|
|
'-//ietf//dtd html 2.0 strict//',
|
|
'-//ietf//dtd html 2.0//',
|
|
'-//ietf//dtd html 2.1e//',
|
|
'-//ietf//dtd html 3.0//',
|
|
'-//ietf//dtd html 3.2 final//',
|
|
'-//ietf//dtd html 3.2//',
|
|
'-//ietf//dtd html 3//',
|
|
'-//ietf//dtd html level 0//',
|
|
'-//ietf//dtd html level 1//',
|
|
'-//ietf//dtd html level 2//',
|
|
'-//ietf//dtd html level 3//',
|
|
'-//ietf//dtd html strict level 0//',
|
|
'-//ietf//dtd html strict level 1//',
|
|
'-//ietf//dtd html strict level 2//',
|
|
'-//ietf//dtd html strict level 3//',
|
|
'-//ietf//dtd html strict//',
|
|
'-//ietf//dtd html//',
|
|
'-//metrius//dtd metrius presentational//',
|
|
'-//microsoft//dtd internet explorer 2.0 html strict//',
|
|
'-//microsoft//dtd internet explorer 2.0 html//',
|
|
'-//microsoft//dtd internet explorer 2.0 tables//',
|
|
'-//microsoft//dtd internet explorer 3.0 html strict//',
|
|
'-//microsoft//dtd internet explorer 3.0 html//',
|
|
'-//microsoft//dtd internet explorer 3.0 tables//',
|
|
'-//netscape comm. corp.//dtd html//',
|
|
'-//netscape comm. corp.//dtd strict html//',
|
|
"-//o'reilly and associates//dtd html 2.0//",
|
|
"-//o'reilly and associates//dtd html extended 1.0//",
|
|
"-//o'reilly and associates//dtd html extended relaxed 1.0//",
|
|
'-//sq//dtd html 2.0 hotmetal + extensions//',
|
|
'-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//',
|
|
'-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//',
|
|
'-//spyglass//dtd html 2.0 extended//',
|
|
'-//sun microsystems corp.//dtd hotjava html//',
|
|
'-//sun microsystems corp.//dtd hotjava strict html//',
|
|
'-//w3c//dtd html 3 1995-03-24//',
|
|
'-//w3c//dtd html 3.2 draft//',
|
|
'-//w3c//dtd html 3.2 final//',
|
|
'-//w3c//dtd html 3.2//',
|
|
'-//w3c//dtd html 3.2s draft//',
|
|
'-//w3c//dtd html 4.0 frameset//',
|
|
'-//w3c//dtd html 4.0 transitional//',
|
|
'-//w3c//dtd html experimental 19960712//',
|
|
'-//w3c//dtd html experimental 970421//',
|
|
'-//w3c//dtd w3 html//',
|
|
'-//w3o//dtd w3 html 3.0//',
|
|
'-//webtechs//dtd mozilla html 2.0//',
|
|
'-//webtechs//dtd mozilla html//'
|
|
];
|
|
|
|
const QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES = QUIRKS_MODE_PUBLIC_ID_PREFIXES.concat([
|
|
'-//w3c//dtd html 4.01 frameset//',
|
|
'-//w3c//dtd html 4.01 transitional//'
|
|
]);
|
|
|
|
const QUIRKS_MODE_PUBLIC_IDS = ['-//w3o//dtd w3 html strict 3.0//en//', '-/w3c/dtd html 4.0 transitional/en', 'html'];
|
|
const LIMITED_QUIRKS_PUBLIC_ID_PREFIXES = ['-//w3c//dtd xhtml 1.0 frameset//', '-//w3c//dtd xhtml 1.0 transitional//'];
|
|
|
|
const LIMITED_QUIRKS_WITH_SYSTEM_ID_PUBLIC_ID_PREFIXES = LIMITED_QUIRKS_PUBLIC_ID_PREFIXES.concat([
|
|
'-//w3c//dtd html 4.01 frameset//',
|
|
'-//w3c//dtd html 4.01 transitional//'
|
|
]);
|
|
|
|
//Utils
|
|
function enquoteDoctypeId(id) {
|
|
const quote = id.indexOf('"') !== -1 ? "'" : '"';
|
|
|
|
return quote + id + quote;
|
|
}
|
|
|
|
function hasPrefix(publicId, prefixes) {
|
|
for (let i = 0; i < prefixes.length; i++) {
|
|
if (publicId.indexOf(prefixes[i]) === 0) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//API
|
|
exports.isConforming = function(token) {
|
|
return (
|
|
token.name === VALID_DOCTYPE_NAME &&
|
|
token.publicId === null &&
|
|
(token.systemId === null || token.systemId === VALID_SYSTEM_ID)
|
|
);
|
|
};
|
|
|
|
exports.getDocumentMode = function(token) {
|
|
if (token.name !== VALID_DOCTYPE_NAME) {
|
|
return DOCUMENT_MODE.QUIRKS;
|
|
}
|
|
|
|
const systemId = token.systemId;
|
|
|
|
if (systemId && systemId.toLowerCase() === QUIRKS_MODE_SYSTEM_ID) {
|
|
return DOCUMENT_MODE.QUIRKS;
|
|
}
|
|
|
|
let publicId = token.publicId;
|
|
|
|
if (publicId !== null) {
|
|
publicId = publicId.toLowerCase();
|
|
|
|
if (QUIRKS_MODE_PUBLIC_IDS.indexOf(publicId) > -1) {
|
|
return DOCUMENT_MODE.QUIRKS;
|
|
}
|
|
|
|
let prefixes = systemId === null ? QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES : QUIRKS_MODE_PUBLIC_ID_PREFIXES;
|
|
|
|
if (hasPrefix(publicId, prefixes)) {
|
|
return DOCUMENT_MODE.QUIRKS;
|
|
}
|
|
|
|
prefixes =
|
|
systemId === null ? LIMITED_QUIRKS_PUBLIC_ID_PREFIXES : LIMITED_QUIRKS_WITH_SYSTEM_ID_PUBLIC_ID_PREFIXES;
|
|
|
|
if (hasPrefix(publicId, prefixes)) {
|
|
return DOCUMENT_MODE.LIMITED_QUIRKS;
|
|
}
|
|
}
|
|
|
|
return DOCUMENT_MODE.NO_QUIRKS;
|
|
};
|
|
|
|
exports.serializeContent = function(name, publicId, systemId) {
|
|
let str = '!DOCTYPE ';
|
|
|
|
if (name) {
|
|
str += name;
|
|
}
|
|
|
|
if (publicId) {
|
|
str += ' PUBLIC ' + enquoteDoctypeId(publicId);
|
|
} else if (systemId) {
|
|
str += ' SYSTEM';
|
|
}
|
|
|
|
if (systemId !== null) {
|
|
str += ' ' + enquoteDoctypeId(systemId);
|
|
}
|
|
|
|
return str;
|
|
};
|
|
|
|
},{"./html":67}],65:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
module.exports = {
|
|
controlCharacterInInputStream: 'control-character-in-input-stream',
|
|
noncharacterInInputStream: 'noncharacter-in-input-stream',
|
|
surrogateInInputStream: 'surrogate-in-input-stream',
|
|
nonVoidHtmlElementStartTagWithTrailingSolidus: 'non-void-html-element-start-tag-with-trailing-solidus',
|
|
endTagWithAttributes: 'end-tag-with-attributes',
|
|
endTagWithTrailingSolidus: 'end-tag-with-trailing-solidus',
|
|
unexpectedSolidusInTag: 'unexpected-solidus-in-tag',
|
|
unexpectedNullCharacter: 'unexpected-null-character',
|
|
unexpectedQuestionMarkInsteadOfTagName: 'unexpected-question-mark-instead-of-tag-name',
|
|
invalidFirstCharacterOfTagName: 'invalid-first-character-of-tag-name',
|
|
unexpectedEqualsSignBeforeAttributeName: 'unexpected-equals-sign-before-attribute-name',
|
|
missingEndTagName: 'missing-end-tag-name',
|
|
unexpectedCharacterInAttributeName: 'unexpected-character-in-attribute-name',
|
|
unknownNamedCharacterReference: 'unknown-named-character-reference',
|
|
missingSemicolonAfterCharacterReference: 'missing-semicolon-after-character-reference',
|
|
unexpectedCharacterAfterDoctypeSystemIdentifier: 'unexpected-character-after-doctype-system-identifier',
|
|
unexpectedCharacterInUnquotedAttributeValue: 'unexpected-character-in-unquoted-attribute-value',
|
|
eofBeforeTagName: 'eof-before-tag-name',
|
|
eofInTag: 'eof-in-tag',
|
|
missingAttributeValue: 'missing-attribute-value',
|
|
missingWhitespaceBetweenAttributes: 'missing-whitespace-between-attributes',
|
|
missingWhitespaceAfterDoctypePublicKeyword: 'missing-whitespace-after-doctype-public-keyword',
|
|
missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers:
|
|
'missing-whitespace-between-doctype-public-and-system-identifiers',
|
|
missingWhitespaceAfterDoctypeSystemKeyword: 'missing-whitespace-after-doctype-system-keyword',
|
|
missingQuoteBeforeDoctypePublicIdentifier: 'missing-quote-before-doctype-public-identifier',
|
|
missingQuoteBeforeDoctypeSystemIdentifier: 'missing-quote-before-doctype-system-identifier',
|
|
missingDoctypePublicIdentifier: 'missing-doctype-public-identifier',
|
|
missingDoctypeSystemIdentifier: 'missing-doctype-system-identifier',
|
|
abruptDoctypePublicIdentifier: 'abrupt-doctype-public-identifier',
|
|
abruptDoctypeSystemIdentifier: 'abrupt-doctype-system-identifier',
|
|
cdataInHtmlContent: 'cdata-in-html-content',
|
|
incorrectlyOpenedComment: 'incorrectly-opened-comment',
|
|
eofInScriptHtmlCommentLikeText: 'eof-in-script-html-comment-like-text',
|
|
eofInDoctype: 'eof-in-doctype',
|
|
nestedComment: 'nested-comment',
|
|
abruptClosingOfEmptyComment: 'abrupt-closing-of-empty-comment',
|
|
eofInComment: 'eof-in-comment',
|
|
incorrectlyClosedComment: 'incorrectly-closed-comment',
|
|
eofInCdata: 'eof-in-cdata',
|
|
absenceOfDigitsInNumericCharacterReference: 'absence-of-digits-in-numeric-character-reference',
|
|
nullCharacterReference: 'null-character-reference',
|
|
surrogateCharacterReference: 'surrogate-character-reference',
|
|
characterReferenceOutsideUnicodeRange: 'character-reference-outside-unicode-range',
|
|
controlCharacterReference: 'control-character-reference',
|
|
noncharacterCharacterReference: 'noncharacter-character-reference',
|
|
missingWhitespaceBeforeDoctypeName: 'missing-whitespace-before-doctype-name',
|
|
missingDoctypeName: 'missing-doctype-name',
|
|
invalidCharacterSequenceAfterDoctypeName: 'invalid-character-sequence-after-doctype-name',
|
|
duplicateAttribute: 'duplicate-attribute',
|
|
nonConformingDoctype: 'non-conforming-doctype',
|
|
missingDoctype: 'missing-doctype',
|
|
misplacedDoctype: 'misplaced-doctype',
|
|
endTagWithoutMatchingOpenElement: 'end-tag-without-matching-open-element',
|
|
closingOfElementWithOpenChildElements: 'closing-of-element-with-open-child-elements',
|
|
disallowedContentInNoscriptInHead: 'disallowed-content-in-noscript-in-head',
|
|
openElementsLeftAfterEof: 'open-elements-left-after-eof',
|
|
abandonedHeadElementChild: 'abandoned-head-element-child',
|
|
misplacedStartTagForHeadElement: 'misplaced-start-tag-for-head-element',
|
|
nestedNoscriptInHead: 'nested-noscript-in-head',
|
|
eofInElementThatCanContainOnlyText: 'eof-in-element-that-can-contain-only-text'
|
|
};
|
|
|
|
},{}],66:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const Tokenizer = require('../tokenizer');
|
|
const HTML = require('./html');
|
|
|
|
//Aliases
|
|
const $ = HTML.TAG_NAMES;
|
|
const NS = HTML.NAMESPACES;
|
|
const ATTRS = HTML.ATTRS;
|
|
|
|
//MIME types
|
|
const MIME_TYPES = {
|
|
TEXT_HTML: 'text/html',
|
|
APPLICATION_XML: 'application/xhtml+xml'
|
|
};
|
|
|
|
//Attributes
|
|
const DEFINITION_URL_ATTR = 'definitionurl';
|
|
const ADJUSTED_DEFINITION_URL_ATTR = 'definitionURL';
|
|
const SVG_ATTRS_ADJUSTMENT_MAP = {
|
|
attributename: 'attributeName',
|
|
attributetype: 'attributeType',
|
|
basefrequency: 'baseFrequency',
|
|
baseprofile: 'baseProfile',
|
|
calcmode: 'calcMode',
|
|
clippathunits: 'clipPathUnits',
|
|
diffuseconstant: 'diffuseConstant',
|
|
edgemode: 'edgeMode',
|
|
filterunits: 'filterUnits',
|
|
glyphref: 'glyphRef',
|
|
gradienttransform: 'gradientTransform',
|
|
gradientunits: 'gradientUnits',
|
|
kernelmatrix: 'kernelMatrix',
|
|
kernelunitlength: 'kernelUnitLength',
|
|
keypoints: 'keyPoints',
|
|
keysplines: 'keySplines',
|
|
keytimes: 'keyTimes',
|
|
lengthadjust: 'lengthAdjust',
|
|
limitingconeangle: 'limitingConeAngle',
|
|
markerheight: 'markerHeight',
|
|
markerunits: 'markerUnits',
|
|
markerwidth: 'markerWidth',
|
|
maskcontentunits: 'maskContentUnits',
|
|
maskunits: 'maskUnits',
|
|
numoctaves: 'numOctaves',
|
|
pathlength: 'pathLength',
|
|
patterncontentunits: 'patternContentUnits',
|
|
patterntransform: 'patternTransform',
|
|
patternunits: 'patternUnits',
|
|
pointsatx: 'pointsAtX',
|
|
pointsaty: 'pointsAtY',
|
|
pointsatz: 'pointsAtZ',
|
|
preservealpha: 'preserveAlpha',
|
|
preserveaspectratio: 'preserveAspectRatio',
|
|
primitiveunits: 'primitiveUnits',
|
|
refx: 'refX',
|
|
refy: 'refY',
|
|
repeatcount: 'repeatCount',
|
|
repeatdur: 'repeatDur',
|
|
requiredextensions: 'requiredExtensions',
|
|
requiredfeatures: 'requiredFeatures',
|
|
specularconstant: 'specularConstant',
|
|
specularexponent: 'specularExponent',
|
|
spreadmethod: 'spreadMethod',
|
|
startoffset: 'startOffset',
|
|
stddeviation: 'stdDeviation',
|
|
stitchtiles: 'stitchTiles',
|
|
surfacescale: 'surfaceScale',
|
|
systemlanguage: 'systemLanguage',
|
|
tablevalues: 'tableValues',
|
|
targetx: 'targetX',
|
|
targety: 'targetY',
|
|
textlength: 'textLength',
|
|
viewbox: 'viewBox',
|
|
viewtarget: 'viewTarget',
|
|
xchannelselector: 'xChannelSelector',
|
|
ychannelselector: 'yChannelSelector',
|
|
zoomandpan: 'zoomAndPan'
|
|
};
|
|
|
|
const XML_ATTRS_ADJUSTMENT_MAP = {
|
|
'xlink:actuate': { prefix: 'xlink', name: 'actuate', namespace: NS.XLINK },
|
|
'xlink:arcrole': { prefix: 'xlink', name: 'arcrole', namespace: NS.XLINK },
|
|
'xlink:href': { prefix: 'xlink', name: 'href', namespace: NS.XLINK },
|
|
'xlink:role': { prefix: 'xlink', name: 'role', namespace: NS.XLINK },
|
|
'xlink:show': { prefix: 'xlink', name: 'show', namespace: NS.XLINK },
|
|
'xlink:title': { prefix: 'xlink', name: 'title', namespace: NS.XLINK },
|
|
'xlink:type': { prefix: 'xlink', name: 'type', namespace: NS.XLINK },
|
|
'xml:base': { prefix: 'xml', name: 'base', namespace: NS.XML },
|
|
'xml:lang': { prefix: 'xml', name: 'lang', namespace: NS.XML },
|
|
'xml:space': { prefix: 'xml', name: 'space', namespace: NS.XML },
|
|
xmlns: { prefix: '', name: 'xmlns', namespace: NS.XMLNS },
|
|
'xmlns:xlink': { prefix: 'xmlns', name: 'xlink', namespace: NS.XMLNS }
|
|
};
|
|
|
|
//SVG tag names adjustment map
|
|
const SVG_TAG_NAMES_ADJUSTMENT_MAP = (exports.SVG_TAG_NAMES_ADJUSTMENT_MAP = {
|
|
altglyph: 'altGlyph',
|
|
altglyphdef: 'altGlyphDef',
|
|
altglyphitem: 'altGlyphItem',
|
|
animatecolor: 'animateColor',
|
|
animatemotion: 'animateMotion',
|
|
animatetransform: 'animateTransform',
|
|
clippath: 'clipPath',
|
|
feblend: 'feBlend',
|
|
fecolormatrix: 'feColorMatrix',
|
|
fecomponenttransfer: 'feComponentTransfer',
|
|
fecomposite: 'feComposite',
|
|
feconvolvematrix: 'feConvolveMatrix',
|
|
fediffuselighting: 'feDiffuseLighting',
|
|
fedisplacementmap: 'feDisplacementMap',
|
|
fedistantlight: 'feDistantLight',
|
|
feflood: 'feFlood',
|
|
fefunca: 'feFuncA',
|
|
fefuncb: 'feFuncB',
|
|
fefuncg: 'feFuncG',
|
|
fefuncr: 'feFuncR',
|
|
fegaussianblur: 'feGaussianBlur',
|
|
feimage: 'feImage',
|
|
femerge: 'feMerge',
|
|
femergenode: 'feMergeNode',
|
|
femorphology: 'feMorphology',
|
|
feoffset: 'feOffset',
|
|
fepointlight: 'fePointLight',
|
|
fespecularlighting: 'feSpecularLighting',
|
|
fespotlight: 'feSpotLight',
|
|
fetile: 'feTile',
|
|
feturbulence: 'feTurbulence',
|
|
foreignobject: 'foreignObject',
|
|
glyphref: 'glyphRef',
|
|
lineargradient: 'linearGradient',
|
|
radialgradient: 'radialGradient',
|
|
textpath: 'textPath'
|
|
});
|
|
|
|
//Tags that causes exit from foreign content
|
|
const EXITS_FOREIGN_CONTENT = {
|
|
[$.B]: true,
|
|
[$.BIG]: true,
|
|
[$.BLOCKQUOTE]: true,
|
|
[$.BODY]: true,
|
|
[$.BR]: true,
|
|
[$.CENTER]: true,
|
|
[$.CODE]: true,
|
|
[$.DD]: true,
|
|
[$.DIV]: true,
|
|
[$.DL]: true,
|
|
[$.DT]: true,
|
|
[$.EM]: true,
|
|
[$.EMBED]: true,
|
|
[$.H1]: true,
|
|
[$.H2]: true,
|
|
[$.H3]: true,
|
|
[$.H4]: true,
|
|
[$.H5]: true,
|
|
[$.H6]: true,
|
|
[$.HEAD]: true,
|
|
[$.HR]: true,
|
|
[$.I]: true,
|
|
[$.IMG]: true,
|
|
[$.LI]: true,
|
|
[$.LISTING]: true,
|
|
[$.MENU]: true,
|
|
[$.META]: true,
|
|
[$.NOBR]: true,
|
|
[$.OL]: true,
|
|
[$.P]: true,
|
|
[$.PRE]: true,
|
|
[$.RUBY]: true,
|
|
[$.S]: true,
|
|
[$.SMALL]: true,
|
|
[$.SPAN]: true,
|
|
[$.STRONG]: true,
|
|
[$.STRIKE]: true,
|
|
[$.SUB]: true,
|
|
[$.SUP]: true,
|
|
[$.TABLE]: true,
|
|
[$.TT]: true,
|
|
[$.U]: true,
|
|
[$.UL]: true,
|
|
[$.VAR]: true
|
|
};
|
|
|
|
//Check exit from foreign content
|
|
exports.causesExit = function(startTagToken) {
|
|
const tn = startTagToken.tagName;
|
|
const isFontWithAttrs =
|
|
tn === $.FONT &&
|
|
(Tokenizer.getTokenAttr(startTagToken, ATTRS.COLOR) !== null ||
|
|
Tokenizer.getTokenAttr(startTagToken, ATTRS.SIZE) !== null ||
|
|
Tokenizer.getTokenAttr(startTagToken, ATTRS.FACE) !== null);
|
|
|
|
return isFontWithAttrs ? true : EXITS_FOREIGN_CONTENT[tn];
|
|
};
|
|
|
|
//Token adjustments
|
|
exports.adjustTokenMathMLAttrs = function(token) {
|
|
for (let i = 0; i < token.attrs.length; i++) {
|
|
if (token.attrs[i].name === DEFINITION_URL_ATTR) {
|
|
token.attrs[i].name = ADJUSTED_DEFINITION_URL_ATTR;
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
exports.adjustTokenSVGAttrs = function(token) {
|
|
for (let i = 0; i < token.attrs.length; i++) {
|
|
const adjustedAttrName = SVG_ATTRS_ADJUSTMENT_MAP[token.attrs[i].name];
|
|
|
|
if (adjustedAttrName) {
|
|
token.attrs[i].name = adjustedAttrName;
|
|
}
|
|
}
|
|
};
|
|
|
|
exports.adjustTokenXMLAttrs = function(token) {
|
|
for (let i = 0; i < token.attrs.length; i++) {
|
|
const adjustedAttrEntry = XML_ATTRS_ADJUSTMENT_MAP[token.attrs[i].name];
|
|
|
|
if (adjustedAttrEntry) {
|
|
token.attrs[i].prefix = adjustedAttrEntry.prefix;
|
|
token.attrs[i].name = adjustedAttrEntry.name;
|
|
token.attrs[i].namespace = adjustedAttrEntry.namespace;
|
|
}
|
|
}
|
|
};
|
|
|
|
exports.adjustTokenSVGTagName = function(token) {
|
|
const adjustedTagName = SVG_TAG_NAMES_ADJUSTMENT_MAP[token.tagName];
|
|
|
|
if (adjustedTagName) {
|
|
token.tagName = adjustedTagName;
|
|
}
|
|
};
|
|
|
|
//Integration points
|
|
function isMathMLTextIntegrationPoint(tn, ns) {
|
|
return ns === NS.MATHML && (tn === $.MI || tn === $.MO || tn === $.MN || tn === $.MS || tn === $.MTEXT);
|
|
}
|
|
|
|
function isHtmlIntegrationPoint(tn, ns, attrs) {
|
|
if (ns === NS.MATHML && tn === $.ANNOTATION_XML) {
|
|
for (let i = 0; i < attrs.length; i++) {
|
|
if (attrs[i].name === ATTRS.ENCODING) {
|
|
const value = attrs[i].value.toLowerCase();
|
|
|
|
return value === MIME_TYPES.TEXT_HTML || value === MIME_TYPES.APPLICATION_XML;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ns === NS.SVG && (tn === $.FOREIGN_OBJECT || tn === $.DESC || tn === $.TITLE);
|
|
}
|
|
|
|
exports.isIntegrationPoint = function(tn, ns, attrs, foreignNS) {
|
|
if ((!foreignNS || foreignNS === NS.HTML) && isHtmlIntegrationPoint(tn, ns, attrs)) {
|
|
return true;
|
|
}
|
|
|
|
if ((!foreignNS || foreignNS === NS.MATHML) && isMathMLTextIntegrationPoint(tn, ns)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
},{"../tokenizer":82,"./html":67}],67:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const NS = (exports.NAMESPACES = {
|
|
HTML: 'http://www.w3.org/1999/xhtml',
|
|
MATHML: 'http://www.w3.org/1998/Math/MathML',
|
|
SVG: 'http://www.w3.org/2000/svg',
|
|
XLINK: 'http://www.w3.org/1999/xlink',
|
|
XML: 'http://www.w3.org/XML/1998/namespace',
|
|
XMLNS: 'http://www.w3.org/2000/xmlns/'
|
|
});
|
|
|
|
exports.ATTRS = {
|
|
TYPE: 'type',
|
|
ACTION: 'action',
|
|
ENCODING: 'encoding',
|
|
PROMPT: 'prompt',
|
|
NAME: 'name',
|
|
COLOR: 'color',
|
|
FACE: 'face',
|
|
SIZE: 'size'
|
|
};
|
|
|
|
exports.DOCUMENT_MODE = {
|
|
NO_QUIRKS: 'no-quirks',
|
|
QUIRKS: 'quirks',
|
|
LIMITED_QUIRKS: 'limited-quirks'
|
|
};
|
|
|
|
const $ = (exports.TAG_NAMES = {
|
|
A: 'a',
|
|
ADDRESS: 'address',
|
|
ANNOTATION_XML: 'annotation-xml',
|
|
APPLET: 'applet',
|
|
AREA: 'area',
|
|
ARTICLE: 'article',
|
|
ASIDE: 'aside',
|
|
|
|
B: 'b',
|
|
BASE: 'base',
|
|
BASEFONT: 'basefont',
|
|
BGSOUND: 'bgsound',
|
|
BIG: 'big',
|
|
BLOCKQUOTE: 'blockquote',
|
|
BODY: 'body',
|
|
BR: 'br',
|
|
BUTTON: 'button',
|
|
|
|
CAPTION: 'caption',
|
|
CENTER: 'center',
|
|
CODE: 'code',
|
|
COL: 'col',
|
|
COLGROUP: 'colgroup',
|
|
|
|
DD: 'dd',
|
|
DESC: 'desc',
|
|
DETAILS: 'details',
|
|
DIALOG: 'dialog',
|
|
DIR: 'dir',
|
|
DIV: 'div',
|
|
DL: 'dl',
|
|
DT: 'dt',
|
|
|
|
EM: 'em',
|
|
EMBED: 'embed',
|
|
|
|
FIELDSET: 'fieldset',
|
|
FIGCAPTION: 'figcaption',
|
|
FIGURE: 'figure',
|
|
FONT: 'font',
|
|
FOOTER: 'footer',
|
|
FOREIGN_OBJECT: 'foreignObject',
|
|
FORM: 'form',
|
|
FRAME: 'frame',
|
|
FRAMESET: 'frameset',
|
|
|
|
H1: 'h1',
|
|
H2: 'h2',
|
|
H3: 'h3',
|
|
H4: 'h4',
|
|
H5: 'h5',
|
|
H6: 'h6',
|
|
HEAD: 'head',
|
|
HEADER: 'header',
|
|
HGROUP: 'hgroup',
|
|
HR: 'hr',
|
|
HTML: 'html',
|
|
|
|
I: 'i',
|
|
IMG: 'img',
|
|
IMAGE: 'image',
|
|
INPUT: 'input',
|
|
IFRAME: 'iframe',
|
|
|
|
KEYGEN: 'keygen',
|
|
|
|
LABEL: 'label',
|
|
LI: 'li',
|
|
LINK: 'link',
|
|
LISTING: 'listing',
|
|
|
|
MAIN: 'main',
|
|
MALIGNMARK: 'malignmark',
|
|
MARQUEE: 'marquee',
|
|
MATH: 'math',
|
|
MENU: 'menu',
|
|
META: 'meta',
|
|
MGLYPH: 'mglyph',
|
|
MI: 'mi',
|
|
MO: 'mo',
|
|
MN: 'mn',
|
|
MS: 'ms',
|
|
MTEXT: 'mtext',
|
|
|
|
NAV: 'nav',
|
|
NOBR: 'nobr',
|
|
NOFRAMES: 'noframes',
|
|
NOEMBED: 'noembed',
|
|
NOSCRIPT: 'noscript',
|
|
|
|
OBJECT: 'object',
|
|
OL: 'ol',
|
|
OPTGROUP: 'optgroup',
|
|
OPTION: 'option',
|
|
|
|
P: 'p',
|
|
PARAM: 'param',
|
|
PLAINTEXT: 'plaintext',
|
|
PRE: 'pre',
|
|
|
|
RB: 'rb',
|
|
RP: 'rp',
|
|
RT: 'rt',
|
|
RTC: 'rtc',
|
|
RUBY: 'ruby',
|
|
|
|
S: 's',
|
|
SCRIPT: 'script',
|
|
SECTION: 'section',
|
|
SELECT: 'select',
|
|
SOURCE: 'source',
|
|
SMALL: 'small',
|
|
SPAN: 'span',
|
|
STRIKE: 'strike',
|
|
STRONG: 'strong',
|
|
STYLE: 'style',
|
|
SUB: 'sub',
|
|
SUMMARY: 'summary',
|
|
SUP: 'sup',
|
|
|
|
TABLE: 'table',
|
|
TBODY: 'tbody',
|
|
TEMPLATE: 'template',
|
|
TEXTAREA: 'textarea',
|
|
TFOOT: 'tfoot',
|
|
TD: 'td',
|
|
TH: 'th',
|
|
THEAD: 'thead',
|
|
TITLE: 'title',
|
|
TR: 'tr',
|
|
TRACK: 'track',
|
|
TT: 'tt',
|
|
|
|
U: 'u',
|
|
UL: 'ul',
|
|
|
|
SVG: 'svg',
|
|
|
|
VAR: 'var',
|
|
|
|
WBR: 'wbr',
|
|
|
|
XMP: 'xmp'
|
|
});
|
|
|
|
exports.SPECIAL_ELEMENTS = {
|
|
[NS.HTML]: {
|
|
[$.ADDRESS]: true,
|
|
[$.APPLET]: true,
|
|
[$.AREA]: true,
|
|
[$.ARTICLE]: true,
|
|
[$.ASIDE]: true,
|
|
[$.BASE]: true,
|
|
[$.BASEFONT]: true,
|
|
[$.BGSOUND]: true,
|
|
[$.BLOCKQUOTE]: true,
|
|
[$.BODY]: true,
|
|
[$.BR]: true,
|
|
[$.BUTTON]: true,
|
|
[$.CAPTION]: true,
|
|
[$.CENTER]: true,
|
|
[$.COL]: true,
|
|
[$.COLGROUP]: true,
|
|
[$.DD]: true,
|
|
[$.DETAILS]: true,
|
|
[$.DIR]: true,
|
|
[$.DIV]: true,
|
|
[$.DL]: true,
|
|
[$.DT]: true,
|
|
[$.EMBED]: true,
|
|
[$.FIELDSET]: true,
|
|
[$.FIGCAPTION]: true,
|
|
[$.FIGURE]: true,
|
|
[$.FOOTER]: true,
|
|
[$.FORM]: true,
|
|
[$.FRAME]: true,
|
|
[$.FRAMESET]: true,
|
|
[$.H1]: true,
|
|
[$.H2]: true,
|
|
[$.H3]: true,
|
|
[$.H4]: true,
|
|
[$.H5]: true,
|
|
[$.H6]: true,
|
|
[$.HEAD]: true,
|
|
[$.HEADER]: true,
|
|
[$.HGROUP]: true,
|
|
[$.HR]: true,
|
|
[$.HTML]: true,
|
|
[$.IFRAME]: true,
|
|
[$.IMG]: true,
|
|
[$.INPUT]: true,
|
|
[$.LI]: true,
|
|
[$.LINK]: true,
|
|
[$.LISTING]: true,
|
|
[$.MAIN]: true,
|
|
[$.MARQUEE]: true,
|
|
[$.MENU]: true,
|
|
[$.META]: true,
|
|
[$.NAV]: true,
|
|
[$.NOEMBED]: true,
|
|
[$.NOFRAMES]: true,
|
|
[$.NOSCRIPT]: true,
|
|
[$.OBJECT]: true,
|
|
[$.OL]: true,
|
|
[$.P]: true,
|
|
[$.PARAM]: true,
|
|
[$.PLAINTEXT]: true,
|
|
[$.PRE]: true,
|
|
[$.SCRIPT]: true,
|
|
[$.SECTION]: true,
|
|
[$.SELECT]: true,
|
|
[$.SOURCE]: true,
|
|
[$.STYLE]: true,
|
|
[$.SUMMARY]: true,
|
|
[$.TABLE]: true,
|
|
[$.TBODY]: true,
|
|
[$.TD]: true,
|
|
[$.TEMPLATE]: true,
|
|
[$.TEXTAREA]: true,
|
|
[$.TFOOT]: true,
|
|
[$.TH]: true,
|
|
[$.THEAD]: true,
|
|
[$.TITLE]: true,
|
|
[$.TR]: true,
|
|
[$.TRACK]: true,
|
|
[$.UL]: true,
|
|
[$.WBR]: true,
|
|
[$.XMP]: true
|
|
},
|
|
[NS.MATHML]: {
|
|
[$.MI]: true,
|
|
[$.MO]: true,
|
|
[$.MN]: true,
|
|
[$.MS]: true,
|
|
[$.MTEXT]: true,
|
|
[$.ANNOTATION_XML]: true
|
|
},
|
|
[NS.SVG]: {
|
|
[$.TITLE]: true,
|
|
[$.FOREIGN_OBJECT]: true,
|
|
[$.DESC]: true
|
|
}
|
|
};
|
|
|
|
},{}],68:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const UNDEFINED_CODE_POINTS = [
|
|
0xfffe,
|
|
0xffff,
|
|
0x1fffe,
|
|
0x1ffff,
|
|
0x2fffe,
|
|
0x2ffff,
|
|
0x3fffe,
|
|
0x3ffff,
|
|
0x4fffe,
|
|
0x4ffff,
|
|
0x5fffe,
|
|
0x5ffff,
|
|
0x6fffe,
|
|
0x6ffff,
|
|
0x7fffe,
|
|
0x7ffff,
|
|
0x8fffe,
|
|
0x8ffff,
|
|
0x9fffe,
|
|
0x9ffff,
|
|
0xafffe,
|
|
0xaffff,
|
|
0xbfffe,
|
|
0xbffff,
|
|
0xcfffe,
|
|
0xcffff,
|
|
0xdfffe,
|
|
0xdffff,
|
|
0xefffe,
|
|
0xeffff,
|
|
0xffffe,
|
|
0xfffff,
|
|
0x10fffe,
|
|
0x10ffff
|
|
];
|
|
|
|
exports.REPLACEMENT_CHARACTER = '\uFFFD';
|
|
|
|
exports.CODE_POINTS = {
|
|
EOF: -1,
|
|
NULL: 0x00,
|
|
TABULATION: 0x09,
|
|
CARRIAGE_RETURN: 0x0d,
|
|
LINE_FEED: 0x0a,
|
|
FORM_FEED: 0x0c,
|
|
SPACE: 0x20,
|
|
EXCLAMATION_MARK: 0x21,
|
|
QUOTATION_MARK: 0x22,
|
|
NUMBER_SIGN: 0x23,
|
|
AMPERSAND: 0x26,
|
|
APOSTROPHE: 0x27,
|
|
HYPHEN_MINUS: 0x2d,
|
|
SOLIDUS: 0x2f,
|
|
DIGIT_0: 0x30,
|
|
DIGIT_9: 0x39,
|
|
SEMICOLON: 0x3b,
|
|
LESS_THAN_SIGN: 0x3c,
|
|
EQUALS_SIGN: 0x3d,
|
|
GREATER_THAN_SIGN: 0x3e,
|
|
QUESTION_MARK: 0x3f,
|
|
LATIN_CAPITAL_A: 0x41,
|
|
LATIN_CAPITAL_F: 0x46,
|
|
LATIN_CAPITAL_X: 0x58,
|
|
LATIN_CAPITAL_Z: 0x5a,
|
|
RIGHT_SQUARE_BRACKET: 0x5d,
|
|
GRAVE_ACCENT: 0x60,
|
|
LATIN_SMALL_A: 0x61,
|
|
LATIN_SMALL_F: 0x66,
|
|
LATIN_SMALL_X: 0x78,
|
|
LATIN_SMALL_Z: 0x7a,
|
|
REPLACEMENT_CHARACTER: 0xfffd
|
|
};
|
|
|
|
exports.CODE_POINT_SEQUENCES = {
|
|
DASH_DASH_STRING: [0x2d, 0x2d], //--
|
|
DOCTYPE_STRING: [0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45], //DOCTYPE
|
|
CDATA_START_STRING: [0x5b, 0x43, 0x44, 0x41, 0x54, 0x41, 0x5b], //[CDATA[
|
|
SCRIPT_STRING: [0x73, 0x63, 0x72, 0x69, 0x70, 0x74], //script
|
|
PUBLIC_STRING: [0x50, 0x55, 0x42, 0x4c, 0x49, 0x43], //PUBLIC
|
|
SYSTEM_STRING: [0x53, 0x59, 0x53, 0x54, 0x45, 0x4d] //SYSTEM
|
|
};
|
|
|
|
//Surrogates
|
|
exports.isSurrogate = function(cp) {
|
|
return cp >= 0xd800 && cp <= 0xdfff;
|
|
};
|
|
|
|
exports.isSurrogatePair = function(cp) {
|
|
return cp >= 0xdc00 && cp <= 0xdfff;
|
|
};
|
|
|
|
exports.getSurrogatePairCodePoint = function(cp1, cp2) {
|
|
return (cp1 - 0xd800) * 0x400 + 0x2400 + cp2;
|
|
};
|
|
|
|
//NOTE: excluding NULL and ASCII whitespace
|
|
exports.isControlCodePoint = function(cp) {
|
|
return (
|
|
(cp !== 0x20 && cp !== 0x0a && cp !== 0x0d && cp !== 0x09 && cp !== 0x0c && cp >= 0x01 && cp <= 0x1f) ||
|
|
(cp >= 0x7f && cp <= 0x9f)
|
|
);
|
|
};
|
|
|
|
exports.isUndefinedCodePoint = function(cp) {
|
|
return (cp >= 0xfdd0 && cp <= 0xfdef) || UNDEFINED_CODE_POINTS.indexOf(cp) > -1;
|
|
};
|
|
|
|
},{}],69:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const Mixin = require('../../utils/mixin');
|
|
|
|
class ErrorReportingMixinBase extends Mixin {
|
|
constructor(host, opts) {
|
|
super(host);
|
|
|
|
this.posTracker = null;
|
|
this.onParseError = opts.onParseError;
|
|
}
|
|
|
|
_setErrorLocation(err) {
|
|
err.startLine = err.endLine = this.posTracker.line;
|
|
err.startCol = err.endCol = this.posTracker.col;
|
|
err.startOffset = err.endOffset = this.posTracker.offset;
|
|
}
|
|
|
|
_reportError(code) {
|
|
const err = {
|
|
code: code,
|
|
startLine: -1,
|
|
startCol: -1,
|
|
startOffset: -1,
|
|
endLine: -1,
|
|
endCol: -1,
|
|
endOffset: -1
|
|
};
|
|
|
|
this._setErrorLocation(err);
|
|
this.onParseError(err);
|
|
}
|
|
|
|
_getOverriddenMethods(mxn) {
|
|
return {
|
|
_err(code) {
|
|
mxn._reportError(code);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = ErrorReportingMixinBase;
|
|
|
|
},{"../../utils/mixin":87}],70:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const ErrorReportingMixinBase = require('./mixin-base');
|
|
const ErrorReportingTokenizerMixin = require('./tokenizer-mixin');
|
|
const LocationInfoTokenizerMixin = require('../location-info/tokenizer-mixin');
|
|
const Mixin = require('../../utils/mixin');
|
|
|
|
class ErrorReportingParserMixin extends ErrorReportingMixinBase {
|
|
constructor(parser, opts) {
|
|
super(parser, opts);
|
|
|
|
this.opts = opts;
|
|
this.ctLoc = null;
|
|
this.locBeforeToken = false;
|
|
}
|
|
|
|
_setErrorLocation(err) {
|
|
if (this.ctLoc) {
|
|
err.startLine = this.ctLoc.startLine;
|
|
err.startCol = this.ctLoc.startCol;
|
|
err.startOffset = this.ctLoc.startOffset;
|
|
|
|
err.endLine = this.locBeforeToken ? this.ctLoc.startLine : this.ctLoc.endLine;
|
|
err.endCol = this.locBeforeToken ? this.ctLoc.startCol : this.ctLoc.endCol;
|
|
err.endOffset = this.locBeforeToken ? this.ctLoc.startOffset : this.ctLoc.endOffset;
|
|
}
|
|
}
|
|
|
|
_getOverriddenMethods(mxn, orig) {
|
|
return {
|
|
_bootstrap(document, fragmentContext) {
|
|
orig._bootstrap.call(this, document, fragmentContext);
|
|
|
|
Mixin.install(this.tokenizer, ErrorReportingTokenizerMixin, mxn.opts);
|
|
Mixin.install(this.tokenizer, LocationInfoTokenizerMixin);
|
|
},
|
|
|
|
_processInputToken(token) {
|
|
mxn.ctLoc = token.location;
|
|
|
|
orig._processInputToken.call(this, token);
|
|
},
|
|
|
|
_err(code, options) {
|
|
mxn.locBeforeToken = options && options.beforeToken;
|
|
mxn._reportError(code);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = ErrorReportingParserMixin;
|
|
|
|
},{"../../utils/mixin":87,"../location-info/tokenizer-mixin":75,"./mixin-base":69,"./tokenizer-mixin":72}],71:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const ErrorReportingMixinBase = require('./mixin-base');
|
|
const PositionTrackingPreprocessorMixin = require('../position-tracking/preprocessor-mixin');
|
|
const Mixin = require('../../utils/mixin');
|
|
|
|
class ErrorReportingPreprocessorMixin extends ErrorReportingMixinBase {
|
|
constructor(preprocessor, opts) {
|
|
super(preprocessor, opts);
|
|
|
|
this.posTracker = Mixin.install(preprocessor, PositionTrackingPreprocessorMixin);
|
|
this.lastErrOffset = -1;
|
|
}
|
|
|
|
_reportError(code) {
|
|
//NOTE: avoid reporting error twice on advance/retreat
|
|
if (this.lastErrOffset !== this.posTracker.offset) {
|
|
this.lastErrOffset = this.posTracker.offset;
|
|
super._reportError(code);
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = ErrorReportingPreprocessorMixin;
|
|
|
|
},{"../../utils/mixin":87,"../position-tracking/preprocessor-mixin":76,"./mixin-base":69}],72:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const ErrorReportingMixinBase = require('./mixin-base');
|
|
const ErrorReportingPreprocessorMixin = require('./preprocessor-mixin');
|
|
const Mixin = require('../../utils/mixin');
|
|
|
|
class ErrorReportingTokenizerMixin extends ErrorReportingMixinBase {
|
|
constructor(tokenizer, opts) {
|
|
super(tokenizer, opts);
|
|
|
|
const preprocessorMixin = Mixin.install(tokenizer.preprocessor, ErrorReportingPreprocessorMixin, opts);
|
|
|
|
this.posTracker = preprocessorMixin.posTracker;
|
|
}
|
|
}
|
|
|
|
module.exports = ErrorReportingTokenizerMixin;
|
|
|
|
},{"../../utils/mixin":87,"./mixin-base":69,"./preprocessor-mixin":71}],73:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const Mixin = require('../../utils/mixin');
|
|
|
|
class LocationInfoOpenElementStackMixin extends Mixin {
|
|
constructor(stack, opts) {
|
|
super(stack);
|
|
|
|
this.onItemPop = opts.onItemPop;
|
|
}
|
|
|
|
_getOverriddenMethods(mxn, orig) {
|
|
return {
|
|
pop() {
|
|
mxn.onItemPop(this.current);
|
|
orig.pop.call(this);
|
|
},
|
|
|
|
popAllUpToHtmlElement() {
|
|
for (let i = this.stackTop; i > 0; i--) {
|
|
mxn.onItemPop(this.items[i]);
|
|
}
|
|
|
|
orig.popAllUpToHtmlElement.call(this);
|
|
},
|
|
|
|
remove(element) {
|
|
mxn.onItemPop(this.current);
|
|
orig.remove.call(this, element);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = LocationInfoOpenElementStackMixin;
|
|
|
|
},{"../../utils/mixin":87}],74:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const Mixin = require('../../utils/mixin');
|
|
const Tokenizer = require('../../tokenizer');
|
|
const LocationInfoTokenizerMixin = require('./tokenizer-mixin');
|
|
const LocationInfoOpenElementStackMixin = require('./open-element-stack-mixin');
|
|
const HTML = require('../../common/html');
|
|
|
|
//Aliases
|
|
const $ = HTML.TAG_NAMES;
|
|
|
|
class LocationInfoParserMixin extends Mixin {
|
|
constructor(parser) {
|
|
super(parser);
|
|
|
|
this.parser = parser;
|
|
this.treeAdapter = this.parser.treeAdapter;
|
|
this.posTracker = null;
|
|
this.lastStartTagToken = null;
|
|
this.lastFosterParentingLocation = null;
|
|
this.currentToken = null;
|
|
}
|
|
|
|
_setStartLocation(element) {
|
|
let loc = null;
|
|
|
|
if (this.lastStartTagToken) {
|
|
loc = Object.assign({}, this.lastStartTagToken.location);
|
|
loc.startTag = this.lastStartTagToken.location;
|
|
}
|
|
|
|
this.treeAdapter.setNodeSourceCodeLocation(element, loc);
|
|
}
|
|
|
|
_setEndLocation(element, closingToken) {
|
|
const loc = this.treeAdapter.getNodeSourceCodeLocation(element);
|
|
|
|
if (loc) {
|
|
if (closingToken.location) {
|
|
const ctLoc = closingToken.location;
|
|
const tn = this.treeAdapter.getTagName(element);
|
|
|
|
// NOTE: For cases like <p> <p> </p> - First 'p' closes without a closing
|
|
// tag and for cases like <td> <p> </td> - 'p' closes without a closing tag.
|
|
const isClosingEndTag = closingToken.type === Tokenizer.END_TAG_TOKEN && tn === closingToken.tagName;
|
|
const endLoc = {};
|
|
if (isClosingEndTag) {
|
|
endLoc.endTag = Object.assign({}, ctLoc);
|
|
endLoc.endLine = ctLoc.endLine;
|
|
endLoc.endCol = ctLoc.endCol;
|
|
endLoc.endOffset = ctLoc.endOffset;
|
|
} else {
|
|
endLoc.endLine = ctLoc.startLine;
|
|
endLoc.endCol = ctLoc.startCol;
|
|
endLoc.endOffset = ctLoc.startOffset;
|
|
}
|
|
|
|
this.treeAdapter.updateNodeSourceCodeLocation(element, endLoc);
|
|
}
|
|
}
|
|
}
|
|
|
|
_getOverriddenMethods(mxn, orig) {
|
|
return {
|
|
_bootstrap(document, fragmentContext) {
|
|
orig._bootstrap.call(this, document, fragmentContext);
|
|
|
|
mxn.lastStartTagToken = null;
|
|
mxn.lastFosterParentingLocation = null;
|
|
mxn.currentToken = null;
|
|
|
|
const tokenizerMixin = Mixin.install(this.tokenizer, LocationInfoTokenizerMixin);
|
|
|
|
mxn.posTracker = tokenizerMixin.posTracker;
|
|
|
|
Mixin.install(this.openElements, LocationInfoOpenElementStackMixin, {
|
|
onItemPop: function(element) {
|
|
mxn._setEndLocation(element, mxn.currentToken);
|
|
}
|
|
});
|
|
},
|
|
|
|
_runParsingLoop(scriptHandler) {
|
|
orig._runParsingLoop.call(this, scriptHandler);
|
|
|
|
// NOTE: generate location info for elements
|
|
// that remains on open element stack
|
|
for (let i = this.openElements.stackTop; i >= 0; i--) {
|
|
mxn._setEndLocation(this.openElements.items[i], mxn.currentToken);
|
|
}
|
|
},
|
|
|
|
//Token processing
|
|
_processTokenInForeignContent(token) {
|
|
mxn.currentToken = token;
|
|
orig._processTokenInForeignContent.call(this, token);
|
|
},
|
|
|
|
_processToken(token) {
|
|
mxn.currentToken = token;
|
|
orig._processToken.call(this, token);
|
|
|
|
//NOTE: <body> and <html> are never popped from the stack, so we need to updated
|
|
//their end location explicitly.
|
|
const requireExplicitUpdate =
|
|
token.type === Tokenizer.END_TAG_TOKEN &&
|
|
(token.tagName === $.HTML || (token.tagName === $.BODY && this.openElements.hasInScope($.BODY)));
|
|
|
|
if (requireExplicitUpdate) {
|
|
for (let i = this.openElements.stackTop; i >= 0; i--) {
|
|
const element = this.openElements.items[i];
|
|
|
|
if (this.treeAdapter.getTagName(element) === token.tagName) {
|
|
mxn._setEndLocation(element, token);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
//Doctype
|
|
_setDocumentType(token) {
|
|
orig._setDocumentType.call(this, token);
|
|
|
|
const documentChildren = this.treeAdapter.getChildNodes(this.document);
|
|
const cnLength = documentChildren.length;
|
|
|
|
for (let i = 0; i < cnLength; i++) {
|
|
const node = documentChildren[i];
|
|
|
|
if (this.treeAdapter.isDocumentTypeNode(node)) {
|
|
this.treeAdapter.setNodeSourceCodeLocation(node, token.location);
|
|
break;
|
|
}
|
|
}
|
|
},
|
|
|
|
//Elements
|
|
_attachElementToTree(element) {
|
|
//NOTE: _attachElementToTree is called from _appendElement, _insertElement and _insertTemplate methods.
|
|
//So we will use token location stored in this methods for the element.
|
|
mxn._setStartLocation(element);
|
|
mxn.lastStartTagToken = null;
|
|
orig._attachElementToTree.call(this, element);
|
|
},
|
|
|
|
_appendElement(token, namespaceURI) {
|
|
mxn.lastStartTagToken = token;
|
|
orig._appendElement.call(this, token, namespaceURI);
|
|
},
|
|
|
|
_insertElement(token, namespaceURI) {
|
|
mxn.lastStartTagToken = token;
|
|
orig._insertElement.call(this, token, namespaceURI);
|
|
},
|
|
|
|
_insertTemplate(token) {
|
|
mxn.lastStartTagToken = token;
|
|
orig._insertTemplate.call(this, token);
|
|
|
|
const tmplContent = this.treeAdapter.getTemplateContent(this.openElements.current);
|
|
|
|
this.treeAdapter.setNodeSourceCodeLocation(tmplContent, null);
|
|
},
|
|
|
|
_insertFakeRootElement() {
|
|
orig._insertFakeRootElement.call(this);
|
|
this.treeAdapter.setNodeSourceCodeLocation(this.openElements.current, null);
|
|
},
|
|
|
|
//Comments
|
|
_appendCommentNode(token, parent) {
|
|
orig._appendCommentNode.call(this, token, parent);
|
|
|
|
const children = this.treeAdapter.getChildNodes(parent);
|
|
const commentNode = children[children.length - 1];
|
|
|
|
this.treeAdapter.setNodeSourceCodeLocation(commentNode, token.location);
|
|
},
|
|
|
|
//Text
|
|
_findFosterParentingLocation() {
|
|
//NOTE: store last foster parenting location, so we will be able to find inserted text
|
|
//in case of foster parenting
|
|
mxn.lastFosterParentingLocation = orig._findFosterParentingLocation.call(this);
|
|
|
|
return mxn.lastFosterParentingLocation;
|
|
},
|
|
|
|
_insertCharacters(token) {
|
|
orig._insertCharacters.call(this, token);
|
|
|
|
const hasFosterParent = this._shouldFosterParentOnInsertion();
|
|
|
|
const parent =
|
|
(hasFosterParent && mxn.lastFosterParentingLocation.parent) ||
|
|
this.openElements.currentTmplContent ||
|
|
this.openElements.current;
|
|
|
|
const siblings = this.treeAdapter.getChildNodes(parent);
|
|
|
|
const textNodeIdx =
|
|
hasFosterParent && mxn.lastFosterParentingLocation.beforeElement
|
|
? siblings.indexOf(mxn.lastFosterParentingLocation.beforeElement) - 1
|
|
: siblings.length - 1;
|
|
|
|
const textNode = siblings[textNodeIdx];
|
|
|
|
//NOTE: if we have location assigned by another token, then just update end position
|
|
const tnLoc = this.treeAdapter.getNodeSourceCodeLocation(textNode);
|
|
|
|
if (tnLoc) {
|
|
const { endLine, endCol, endOffset } = token.location;
|
|
this.treeAdapter.updateNodeSourceCodeLocation(textNode, { endLine, endCol, endOffset });
|
|
} else {
|
|
this.treeAdapter.setNodeSourceCodeLocation(textNode, token.location);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = LocationInfoParserMixin;
|
|
|
|
},{"../../common/html":67,"../../tokenizer":82,"../../utils/mixin":87,"./open-element-stack-mixin":73,"./tokenizer-mixin":75}],75:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const Mixin = require('../../utils/mixin');
|
|
const Tokenizer = require('../../tokenizer');
|
|
const PositionTrackingPreprocessorMixin = require('../position-tracking/preprocessor-mixin');
|
|
|
|
class LocationInfoTokenizerMixin extends Mixin {
|
|
constructor(tokenizer) {
|
|
super(tokenizer);
|
|
|
|
this.tokenizer = tokenizer;
|
|
this.posTracker = Mixin.install(tokenizer.preprocessor, PositionTrackingPreprocessorMixin);
|
|
this.currentAttrLocation = null;
|
|
this.ctLoc = null;
|
|
}
|
|
|
|
_getCurrentLocation() {
|
|
return {
|
|
startLine: this.posTracker.line,
|
|
startCol: this.posTracker.col,
|
|
startOffset: this.posTracker.offset,
|
|
endLine: -1,
|
|
endCol: -1,
|
|
endOffset: -1
|
|
};
|
|
}
|
|
|
|
_attachCurrentAttrLocationInfo() {
|
|
this.currentAttrLocation.endLine = this.posTracker.line;
|
|
this.currentAttrLocation.endCol = this.posTracker.col;
|
|
this.currentAttrLocation.endOffset = this.posTracker.offset;
|
|
|
|
const currentToken = this.tokenizer.currentToken;
|
|
const currentAttr = this.tokenizer.currentAttr;
|
|
|
|
if (!currentToken.location.attrs) {
|
|
currentToken.location.attrs = Object.create(null);
|
|
}
|
|
|
|
currentToken.location.attrs[currentAttr.name] = this.currentAttrLocation;
|
|
}
|
|
|
|
_getOverriddenMethods(mxn, orig) {
|
|
const methods = {
|
|
_createStartTagToken() {
|
|
orig._createStartTagToken.call(this);
|
|
this.currentToken.location = mxn.ctLoc;
|
|
},
|
|
|
|
_createEndTagToken() {
|
|
orig._createEndTagToken.call(this);
|
|
this.currentToken.location = mxn.ctLoc;
|
|
},
|
|
|
|
_createCommentToken() {
|
|
orig._createCommentToken.call(this);
|
|
this.currentToken.location = mxn.ctLoc;
|
|
},
|
|
|
|
_createDoctypeToken(initialName) {
|
|
orig._createDoctypeToken.call(this, initialName);
|
|
this.currentToken.location = mxn.ctLoc;
|
|
},
|
|
|
|
_createCharacterToken(type, ch) {
|
|
orig._createCharacterToken.call(this, type, ch);
|
|
this.currentCharacterToken.location = mxn.ctLoc;
|
|
},
|
|
|
|
_createEOFToken() {
|
|
orig._createEOFToken.call(this);
|
|
this.currentToken.location = mxn._getCurrentLocation();
|
|
},
|
|
|
|
_createAttr(attrNameFirstCh) {
|
|
orig._createAttr.call(this, attrNameFirstCh);
|
|
mxn.currentAttrLocation = mxn._getCurrentLocation();
|
|
},
|
|
|
|
_leaveAttrName(toState) {
|
|
orig._leaveAttrName.call(this, toState);
|
|
mxn._attachCurrentAttrLocationInfo();
|
|
},
|
|
|
|
_leaveAttrValue(toState) {
|
|
orig._leaveAttrValue.call(this, toState);
|
|
mxn._attachCurrentAttrLocationInfo();
|
|
},
|
|
|
|
_emitCurrentToken() {
|
|
const ctLoc = this.currentToken.location;
|
|
|
|
//NOTE: if we have pending character token make it's end location equal to the
|
|
//current token's start location.
|
|
if (this.currentCharacterToken) {
|
|
this.currentCharacterToken.location.endLine = ctLoc.startLine;
|
|
this.currentCharacterToken.location.endCol = ctLoc.startCol;
|
|
this.currentCharacterToken.location.endOffset = ctLoc.startOffset;
|
|
}
|
|
|
|
if (this.currentToken.type === Tokenizer.EOF_TOKEN) {
|
|
ctLoc.endLine = ctLoc.startLine;
|
|
ctLoc.endCol = ctLoc.startCol;
|
|
ctLoc.endOffset = ctLoc.startOffset;
|
|
} else {
|
|
ctLoc.endLine = mxn.posTracker.line;
|
|
ctLoc.endCol = mxn.posTracker.col + 1;
|
|
ctLoc.endOffset = mxn.posTracker.offset + 1;
|
|
}
|
|
|
|
orig._emitCurrentToken.call(this);
|
|
},
|
|
|
|
_emitCurrentCharacterToken() {
|
|
const ctLoc = this.currentCharacterToken && this.currentCharacterToken.location;
|
|
|
|
//NOTE: if we have character token and it's location wasn't set in the _emitCurrentToken(),
|
|
//then set it's location at the current preprocessor position.
|
|
//We don't need to increment preprocessor position, since character token
|
|
//emission is always forced by the start of the next character token here.
|
|
//So, we already have advanced position.
|
|
if (ctLoc && ctLoc.endOffset === -1) {
|
|
ctLoc.endLine = mxn.posTracker.line;
|
|
ctLoc.endCol = mxn.posTracker.col;
|
|
ctLoc.endOffset = mxn.posTracker.offset;
|
|
}
|
|
|
|
orig._emitCurrentCharacterToken.call(this);
|
|
}
|
|
};
|
|
|
|
//NOTE: patch initial states for each mode to obtain token start position
|
|
Object.keys(Tokenizer.MODE).forEach(modeName => {
|
|
const state = Tokenizer.MODE[modeName];
|
|
|
|
methods[state] = function(cp) {
|
|
mxn.ctLoc = mxn._getCurrentLocation();
|
|
orig[state].call(this, cp);
|
|
};
|
|
});
|
|
|
|
return methods;
|
|
}
|
|
}
|
|
|
|
module.exports = LocationInfoTokenizerMixin;
|
|
|
|
},{"../../tokenizer":82,"../../utils/mixin":87,"../position-tracking/preprocessor-mixin":76}],76:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const Mixin = require('../../utils/mixin');
|
|
|
|
class PositionTrackingPreprocessorMixin extends Mixin {
|
|
constructor(preprocessor) {
|
|
super(preprocessor);
|
|
|
|
this.preprocessor = preprocessor;
|
|
this.isEol = false;
|
|
this.lineStartPos = 0;
|
|
this.droppedBufferSize = 0;
|
|
|
|
this.offset = 0;
|
|
this.col = 0;
|
|
this.line = 1;
|
|
}
|
|
|
|
_getOverriddenMethods(mxn, orig) {
|
|
return {
|
|
advance() {
|
|
const pos = this.pos + 1;
|
|
const ch = this.html[pos];
|
|
|
|
//NOTE: LF should be in the last column of the line
|
|
if (mxn.isEol) {
|
|
mxn.isEol = false;
|
|
mxn.line++;
|
|
mxn.lineStartPos = pos;
|
|
}
|
|
|
|
if (ch === '\n' || (ch === '\r' && this.html[pos + 1] !== '\n')) {
|
|
mxn.isEol = true;
|
|
}
|
|
|
|
mxn.col = pos - mxn.lineStartPos + 1;
|
|
mxn.offset = mxn.droppedBufferSize + pos;
|
|
|
|
return orig.advance.call(this);
|
|
},
|
|
|
|
retreat() {
|
|
orig.retreat.call(this);
|
|
|
|
mxn.isEol = false;
|
|
mxn.col = this.pos - mxn.lineStartPos + 1;
|
|
},
|
|
|
|
dropParsedChunk() {
|
|
const prevPos = this.pos;
|
|
|
|
orig.dropParsedChunk.call(this);
|
|
|
|
const reduction = prevPos - this.pos;
|
|
|
|
mxn.lineStartPos -= reduction;
|
|
mxn.droppedBufferSize += reduction;
|
|
mxn.offset = mxn.droppedBufferSize + this.pos;
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = PositionTrackingPreprocessorMixin;
|
|
|
|
},{"../../utils/mixin":87}],77:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const Parser = require('./parser');
|
|
const Serializer = require('./serializer');
|
|
|
|
// Shorthands
|
|
exports.parse = function parse(html, options) {
|
|
const parser = new Parser(options);
|
|
|
|
return parser.parse(html);
|
|
};
|
|
|
|
exports.parseFragment = function parseFragment(fragmentContext, html, options) {
|
|
if (typeof fragmentContext === 'string') {
|
|
options = html;
|
|
html = fragmentContext;
|
|
fragmentContext = null;
|
|
}
|
|
|
|
const parser = new Parser(options);
|
|
|
|
return parser.parseFragment(html, fragmentContext);
|
|
};
|
|
|
|
exports.serialize = function(node, options) {
|
|
const serializer = new Serializer(node, options);
|
|
|
|
return serializer.serialize();
|
|
};
|
|
|
|
},{"./parser":79,"./serializer":81}],78:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
//Const
|
|
const NOAH_ARK_CAPACITY = 3;
|
|
|
|
//List of formatting elements
|
|
class FormattingElementList {
|
|
constructor(treeAdapter) {
|
|
this.length = 0;
|
|
this.entries = [];
|
|
this.treeAdapter = treeAdapter;
|
|
this.bookmark = null;
|
|
}
|
|
|
|
//Noah Ark's condition
|
|
//OPTIMIZATION: at first we try to find possible candidates for exclusion using
|
|
//lightweight heuristics without thorough attributes check.
|
|
_getNoahArkConditionCandidates(newElement) {
|
|
const candidates = [];
|
|
|
|
if (this.length >= NOAH_ARK_CAPACITY) {
|
|
const neAttrsLength = this.treeAdapter.getAttrList(newElement).length;
|
|
const neTagName = this.treeAdapter.getTagName(newElement);
|
|
const neNamespaceURI = this.treeAdapter.getNamespaceURI(newElement);
|
|
|
|
for (let i = this.length - 1; i >= 0; i--) {
|
|
const entry = this.entries[i];
|
|
|
|
if (entry.type === FormattingElementList.MARKER_ENTRY) {
|
|
break;
|
|
}
|
|
|
|
const element = entry.element;
|
|
const elementAttrs = this.treeAdapter.getAttrList(element);
|
|
|
|
const isCandidate =
|
|
this.treeAdapter.getTagName(element) === neTagName &&
|
|
this.treeAdapter.getNamespaceURI(element) === neNamespaceURI &&
|
|
elementAttrs.length === neAttrsLength;
|
|
|
|
if (isCandidate) {
|
|
candidates.push({ idx: i, attrs: elementAttrs });
|
|
}
|
|
}
|
|
}
|
|
|
|
return candidates.length < NOAH_ARK_CAPACITY ? [] : candidates;
|
|
}
|
|
|
|
_ensureNoahArkCondition(newElement) {
|
|
const candidates = this._getNoahArkConditionCandidates(newElement);
|
|
let cLength = candidates.length;
|
|
|
|
if (cLength) {
|
|
const neAttrs = this.treeAdapter.getAttrList(newElement);
|
|
const neAttrsLength = neAttrs.length;
|
|
const neAttrsMap = Object.create(null);
|
|
|
|
//NOTE: build attrs map for the new element so we can perform fast lookups
|
|
for (let i = 0; i < neAttrsLength; i++) {
|
|
const neAttr = neAttrs[i];
|
|
|
|
neAttrsMap[neAttr.name] = neAttr.value;
|
|
}
|
|
|
|
for (let i = 0; i < neAttrsLength; i++) {
|
|
for (let j = 0; j < cLength; j++) {
|
|
const cAttr = candidates[j].attrs[i];
|
|
|
|
if (neAttrsMap[cAttr.name] !== cAttr.value) {
|
|
candidates.splice(j, 1);
|
|
cLength--;
|
|
}
|
|
|
|
if (candidates.length < NOAH_ARK_CAPACITY) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//NOTE: remove bottommost candidates until Noah's Ark condition will not be met
|
|
for (let i = cLength - 1; i >= NOAH_ARK_CAPACITY - 1; i--) {
|
|
this.entries.splice(candidates[i].idx, 1);
|
|
this.length--;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Mutations
|
|
insertMarker() {
|
|
this.entries.push({ type: FormattingElementList.MARKER_ENTRY });
|
|
this.length++;
|
|
}
|
|
|
|
pushElement(element, token) {
|
|
this._ensureNoahArkCondition(element);
|
|
|
|
this.entries.push({
|
|
type: FormattingElementList.ELEMENT_ENTRY,
|
|
element: element,
|
|
token: token
|
|
});
|
|
|
|
this.length++;
|
|
}
|
|
|
|
insertElementAfterBookmark(element, token) {
|
|
let bookmarkIdx = this.length - 1;
|
|
|
|
for (; bookmarkIdx >= 0; bookmarkIdx--) {
|
|
if (this.entries[bookmarkIdx] === this.bookmark) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
this.entries.splice(bookmarkIdx + 1, 0, {
|
|
type: FormattingElementList.ELEMENT_ENTRY,
|
|
element: element,
|
|
token: token
|
|
});
|
|
|
|
this.length++;
|
|
}
|
|
|
|
removeEntry(entry) {
|
|
for (let i = this.length - 1; i >= 0; i--) {
|
|
if (this.entries[i] === entry) {
|
|
this.entries.splice(i, 1);
|
|
this.length--;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
clearToLastMarker() {
|
|
while (this.length) {
|
|
const entry = this.entries.pop();
|
|
|
|
this.length--;
|
|
|
|
if (entry.type === FormattingElementList.MARKER_ENTRY) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Search
|
|
getElementEntryInScopeWithTagName(tagName) {
|
|
for (let i = this.length - 1; i >= 0; i--) {
|
|
const entry = this.entries[i];
|
|
|
|
if (entry.type === FormattingElementList.MARKER_ENTRY) {
|
|
return null;
|
|
}
|
|
|
|
if (this.treeAdapter.getTagName(entry.element) === tagName) {
|
|
return entry;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
getElementEntry(element) {
|
|
for (let i = this.length - 1; i >= 0; i--) {
|
|
const entry = this.entries[i];
|
|
|
|
if (entry.type === FormattingElementList.ELEMENT_ENTRY && entry.element === element) {
|
|
return entry;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
//Entry types
|
|
FormattingElementList.MARKER_ENTRY = 'MARKER_ENTRY';
|
|
FormattingElementList.ELEMENT_ENTRY = 'ELEMENT_ENTRY';
|
|
|
|
module.exports = FormattingElementList;
|
|
|
|
},{}],79:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const Tokenizer = require('../tokenizer');
|
|
const OpenElementStack = require('./open-element-stack');
|
|
const FormattingElementList = require('./formatting-element-list');
|
|
const LocationInfoParserMixin = require('../extensions/location-info/parser-mixin');
|
|
const ErrorReportingParserMixin = require('../extensions/error-reporting/parser-mixin');
|
|
const Mixin = require('../utils/mixin');
|
|
const defaultTreeAdapter = require('../tree-adapters/default');
|
|
const mergeOptions = require('../utils/merge-options');
|
|
const doctype = require('../common/doctype');
|
|
const foreignContent = require('../common/foreign-content');
|
|
const ERR = require('../common/error-codes');
|
|
const unicode = require('../common/unicode');
|
|
const HTML = require('../common/html');
|
|
|
|
//Aliases
|
|
const $ = HTML.TAG_NAMES;
|
|
const NS = HTML.NAMESPACES;
|
|
const ATTRS = HTML.ATTRS;
|
|
|
|
const DEFAULT_OPTIONS = {
|
|
scriptingEnabled: true,
|
|
sourceCodeLocationInfo: false,
|
|
onParseError: null,
|
|
treeAdapter: defaultTreeAdapter
|
|
};
|
|
|
|
//Misc constants
|
|
const HIDDEN_INPUT_TYPE = 'hidden';
|
|
|
|
//Adoption agency loops iteration count
|
|
const AA_OUTER_LOOP_ITER = 8;
|
|
const AA_INNER_LOOP_ITER = 3;
|
|
|
|
//Insertion modes
|
|
const INITIAL_MODE = 'INITIAL_MODE';
|
|
const BEFORE_HTML_MODE = 'BEFORE_HTML_MODE';
|
|
const BEFORE_HEAD_MODE = 'BEFORE_HEAD_MODE';
|
|
const IN_HEAD_MODE = 'IN_HEAD_MODE';
|
|
const IN_HEAD_NO_SCRIPT_MODE = 'IN_HEAD_NO_SCRIPT_MODE';
|
|
const AFTER_HEAD_MODE = 'AFTER_HEAD_MODE';
|
|
const IN_BODY_MODE = 'IN_BODY_MODE';
|
|
const TEXT_MODE = 'TEXT_MODE';
|
|
const IN_TABLE_MODE = 'IN_TABLE_MODE';
|
|
const IN_TABLE_TEXT_MODE = 'IN_TABLE_TEXT_MODE';
|
|
const IN_CAPTION_MODE = 'IN_CAPTION_MODE';
|
|
const IN_COLUMN_GROUP_MODE = 'IN_COLUMN_GROUP_MODE';
|
|
const IN_TABLE_BODY_MODE = 'IN_TABLE_BODY_MODE';
|
|
const IN_ROW_MODE = 'IN_ROW_MODE';
|
|
const IN_CELL_MODE = 'IN_CELL_MODE';
|
|
const IN_SELECT_MODE = 'IN_SELECT_MODE';
|
|
const IN_SELECT_IN_TABLE_MODE = 'IN_SELECT_IN_TABLE_MODE';
|
|
const IN_TEMPLATE_MODE = 'IN_TEMPLATE_MODE';
|
|
const AFTER_BODY_MODE = 'AFTER_BODY_MODE';
|
|
const IN_FRAMESET_MODE = 'IN_FRAMESET_MODE';
|
|
const AFTER_FRAMESET_MODE = 'AFTER_FRAMESET_MODE';
|
|
const AFTER_AFTER_BODY_MODE = 'AFTER_AFTER_BODY_MODE';
|
|
const AFTER_AFTER_FRAMESET_MODE = 'AFTER_AFTER_FRAMESET_MODE';
|
|
|
|
//Insertion mode reset map
|
|
const INSERTION_MODE_RESET_MAP = {
|
|
[$.TR]: IN_ROW_MODE,
|
|
[$.TBODY]: IN_TABLE_BODY_MODE,
|
|
[$.THEAD]: IN_TABLE_BODY_MODE,
|
|
[$.TFOOT]: IN_TABLE_BODY_MODE,
|
|
[$.CAPTION]: IN_CAPTION_MODE,
|
|
[$.COLGROUP]: IN_COLUMN_GROUP_MODE,
|
|
[$.TABLE]: IN_TABLE_MODE,
|
|
[$.BODY]: IN_BODY_MODE,
|
|
[$.FRAMESET]: IN_FRAMESET_MODE
|
|
};
|
|
|
|
//Template insertion mode switch map
|
|
const TEMPLATE_INSERTION_MODE_SWITCH_MAP = {
|
|
[$.CAPTION]: IN_TABLE_MODE,
|
|
[$.COLGROUP]: IN_TABLE_MODE,
|
|
[$.TBODY]: IN_TABLE_MODE,
|
|
[$.TFOOT]: IN_TABLE_MODE,
|
|
[$.THEAD]: IN_TABLE_MODE,
|
|
[$.COL]: IN_COLUMN_GROUP_MODE,
|
|
[$.TR]: IN_TABLE_BODY_MODE,
|
|
[$.TD]: IN_ROW_MODE,
|
|
[$.TH]: IN_ROW_MODE
|
|
};
|
|
|
|
//Token handlers map for insertion modes
|
|
const TOKEN_HANDLERS = {
|
|
[INITIAL_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: tokenInInitialMode,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenInInitialMode,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: doctypeInInitialMode,
|
|
[Tokenizer.START_TAG_TOKEN]: tokenInInitialMode,
|
|
[Tokenizer.END_TAG_TOKEN]: tokenInInitialMode,
|
|
[Tokenizer.EOF_TOKEN]: tokenInInitialMode
|
|
},
|
|
[BEFORE_HTML_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: tokenBeforeHtml,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenBeforeHtml,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagBeforeHtml,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagBeforeHtml,
|
|
[Tokenizer.EOF_TOKEN]: tokenBeforeHtml
|
|
},
|
|
[BEFORE_HEAD_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: tokenBeforeHead,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenBeforeHead,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: misplacedDoctype,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagBeforeHead,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagBeforeHead,
|
|
[Tokenizer.EOF_TOKEN]: tokenBeforeHead
|
|
},
|
|
[IN_HEAD_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: tokenInHead,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenInHead,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: misplacedDoctype,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagInHead,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagInHead,
|
|
[Tokenizer.EOF_TOKEN]: tokenInHead
|
|
},
|
|
[IN_HEAD_NO_SCRIPT_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: tokenInHeadNoScript,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenInHeadNoScript,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: misplacedDoctype,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagInHeadNoScript,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagInHeadNoScript,
|
|
[Tokenizer.EOF_TOKEN]: tokenInHeadNoScript
|
|
},
|
|
[AFTER_HEAD_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: tokenAfterHead,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenAfterHead,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: misplacedDoctype,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagAfterHead,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagAfterHead,
|
|
[Tokenizer.EOF_TOKEN]: tokenAfterHead
|
|
},
|
|
[IN_BODY_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: characterInBody,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagInBody,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagInBody,
|
|
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
},
|
|
[TEXT_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: insertCharacters,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: insertCharacters,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
[Tokenizer.COMMENT_TOKEN]: ignoreToken,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: ignoreToken,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagInText,
|
|
[Tokenizer.EOF_TOKEN]: eofInText
|
|
},
|
|
[IN_TABLE_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: characterInTable,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: characterInTable,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: characterInTable,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagInTable,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagInTable,
|
|
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
},
|
|
[IN_TABLE_TEXT_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: characterInTableText,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInTableText,
|
|
[Tokenizer.COMMENT_TOKEN]: tokenInTableText,
|
|
[Tokenizer.DOCTYPE_TOKEN]: tokenInTableText,
|
|
[Tokenizer.START_TAG_TOKEN]: tokenInTableText,
|
|
[Tokenizer.END_TAG_TOKEN]: tokenInTableText,
|
|
[Tokenizer.EOF_TOKEN]: tokenInTableText
|
|
},
|
|
[IN_CAPTION_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: characterInBody,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagInCaption,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagInCaption,
|
|
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
},
|
|
[IN_COLUMN_GROUP_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: tokenInColumnGroup,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenInColumnGroup,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagInColumnGroup,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagInColumnGroup,
|
|
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
},
|
|
[IN_TABLE_BODY_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: characterInTable,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: characterInTable,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: characterInTable,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagInTableBody,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagInTableBody,
|
|
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
},
|
|
[IN_ROW_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: characterInTable,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: characterInTable,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: characterInTable,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagInRow,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagInRow,
|
|
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
},
|
|
[IN_CELL_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: characterInBody,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagInCell,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagInCell,
|
|
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
},
|
|
[IN_SELECT_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: insertCharacters,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagInSelect,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagInSelect,
|
|
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
},
|
|
[IN_SELECT_IN_TABLE_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: insertCharacters,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagInSelectInTable,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagInSelectInTable,
|
|
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
},
|
|
[IN_TEMPLATE_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: characterInBody,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagInTemplate,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagInTemplate,
|
|
[Tokenizer.EOF_TOKEN]: eofInTemplate
|
|
},
|
|
[AFTER_BODY_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: tokenAfterBody,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenAfterBody,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
|
|
[Tokenizer.COMMENT_TOKEN]: appendCommentToRootHtmlElement,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagAfterBody,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagAfterBody,
|
|
[Tokenizer.EOF_TOKEN]: stopParsing
|
|
},
|
|
[IN_FRAMESET_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagInFrameset,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagInFrameset,
|
|
[Tokenizer.EOF_TOKEN]: stopParsing
|
|
},
|
|
[AFTER_FRAMESET_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagAfterFrameset,
|
|
[Tokenizer.END_TAG_TOKEN]: endTagAfterFrameset,
|
|
[Tokenizer.EOF_TOKEN]: stopParsing
|
|
},
|
|
[AFTER_AFTER_BODY_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: tokenAfterAfterBody,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenAfterAfterBody,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
|
|
[Tokenizer.COMMENT_TOKEN]: appendCommentToDocument,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagAfterAfterBody,
|
|
[Tokenizer.END_TAG_TOKEN]: tokenAfterAfterBody,
|
|
[Tokenizer.EOF_TOKEN]: stopParsing
|
|
},
|
|
[AFTER_AFTER_FRAMESET_MODE]: {
|
|
[Tokenizer.CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
|
|
[Tokenizer.COMMENT_TOKEN]: appendCommentToDocument,
|
|
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
[Tokenizer.START_TAG_TOKEN]: startTagAfterAfterFrameset,
|
|
[Tokenizer.END_TAG_TOKEN]: ignoreToken,
|
|
[Tokenizer.EOF_TOKEN]: stopParsing
|
|
}
|
|
};
|
|
|
|
//Parser
|
|
class Parser {
|
|
constructor(options) {
|
|
this.options = mergeOptions(DEFAULT_OPTIONS, options);
|
|
|
|
this.treeAdapter = this.options.treeAdapter;
|
|
this.pendingScript = null;
|
|
|
|
if (this.options.sourceCodeLocationInfo) {
|
|
Mixin.install(this, LocationInfoParserMixin);
|
|
}
|
|
|
|
if (this.options.onParseError) {
|
|
Mixin.install(this, ErrorReportingParserMixin, { onParseError: this.options.onParseError });
|
|
}
|
|
}
|
|
|
|
// API
|
|
parse(html) {
|
|
const document = this.treeAdapter.createDocument();
|
|
|
|
this._bootstrap(document, null);
|
|
this.tokenizer.write(html, true);
|
|
this._runParsingLoop(null);
|
|
|
|
return document;
|
|
}
|
|
|
|
parseFragment(html, fragmentContext) {
|
|
//NOTE: use <template> element as a fragment context if context element was not provided,
|
|
//so we will parse in "forgiving" manner
|
|
if (!fragmentContext) {
|
|
fragmentContext = this.treeAdapter.createElement($.TEMPLATE, NS.HTML, []);
|
|
}
|
|
|
|
//NOTE: create fake element which will be used as 'document' for fragment parsing.
|
|
//This is important for jsdom there 'document' can't be recreated, therefore
|
|
//fragment parsing causes messing of the main `document`.
|
|
const documentMock = this.treeAdapter.createElement('documentmock', NS.HTML, []);
|
|
|
|
this._bootstrap(documentMock, fragmentContext);
|
|
|
|
if (this.treeAdapter.getTagName(fragmentContext) === $.TEMPLATE) {
|
|
this._pushTmplInsertionMode(IN_TEMPLATE_MODE);
|
|
}
|
|
|
|
this._initTokenizerForFragmentParsing();
|
|
this._insertFakeRootElement();
|
|
this._resetInsertionMode();
|
|
this._findFormInFragmentContext();
|
|
this.tokenizer.write(html, true);
|
|
this._runParsingLoop(null);
|
|
|
|
const rootElement = this.treeAdapter.getFirstChild(documentMock);
|
|
const fragment = this.treeAdapter.createDocumentFragment();
|
|
|
|
this._adoptNodes(rootElement, fragment);
|
|
|
|
return fragment;
|
|
}
|
|
|
|
//Bootstrap parser
|
|
_bootstrap(document, fragmentContext) {
|
|
this.tokenizer = new Tokenizer(this.options);
|
|
|
|
this.stopped = false;
|
|
|
|
this.insertionMode = INITIAL_MODE;
|
|
this.originalInsertionMode = '';
|
|
|
|
this.document = document;
|
|
this.fragmentContext = fragmentContext;
|
|
|
|
this.headElement = null;
|
|
this.formElement = null;
|
|
|
|
this.openElements = new OpenElementStack(this.document, this.treeAdapter);
|
|
this.activeFormattingElements = new FormattingElementList(this.treeAdapter);
|
|
|
|
this.tmplInsertionModeStack = [];
|
|
this.tmplInsertionModeStackTop = -1;
|
|
this.currentTmplInsertionMode = null;
|
|
|
|
this.pendingCharacterTokens = [];
|
|
this.hasNonWhitespacePendingCharacterToken = false;
|
|
|
|
this.framesetOk = true;
|
|
this.skipNextNewLine = false;
|
|
this.fosterParentingEnabled = false;
|
|
}
|
|
|
|
//Errors
|
|
_err() {
|
|
// NOTE: err reporting is noop by default. Enabled by mixin.
|
|
}
|
|
|
|
//Parsing loop
|
|
_runParsingLoop(scriptHandler) {
|
|
while (!this.stopped) {
|
|
this._setupTokenizerCDATAMode();
|
|
|
|
const token = this.tokenizer.getNextToken();
|
|
|
|
if (token.type === Tokenizer.HIBERNATION_TOKEN) {
|
|
break;
|
|
}
|
|
|
|
if (this.skipNextNewLine) {
|
|
this.skipNextNewLine = false;
|
|
|
|
if (token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN && token.chars[0] === '\n') {
|
|
if (token.chars.length === 1) {
|
|
continue;
|
|
}
|
|
|
|
token.chars = token.chars.substr(1);
|
|
}
|
|
}
|
|
|
|
this._processInputToken(token);
|
|
|
|
if (scriptHandler && this.pendingScript) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
runParsingLoopForCurrentChunk(writeCallback, scriptHandler) {
|
|
this._runParsingLoop(scriptHandler);
|
|
|
|
if (scriptHandler && this.pendingScript) {
|
|
const script = this.pendingScript;
|
|
|
|
this.pendingScript = null;
|
|
|
|
scriptHandler(script);
|
|
|
|
return;
|
|
}
|
|
|
|
if (writeCallback) {
|
|
writeCallback();
|
|
}
|
|
}
|
|
|
|
//Text parsing
|
|
_setupTokenizerCDATAMode() {
|
|
const current = this._getAdjustedCurrentElement();
|
|
|
|
this.tokenizer.allowCDATA =
|
|
current &&
|
|
current !== this.document &&
|
|
this.treeAdapter.getNamespaceURI(current) !== NS.HTML &&
|
|
!this._isIntegrationPoint(current);
|
|
}
|
|
|
|
_switchToTextParsing(currentToken, nextTokenizerState) {
|
|
this._insertElement(currentToken, NS.HTML);
|
|
this.tokenizer.state = nextTokenizerState;
|
|
this.originalInsertionMode = this.insertionMode;
|
|
this.insertionMode = TEXT_MODE;
|
|
}
|
|
|
|
switchToPlaintextParsing() {
|
|
this.insertionMode = TEXT_MODE;
|
|
this.originalInsertionMode = IN_BODY_MODE;
|
|
this.tokenizer.state = Tokenizer.MODE.PLAINTEXT;
|
|
}
|
|
|
|
//Fragment parsing
|
|
_getAdjustedCurrentElement() {
|
|
return this.openElements.stackTop === 0 && this.fragmentContext
|
|
? this.fragmentContext
|
|
: this.openElements.current;
|
|
}
|
|
|
|
_findFormInFragmentContext() {
|
|
let node = this.fragmentContext;
|
|
|
|
do {
|
|
if (this.treeAdapter.getTagName(node) === $.FORM) {
|
|
this.formElement = node;
|
|
break;
|
|
}
|
|
|
|
node = this.treeAdapter.getParentNode(node);
|
|
} while (node);
|
|
}
|
|
|
|
_initTokenizerForFragmentParsing() {
|
|
if (this.treeAdapter.getNamespaceURI(this.fragmentContext) === NS.HTML) {
|
|
const tn = this.treeAdapter.getTagName(this.fragmentContext);
|
|
|
|
if (tn === $.TITLE || tn === $.TEXTAREA) {
|
|
this.tokenizer.state = Tokenizer.MODE.RCDATA;
|
|
} else if (
|
|
tn === $.STYLE ||
|
|
tn === $.XMP ||
|
|
tn === $.IFRAME ||
|
|
tn === $.NOEMBED ||
|
|
tn === $.NOFRAMES ||
|
|
tn === $.NOSCRIPT
|
|
) {
|
|
this.tokenizer.state = Tokenizer.MODE.RAWTEXT;
|
|
} else if (tn === $.SCRIPT) {
|
|
this.tokenizer.state = Tokenizer.MODE.SCRIPT_DATA;
|
|
} else if (tn === $.PLAINTEXT) {
|
|
this.tokenizer.state = Tokenizer.MODE.PLAINTEXT;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Tree mutation
|
|
_setDocumentType(token) {
|
|
const name = token.name || '';
|
|
const publicId = token.publicId || '';
|
|
const systemId = token.systemId || '';
|
|
|
|
this.treeAdapter.setDocumentType(this.document, name, publicId, systemId);
|
|
}
|
|
|
|
_attachElementToTree(element) {
|
|
if (this._shouldFosterParentOnInsertion()) {
|
|
this._fosterParentElement(element);
|
|
} else {
|
|
const parent = this.openElements.currentTmplContent || this.openElements.current;
|
|
|
|
this.treeAdapter.appendChild(parent, element);
|
|
}
|
|
}
|
|
|
|
_appendElement(token, namespaceURI) {
|
|
const element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
|
|
|
|
this._attachElementToTree(element);
|
|
}
|
|
|
|
_insertElement(token, namespaceURI) {
|
|
const element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
|
|
|
|
this._attachElementToTree(element);
|
|
this.openElements.push(element);
|
|
}
|
|
|
|
_insertFakeElement(tagName) {
|
|
const element = this.treeAdapter.createElement(tagName, NS.HTML, []);
|
|
|
|
this._attachElementToTree(element);
|
|
this.openElements.push(element);
|
|
}
|
|
|
|
_insertTemplate(token) {
|
|
const tmpl = this.treeAdapter.createElement(token.tagName, NS.HTML, token.attrs);
|
|
const content = this.treeAdapter.createDocumentFragment();
|
|
|
|
this.treeAdapter.setTemplateContent(tmpl, content);
|
|
this._attachElementToTree(tmpl);
|
|
this.openElements.push(tmpl);
|
|
}
|
|
|
|
_insertFakeRootElement() {
|
|
const element = this.treeAdapter.createElement($.HTML, NS.HTML, []);
|
|
|
|
this.treeAdapter.appendChild(this.openElements.current, element);
|
|
this.openElements.push(element);
|
|
}
|
|
|
|
_appendCommentNode(token, parent) {
|
|
const commentNode = this.treeAdapter.createCommentNode(token.data);
|
|
|
|
this.treeAdapter.appendChild(parent, commentNode);
|
|
}
|
|
|
|
_insertCharacters(token) {
|
|
if (this._shouldFosterParentOnInsertion()) {
|
|
this._fosterParentText(token.chars);
|
|
} else {
|
|
const parent = this.openElements.currentTmplContent || this.openElements.current;
|
|
|
|
this.treeAdapter.insertText(parent, token.chars);
|
|
}
|
|
}
|
|
|
|
_adoptNodes(donor, recipient) {
|
|
for (let child = this.treeAdapter.getFirstChild(donor); child; child = this.treeAdapter.getFirstChild(donor)) {
|
|
this.treeAdapter.detachNode(child);
|
|
this.treeAdapter.appendChild(recipient, child);
|
|
}
|
|
}
|
|
|
|
//Token processing
|
|
_shouldProcessTokenInForeignContent(token) {
|
|
const current = this._getAdjustedCurrentElement();
|
|
|
|
if (!current || current === this.document) {
|
|
return false;
|
|
}
|
|
|
|
const ns = this.treeAdapter.getNamespaceURI(current);
|
|
|
|
if (ns === NS.HTML) {
|
|
return false;
|
|
}
|
|
|
|
if (
|
|
this.treeAdapter.getTagName(current) === $.ANNOTATION_XML &&
|
|
ns === NS.MATHML &&
|
|
token.type === Tokenizer.START_TAG_TOKEN &&
|
|
token.tagName === $.SVG
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
const isCharacterToken =
|
|
token.type === Tokenizer.CHARACTER_TOKEN ||
|
|
token.type === Tokenizer.NULL_CHARACTER_TOKEN ||
|
|
token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN;
|
|
|
|
const isMathMLTextStartTag =
|
|
token.type === Tokenizer.START_TAG_TOKEN && token.tagName !== $.MGLYPH && token.tagName !== $.MALIGNMARK;
|
|
|
|
if ((isMathMLTextStartTag || isCharacterToken) && this._isIntegrationPoint(current, NS.MATHML)) {
|
|
return false;
|
|
}
|
|
|
|
if (
|
|
(token.type === Tokenizer.START_TAG_TOKEN || isCharacterToken) &&
|
|
this._isIntegrationPoint(current, NS.HTML)
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
return token.type !== Tokenizer.EOF_TOKEN;
|
|
}
|
|
|
|
_processToken(token) {
|
|
TOKEN_HANDLERS[this.insertionMode][token.type](this, token);
|
|
}
|
|
|
|
_processTokenInBodyMode(token) {
|
|
TOKEN_HANDLERS[IN_BODY_MODE][token.type](this, token);
|
|
}
|
|
|
|
_processTokenInForeignContent(token) {
|
|
if (token.type === Tokenizer.CHARACTER_TOKEN) {
|
|
characterInForeignContent(this, token);
|
|
} else if (token.type === Tokenizer.NULL_CHARACTER_TOKEN) {
|
|
nullCharacterInForeignContent(this, token);
|
|
} else if (token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN) {
|
|
insertCharacters(this, token);
|
|
} else if (token.type === Tokenizer.COMMENT_TOKEN) {
|
|
appendComment(this, token);
|
|
} else if (token.type === Tokenizer.START_TAG_TOKEN) {
|
|
startTagInForeignContent(this, token);
|
|
} else if (token.type === Tokenizer.END_TAG_TOKEN) {
|
|
endTagInForeignContent(this, token);
|
|
}
|
|
}
|
|
|
|
_processInputToken(token) {
|
|
if (this._shouldProcessTokenInForeignContent(token)) {
|
|
this._processTokenInForeignContent(token);
|
|
} else {
|
|
this._processToken(token);
|
|
}
|
|
|
|
if (token.type === Tokenizer.START_TAG_TOKEN && token.selfClosing && !token.ackSelfClosing) {
|
|
this._err(ERR.nonVoidHtmlElementStartTagWithTrailingSolidus);
|
|
}
|
|
}
|
|
|
|
//Integration points
|
|
_isIntegrationPoint(element, foreignNS) {
|
|
const tn = this.treeAdapter.getTagName(element);
|
|
const ns = this.treeAdapter.getNamespaceURI(element);
|
|
const attrs = this.treeAdapter.getAttrList(element);
|
|
|
|
return foreignContent.isIntegrationPoint(tn, ns, attrs, foreignNS);
|
|
}
|
|
|
|
//Active formatting elements reconstruction
|
|
_reconstructActiveFormattingElements() {
|
|
const listLength = this.activeFormattingElements.length;
|
|
|
|
if (listLength) {
|
|
let unopenIdx = listLength;
|
|
let entry = null;
|
|
|
|
do {
|
|
unopenIdx--;
|
|
entry = this.activeFormattingElements.entries[unopenIdx];
|
|
|
|
if (entry.type === FormattingElementList.MARKER_ENTRY || this.openElements.contains(entry.element)) {
|
|
unopenIdx++;
|
|
break;
|
|
}
|
|
} while (unopenIdx > 0);
|
|
|
|
for (let i = unopenIdx; i < listLength; i++) {
|
|
entry = this.activeFormattingElements.entries[i];
|
|
this._insertElement(entry.token, this.treeAdapter.getNamespaceURI(entry.element));
|
|
entry.element = this.openElements.current;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Close elements
|
|
_closeTableCell() {
|
|
this.openElements.generateImpliedEndTags();
|
|
this.openElements.popUntilTableCellPopped();
|
|
this.activeFormattingElements.clearToLastMarker();
|
|
this.insertionMode = IN_ROW_MODE;
|
|
}
|
|
|
|
_closePElement() {
|
|
this.openElements.generateImpliedEndTagsWithExclusion($.P);
|
|
this.openElements.popUntilTagNamePopped($.P);
|
|
}
|
|
|
|
//Insertion modes
|
|
_resetInsertionMode() {
|
|
for (let i = this.openElements.stackTop, last = false; i >= 0; i--) {
|
|
let element = this.openElements.items[i];
|
|
|
|
if (i === 0) {
|
|
last = true;
|
|
|
|
if (this.fragmentContext) {
|
|
element = this.fragmentContext;
|
|
}
|
|
}
|
|
|
|
const tn = this.treeAdapter.getTagName(element);
|
|
const newInsertionMode = INSERTION_MODE_RESET_MAP[tn];
|
|
|
|
if (newInsertionMode) {
|
|
this.insertionMode = newInsertionMode;
|
|
break;
|
|
} else if (!last && (tn === $.TD || tn === $.TH)) {
|
|
this.insertionMode = IN_CELL_MODE;
|
|
break;
|
|
} else if (!last && tn === $.HEAD) {
|
|
this.insertionMode = IN_HEAD_MODE;
|
|
break;
|
|
} else if (tn === $.SELECT) {
|
|
this._resetInsertionModeForSelect(i);
|
|
break;
|
|
} else if (tn === $.TEMPLATE) {
|
|
this.insertionMode = this.currentTmplInsertionMode;
|
|
break;
|
|
} else if (tn === $.HTML) {
|
|
this.insertionMode = this.headElement ? AFTER_HEAD_MODE : BEFORE_HEAD_MODE;
|
|
break;
|
|
} else if (last) {
|
|
this.insertionMode = IN_BODY_MODE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
_resetInsertionModeForSelect(selectIdx) {
|
|
if (selectIdx > 0) {
|
|
for (let i = selectIdx - 1; i > 0; i--) {
|
|
const ancestor = this.openElements.items[i];
|
|
const tn = this.treeAdapter.getTagName(ancestor);
|
|
|
|
if (tn === $.TEMPLATE) {
|
|
break;
|
|
} else if (tn === $.TABLE) {
|
|
this.insertionMode = IN_SELECT_IN_TABLE_MODE;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.insertionMode = IN_SELECT_MODE;
|
|
}
|
|
|
|
_pushTmplInsertionMode(mode) {
|
|
this.tmplInsertionModeStack.push(mode);
|
|
this.tmplInsertionModeStackTop++;
|
|
this.currentTmplInsertionMode = mode;
|
|
}
|
|
|
|
_popTmplInsertionMode() {
|
|
this.tmplInsertionModeStack.pop();
|
|
this.tmplInsertionModeStackTop--;
|
|
this.currentTmplInsertionMode = this.tmplInsertionModeStack[this.tmplInsertionModeStackTop];
|
|
}
|
|
|
|
//Foster parenting
|
|
_isElementCausesFosterParenting(element) {
|
|
const tn = this.treeAdapter.getTagName(element);
|
|
|
|
return tn === $.TABLE || tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD || tn === $.TR;
|
|
}
|
|
|
|
_shouldFosterParentOnInsertion() {
|
|
return this.fosterParentingEnabled && this._isElementCausesFosterParenting(this.openElements.current);
|
|
}
|
|
|
|
_findFosterParentingLocation() {
|
|
const location = {
|
|
parent: null,
|
|
beforeElement: null
|
|
};
|
|
|
|
for (let i = this.openElements.stackTop; i >= 0; i--) {
|
|
const openElement = this.openElements.items[i];
|
|
const tn = this.treeAdapter.getTagName(openElement);
|
|
const ns = this.treeAdapter.getNamespaceURI(openElement);
|
|
|
|
if (tn === $.TEMPLATE && ns === NS.HTML) {
|
|
location.parent = this.treeAdapter.getTemplateContent(openElement);
|
|
break;
|
|
} else if (tn === $.TABLE) {
|
|
location.parent = this.treeAdapter.getParentNode(openElement);
|
|
|
|
if (location.parent) {
|
|
location.beforeElement = openElement;
|
|
} else {
|
|
location.parent = this.openElements.items[i - 1];
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!location.parent) {
|
|
location.parent = this.openElements.items[0];
|
|
}
|
|
|
|
return location;
|
|
}
|
|
|
|
_fosterParentElement(element) {
|
|
const location = this._findFosterParentingLocation();
|
|
|
|
if (location.beforeElement) {
|
|
this.treeAdapter.insertBefore(location.parent, element, location.beforeElement);
|
|
} else {
|
|
this.treeAdapter.appendChild(location.parent, element);
|
|
}
|
|
}
|
|
|
|
_fosterParentText(chars) {
|
|
const location = this._findFosterParentingLocation();
|
|
|
|
if (location.beforeElement) {
|
|
this.treeAdapter.insertTextBefore(location.parent, chars, location.beforeElement);
|
|
} else {
|
|
this.treeAdapter.insertText(location.parent, chars);
|
|
}
|
|
}
|
|
|
|
//Special elements
|
|
_isSpecialElement(element) {
|
|
const tn = this.treeAdapter.getTagName(element);
|
|
const ns = this.treeAdapter.getNamespaceURI(element);
|
|
|
|
return HTML.SPECIAL_ELEMENTS[ns][tn];
|
|
}
|
|
}
|
|
|
|
module.exports = Parser;
|
|
|
|
//Adoption agency algorithm
|
|
//(see: http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#adoptionAgency)
|
|
//------------------------------------------------------------------
|
|
|
|
//Steps 5-8 of the algorithm
|
|
function aaObtainFormattingElementEntry(p, token) {
|
|
let formattingElementEntry = p.activeFormattingElements.getElementEntryInScopeWithTagName(token.tagName);
|
|
|
|
if (formattingElementEntry) {
|
|
if (!p.openElements.contains(formattingElementEntry.element)) {
|
|
p.activeFormattingElements.removeEntry(formattingElementEntry);
|
|
formattingElementEntry = null;
|
|
} else if (!p.openElements.hasInScope(token.tagName)) {
|
|
formattingElementEntry = null;
|
|
}
|
|
} else {
|
|
genericEndTagInBody(p, token);
|
|
}
|
|
|
|
return formattingElementEntry;
|
|
}
|
|
|
|
//Steps 9 and 10 of the algorithm
|
|
function aaObtainFurthestBlock(p, formattingElementEntry) {
|
|
let furthestBlock = null;
|
|
|
|
for (let i = p.openElements.stackTop; i >= 0; i--) {
|
|
const element = p.openElements.items[i];
|
|
|
|
if (element === formattingElementEntry.element) {
|
|
break;
|
|
}
|
|
|
|
if (p._isSpecialElement(element)) {
|
|
furthestBlock = element;
|
|
}
|
|
}
|
|
|
|
if (!furthestBlock) {
|
|
p.openElements.popUntilElementPopped(formattingElementEntry.element);
|
|
p.activeFormattingElements.removeEntry(formattingElementEntry);
|
|
}
|
|
|
|
return furthestBlock;
|
|
}
|
|
|
|
//Step 13 of the algorithm
|
|
function aaInnerLoop(p, furthestBlock, formattingElement) {
|
|
let lastElement = furthestBlock;
|
|
let nextElement = p.openElements.getCommonAncestor(furthestBlock);
|
|
|
|
for (let i = 0, element = nextElement; element !== formattingElement; i++, element = nextElement) {
|
|
//NOTE: store next element for the next loop iteration (it may be deleted from the stack by step 9.5)
|
|
nextElement = p.openElements.getCommonAncestor(element);
|
|
|
|
const elementEntry = p.activeFormattingElements.getElementEntry(element);
|
|
const counterOverflow = elementEntry && i >= AA_INNER_LOOP_ITER;
|
|
const shouldRemoveFromOpenElements = !elementEntry || counterOverflow;
|
|
|
|
if (shouldRemoveFromOpenElements) {
|
|
if (counterOverflow) {
|
|
p.activeFormattingElements.removeEntry(elementEntry);
|
|
}
|
|
|
|
p.openElements.remove(element);
|
|
} else {
|
|
element = aaRecreateElementFromEntry(p, elementEntry);
|
|
|
|
if (lastElement === furthestBlock) {
|
|
p.activeFormattingElements.bookmark = elementEntry;
|
|
}
|
|
|
|
p.treeAdapter.detachNode(lastElement);
|
|
p.treeAdapter.appendChild(element, lastElement);
|
|
lastElement = element;
|
|
}
|
|
}
|
|
|
|
return lastElement;
|
|
}
|
|
|
|
//Step 13.7 of the algorithm
|
|
function aaRecreateElementFromEntry(p, elementEntry) {
|
|
const ns = p.treeAdapter.getNamespaceURI(elementEntry.element);
|
|
const newElement = p.treeAdapter.createElement(elementEntry.token.tagName, ns, elementEntry.token.attrs);
|
|
|
|
p.openElements.replace(elementEntry.element, newElement);
|
|
elementEntry.element = newElement;
|
|
|
|
return newElement;
|
|
}
|
|
|
|
//Step 14 of the algorithm
|
|
function aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement) {
|
|
if (p._isElementCausesFosterParenting(commonAncestor)) {
|
|
p._fosterParentElement(lastElement);
|
|
} else {
|
|
const tn = p.treeAdapter.getTagName(commonAncestor);
|
|
const ns = p.treeAdapter.getNamespaceURI(commonAncestor);
|
|
|
|
if (tn === $.TEMPLATE && ns === NS.HTML) {
|
|
commonAncestor = p.treeAdapter.getTemplateContent(commonAncestor);
|
|
}
|
|
|
|
p.treeAdapter.appendChild(commonAncestor, lastElement);
|
|
}
|
|
}
|
|
|
|
//Steps 15-19 of the algorithm
|
|
function aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry) {
|
|
const ns = p.treeAdapter.getNamespaceURI(formattingElementEntry.element);
|
|
const token = formattingElementEntry.token;
|
|
const newElement = p.treeAdapter.createElement(token.tagName, ns, token.attrs);
|
|
|
|
p._adoptNodes(furthestBlock, newElement);
|
|
p.treeAdapter.appendChild(furthestBlock, newElement);
|
|
|
|
p.activeFormattingElements.insertElementAfterBookmark(newElement, formattingElementEntry.token);
|
|
p.activeFormattingElements.removeEntry(formattingElementEntry);
|
|
|
|
p.openElements.remove(formattingElementEntry.element);
|
|
p.openElements.insertAfter(furthestBlock, newElement);
|
|
}
|
|
|
|
//Algorithm entry point
|
|
function callAdoptionAgency(p, token) {
|
|
let formattingElementEntry;
|
|
|
|
for (let i = 0; i < AA_OUTER_LOOP_ITER; i++) {
|
|
formattingElementEntry = aaObtainFormattingElementEntry(p, token, formattingElementEntry);
|
|
|
|
if (!formattingElementEntry) {
|
|
break;
|
|
}
|
|
|
|
const furthestBlock = aaObtainFurthestBlock(p, formattingElementEntry);
|
|
|
|
if (!furthestBlock) {
|
|
break;
|
|
}
|
|
|
|
p.activeFormattingElements.bookmark = formattingElementEntry;
|
|
|
|
const lastElement = aaInnerLoop(p, furthestBlock, formattingElementEntry.element);
|
|
const commonAncestor = p.openElements.getCommonAncestor(formattingElementEntry.element);
|
|
|
|
p.treeAdapter.detachNode(lastElement);
|
|
aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement);
|
|
aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry);
|
|
}
|
|
}
|
|
|
|
//Generic token handlers
|
|
//------------------------------------------------------------------
|
|
function ignoreToken() {
|
|
//NOTE: do nothing =)
|
|
}
|
|
|
|
function misplacedDoctype(p) {
|
|
p._err(ERR.misplacedDoctype);
|
|
}
|
|
|
|
function appendComment(p, token) {
|
|
p._appendCommentNode(token, p.openElements.currentTmplContent || p.openElements.current);
|
|
}
|
|
|
|
function appendCommentToRootHtmlElement(p, token) {
|
|
p._appendCommentNode(token, p.openElements.items[0]);
|
|
}
|
|
|
|
function appendCommentToDocument(p, token) {
|
|
p._appendCommentNode(token, p.document);
|
|
}
|
|
|
|
function insertCharacters(p, token) {
|
|
p._insertCharacters(token);
|
|
}
|
|
|
|
function stopParsing(p) {
|
|
p.stopped = true;
|
|
}
|
|
|
|
// The "initial" insertion mode
|
|
//------------------------------------------------------------------
|
|
function doctypeInInitialMode(p, token) {
|
|
p._setDocumentType(token);
|
|
|
|
const mode = token.forceQuirks ? HTML.DOCUMENT_MODE.QUIRKS : doctype.getDocumentMode(token);
|
|
|
|
if (!doctype.isConforming(token)) {
|
|
p._err(ERR.nonConformingDoctype);
|
|
}
|
|
|
|
p.treeAdapter.setDocumentMode(p.document, mode);
|
|
|
|
p.insertionMode = BEFORE_HTML_MODE;
|
|
}
|
|
|
|
function tokenInInitialMode(p, token) {
|
|
p._err(ERR.missingDoctype, { beforeToken: true });
|
|
p.treeAdapter.setDocumentMode(p.document, HTML.DOCUMENT_MODE.QUIRKS);
|
|
p.insertionMode = BEFORE_HTML_MODE;
|
|
p._processToken(token);
|
|
}
|
|
|
|
// The "before html" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagBeforeHtml(p, token) {
|
|
if (token.tagName === $.HTML) {
|
|
p._insertElement(token, NS.HTML);
|
|
p.insertionMode = BEFORE_HEAD_MODE;
|
|
} else {
|
|
tokenBeforeHtml(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagBeforeHtml(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.HTML || tn === $.HEAD || tn === $.BODY || tn === $.BR) {
|
|
tokenBeforeHtml(p, token);
|
|
}
|
|
}
|
|
|
|
function tokenBeforeHtml(p, token) {
|
|
p._insertFakeRootElement();
|
|
p.insertionMode = BEFORE_HEAD_MODE;
|
|
p._processToken(token);
|
|
}
|
|
|
|
// The "before head" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagBeforeHead(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.HTML) {
|
|
startTagInBody(p, token);
|
|
} else if (tn === $.HEAD) {
|
|
p._insertElement(token, NS.HTML);
|
|
p.headElement = p.openElements.current;
|
|
p.insertionMode = IN_HEAD_MODE;
|
|
} else {
|
|
tokenBeforeHead(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagBeforeHead(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.HEAD || tn === $.BODY || tn === $.HTML || tn === $.BR) {
|
|
tokenBeforeHead(p, token);
|
|
} else {
|
|
p._err(ERR.endTagWithoutMatchingOpenElement);
|
|
}
|
|
}
|
|
|
|
function tokenBeforeHead(p, token) {
|
|
p._insertFakeElement($.HEAD);
|
|
p.headElement = p.openElements.current;
|
|
p.insertionMode = IN_HEAD_MODE;
|
|
p._processToken(token);
|
|
}
|
|
|
|
// The "in head" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagInHead(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.HTML) {
|
|
startTagInBody(p, token);
|
|
} else if (tn === $.BASE || tn === $.BASEFONT || tn === $.BGSOUND || tn === $.LINK || tn === $.META) {
|
|
p._appendElement(token, NS.HTML);
|
|
token.ackSelfClosing = true;
|
|
} else if (tn === $.TITLE) {
|
|
p._switchToTextParsing(token, Tokenizer.MODE.RCDATA);
|
|
} else if (tn === $.NOSCRIPT) {
|
|
if (p.options.scriptingEnabled) {
|
|
p._switchToTextParsing(token, Tokenizer.MODE.RAWTEXT);
|
|
} else {
|
|
p._insertElement(token, NS.HTML);
|
|
p.insertionMode = IN_HEAD_NO_SCRIPT_MODE;
|
|
}
|
|
} else if (tn === $.NOFRAMES || tn === $.STYLE) {
|
|
p._switchToTextParsing(token, Tokenizer.MODE.RAWTEXT);
|
|
} else if (tn === $.SCRIPT) {
|
|
p._switchToTextParsing(token, Tokenizer.MODE.SCRIPT_DATA);
|
|
} else if (tn === $.TEMPLATE) {
|
|
p._insertTemplate(token, NS.HTML);
|
|
p.activeFormattingElements.insertMarker();
|
|
p.framesetOk = false;
|
|
p.insertionMode = IN_TEMPLATE_MODE;
|
|
p._pushTmplInsertionMode(IN_TEMPLATE_MODE);
|
|
} else if (tn === $.HEAD) {
|
|
p._err(ERR.misplacedStartTagForHeadElement);
|
|
} else {
|
|
tokenInHead(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagInHead(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.HEAD) {
|
|
p.openElements.pop();
|
|
p.insertionMode = AFTER_HEAD_MODE;
|
|
} else if (tn === $.BODY || tn === $.BR || tn === $.HTML) {
|
|
tokenInHead(p, token);
|
|
} else if (tn === $.TEMPLATE) {
|
|
if (p.openElements.tmplCount > 0) {
|
|
p.openElements.generateImpliedEndTagsThoroughly();
|
|
|
|
if (p.openElements.currentTagName !== $.TEMPLATE) {
|
|
p._err(ERR.closingOfElementWithOpenChildElements);
|
|
}
|
|
|
|
p.openElements.popUntilTagNamePopped($.TEMPLATE);
|
|
p.activeFormattingElements.clearToLastMarker();
|
|
p._popTmplInsertionMode();
|
|
p._resetInsertionMode();
|
|
} else {
|
|
p._err(ERR.endTagWithoutMatchingOpenElement);
|
|
}
|
|
} else {
|
|
p._err(ERR.endTagWithoutMatchingOpenElement);
|
|
}
|
|
}
|
|
|
|
function tokenInHead(p, token) {
|
|
p.openElements.pop();
|
|
p.insertionMode = AFTER_HEAD_MODE;
|
|
p._processToken(token);
|
|
}
|
|
|
|
// The "in head no script" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagInHeadNoScript(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.HTML) {
|
|
startTagInBody(p, token);
|
|
} else if (
|
|
tn === $.BASEFONT ||
|
|
tn === $.BGSOUND ||
|
|
tn === $.HEAD ||
|
|
tn === $.LINK ||
|
|
tn === $.META ||
|
|
tn === $.NOFRAMES ||
|
|
tn === $.STYLE
|
|
) {
|
|
startTagInHead(p, token);
|
|
} else if (tn === $.NOSCRIPT) {
|
|
p._err(ERR.nestedNoscriptInHead);
|
|
} else {
|
|
tokenInHeadNoScript(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagInHeadNoScript(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.NOSCRIPT) {
|
|
p.openElements.pop();
|
|
p.insertionMode = IN_HEAD_MODE;
|
|
} else if (tn === $.BR) {
|
|
tokenInHeadNoScript(p, token);
|
|
} else {
|
|
p._err(ERR.endTagWithoutMatchingOpenElement);
|
|
}
|
|
}
|
|
|
|
function tokenInHeadNoScript(p, token) {
|
|
const errCode =
|
|
token.type === Tokenizer.EOF_TOKEN ? ERR.openElementsLeftAfterEof : ERR.disallowedContentInNoscriptInHead;
|
|
|
|
p._err(errCode);
|
|
p.openElements.pop();
|
|
p.insertionMode = IN_HEAD_MODE;
|
|
p._processToken(token);
|
|
}
|
|
|
|
// The "after head" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagAfterHead(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.HTML) {
|
|
startTagInBody(p, token);
|
|
} else if (tn === $.BODY) {
|
|
p._insertElement(token, NS.HTML);
|
|
p.framesetOk = false;
|
|
p.insertionMode = IN_BODY_MODE;
|
|
} else if (tn === $.FRAMESET) {
|
|
p._insertElement(token, NS.HTML);
|
|
p.insertionMode = IN_FRAMESET_MODE;
|
|
} else if (
|
|
tn === $.BASE ||
|
|
tn === $.BASEFONT ||
|
|
tn === $.BGSOUND ||
|
|
tn === $.LINK ||
|
|
tn === $.META ||
|
|
tn === $.NOFRAMES ||
|
|
tn === $.SCRIPT ||
|
|
tn === $.STYLE ||
|
|
tn === $.TEMPLATE ||
|
|
tn === $.TITLE
|
|
) {
|
|
p._err(ERR.abandonedHeadElementChild);
|
|
p.openElements.push(p.headElement);
|
|
startTagInHead(p, token);
|
|
p.openElements.remove(p.headElement);
|
|
} else if (tn === $.HEAD) {
|
|
p._err(ERR.misplacedStartTagForHeadElement);
|
|
} else {
|
|
tokenAfterHead(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagAfterHead(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.BODY || tn === $.HTML || tn === $.BR) {
|
|
tokenAfterHead(p, token);
|
|
} else if (tn === $.TEMPLATE) {
|
|
endTagInHead(p, token);
|
|
} else {
|
|
p._err(ERR.endTagWithoutMatchingOpenElement);
|
|
}
|
|
}
|
|
|
|
function tokenAfterHead(p, token) {
|
|
p._insertFakeElement($.BODY);
|
|
p.insertionMode = IN_BODY_MODE;
|
|
p._processToken(token);
|
|
}
|
|
|
|
// The "in body" insertion mode
|
|
//------------------------------------------------------------------
|
|
function whitespaceCharacterInBody(p, token) {
|
|
p._reconstructActiveFormattingElements();
|
|
p._insertCharacters(token);
|
|
}
|
|
|
|
function characterInBody(p, token) {
|
|
p._reconstructActiveFormattingElements();
|
|
p._insertCharacters(token);
|
|
p.framesetOk = false;
|
|
}
|
|
|
|
function htmlStartTagInBody(p, token) {
|
|
if (p.openElements.tmplCount === 0) {
|
|
p.treeAdapter.adoptAttributes(p.openElements.items[0], token.attrs);
|
|
}
|
|
}
|
|
|
|
function bodyStartTagInBody(p, token) {
|
|
const bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
|
|
|
|
if (bodyElement && p.openElements.tmplCount === 0) {
|
|
p.framesetOk = false;
|
|
p.treeAdapter.adoptAttributes(bodyElement, token.attrs);
|
|
}
|
|
}
|
|
|
|
function framesetStartTagInBody(p, token) {
|
|
const bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
|
|
|
|
if (p.framesetOk && bodyElement) {
|
|
p.treeAdapter.detachNode(bodyElement);
|
|
p.openElements.popAllUpToHtmlElement();
|
|
p._insertElement(token, NS.HTML);
|
|
p.insertionMode = IN_FRAMESET_MODE;
|
|
}
|
|
}
|
|
|
|
function addressStartTagInBody(p, token) {
|
|
if (p.openElements.hasInButtonScope($.P)) {
|
|
p._closePElement();
|
|
}
|
|
|
|
p._insertElement(token, NS.HTML);
|
|
}
|
|
|
|
function numberedHeaderStartTagInBody(p, token) {
|
|
if (p.openElements.hasInButtonScope($.P)) {
|
|
p._closePElement();
|
|
}
|
|
|
|
const tn = p.openElements.currentTagName;
|
|
|
|
if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6) {
|
|
p.openElements.pop();
|
|
}
|
|
|
|
p._insertElement(token, NS.HTML);
|
|
}
|
|
|
|
function preStartTagInBody(p, token) {
|
|
if (p.openElements.hasInButtonScope($.P)) {
|
|
p._closePElement();
|
|
}
|
|
|
|
p._insertElement(token, NS.HTML);
|
|
//NOTE: If the next token is a U+000A LINE FEED (LF) character token, then ignore that token and move
|
|
//on to the next one. (Newlines at the start of pre blocks are ignored as an authoring convenience.)
|
|
p.skipNextNewLine = true;
|
|
p.framesetOk = false;
|
|
}
|
|
|
|
function formStartTagInBody(p, token) {
|
|
const inTemplate = p.openElements.tmplCount > 0;
|
|
|
|
if (!p.formElement || inTemplate) {
|
|
if (p.openElements.hasInButtonScope($.P)) {
|
|
p._closePElement();
|
|
}
|
|
|
|
p._insertElement(token, NS.HTML);
|
|
|
|
if (!inTemplate) {
|
|
p.formElement = p.openElements.current;
|
|
}
|
|
}
|
|
}
|
|
|
|
function listItemStartTagInBody(p, token) {
|
|
p.framesetOk = false;
|
|
|
|
const tn = token.tagName;
|
|
|
|
for (let i = p.openElements.stackTop; i >= 0; i--) {
|
|
const element = p.openElements.items[i];
|
|
const elementTn = p.treeAdapter.getTagName(element);
|
|
let closeTn = null;
|
|
|
|
if (tn === $.LI && elementTn === $.LI) {
|
|
closeTn = $.LI;
|
|
} else if ((tn === $.DD || tn === $.DT) && (elementTn === $.DD || elementTn === $.DT)) {
|
|
closeTn = elementTn;
|
|
}
|
|
|
|
if (closeTn) {
|
|
p.openElements.generateImpliedEndTagsWithExclusion(closeTn);
|
|
p.openElements.popUntilTagNamePopped(closeTn);
|
|
break;
|
|
}
|
|
|
|
if (elementTn !== $.ADDRESS && elementTn !== $.DIV && elementTn !== $.P && p._isSpecialElement(element)) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (p.openElements.hasInButtonScope($.P)) {
|
|
p._closePElement();
|
|
}
|
|
|
|
p._insertElement(token, NS.HTML);
|
|
}
|
|
|
|
function plaintextStartTagInBody(p, token) {
|
|
if (p.openElements.hasInButtonScope($.P)) {
|
|
p._closePElement();
|
|
}
|
|
|
|
p._insertElement(token, NS.HTML);
|
|
p.tokenizer.state = Tokenizer.MODE.PLAINTEXT;
|
|
}
|
|
|
|
function buttonStartTagInBody(p, token) {
|
|
if (p.openElements.hasInScope($.BUTTON)) {
|
|
p.openElements.generateImpliedEndTags();
|
|
p.openElements.popUntilTagNamePopped($.BUTTON);
|
|
}
|
|
|
|
p._reconstructActiveFormattingElements();
|
|
p._insertElement(token, NS.HTML);
|
|
p.framesetOk = false;
|
|
}
|
|
|
|
function aStartTagInBody(p, token) {
|
|
const activeElementEntry = p.activeFormattingElements.getElementEntryInScopeWithTagName($.A);
|
|
|
|
if (activeElementEntry) {
|
|
callAdoptionAgency(p, token);
|
|
p.openElements.remove(activeElementEntry.element);
|
|
p.activeFormattingElements.removeEntry(activeElementEntry);
|
|
}
|
|
|
|
p._reconstructActiveFormattingElements();
|
|
p._insertElement(token, NS.HTML);
|
|
p.activeFormattingElements.pushElement(p.openElements.current, token);
|
|
}
|
|
|
|
function bStartTagInBody(p, token) {
|
|
p._reconstructActiveFormattingElements();
|
|
p._insertElement(token, NS.HTML);
|
|
p.activeFormattingElements.pushElement(p.openElements.current, token);
|
|
}
|
|
|
|
function nobrStartTagInBody(p, token) {
|
|
p._reconstructActiveFormattingElements();
|
|
|
|
if (p.openElements.hasInScope($.NOBR)) {
|
|
callAdoptionAgency(p, token);
|
|
p._reconstructActiveFormattingElements();
|
|
}
|
|
|
|
p._insertElement(token, NS.HTML);
|
|
p.activeFormattingElements.pushElement(p.openElements.current, token);
|
|
}
|
|
|
|
function appletStartTagInBody(p, token) {
|
|
p._reconstructActiveFormattingElements();
|
|
p._insertElement(token, NS.HTML);
|
|
p.activeFormattingElements.insertMarker();
|
|
p.framesetOk = false;
|
|
}
|
|
|
|
function tableStartTagInBody(p, token) {
|
|
if (
|
|
p.treeAdapter.getDocumentMode(p.document) !== HTML.DOCUMENT_MODE.QUIRKS &&
|
|
p.openElements.hasInButtonScope($.P)
|
|
) {
|
|
p._closePElement();
|
|
}
|
|
|
|
p._insertElement(token, NS.HTML);
|
|
p.framesetOk = false;
|
|
p.insertionMode = IN_TABLE_MODE;
|
|
}
|
|
|
|
function areaStartTagInBody(p, token) {
|
|
p._reconstructActiveFormattingElements();
|
|
p._appendElement(token, NS.HTML);
|
|
p.framesetOk = false;
|
|
token.ackSelfClosing = true;
|
|
}
|
|
|
|
function inputStartTagInBody(p, token) {
|
|
p._reconstructActiveFormattingElements();
|
|
p._appendElement(token, NS.HTML);
|
|
|
|
const inputType = Tokenizer.getTokenAttr(token, ATTRS.TYPE);
|
|
|
|
if (!inputType || inputType.toLowerCase() !== HIDDEN_INPUT_TYPE) {
|
|
p.framesetOk = false;
|
|
}
|
|
|
|
token.ackSelfClosing = true;
|
|
}
|
|
|
|
function paramStartTagInBody(p, token) {
|
|
p._appendElement(token, NS.HTML);
|
|
token.ackSelfClosing = true;
|
|
}
|
|
|
|
function hrStartTagInBody(p, token) {
|
|
if (p.openElements.hasInButtonScope($.P)) {
|
|
p._closePElement();
|
|
}
|
|
|
|
p._appendElement(token, NS.HTML);
|
|
p.framesetOk = false;
|
|
token.ackSelfClosing = true;
|
|
}
|
|
|
|
function imageStartTagInBody(p, token) {
|
|
token.tagName = $.IMG;
|
|
areaStartTagInBody(p, token);
|
|
}
|
|
|
|
function textareaStartTagInBody(p, token) {
|
|
p._insertElement(token, NS.HTML);
|
|
//NOTE: If the next token is a U+000A LINE FEED (LF) character token, then ignore that token and move
|
|
//on to the next one. (Newlines at the start of textarea elements are ignored as an authoring convenience.)
|
|
p.skipNextNewLine = true;
|
|
p.tokenizer.state = Tokenizer.MODE.RCDATA;
|
|
p.originalInsertionMode = p.insertionMode;
|
|
p.framesetOk = false;
|
|
p.insertionMode = TEXT_MODE;
|
|
}
|
|
|
|
function xmpStartTagInBody(p, token) {
|
|
if (p.openElements.hasInButtonScope($.P)) {
|
|
p._closePElement();
|
|
}
|
|
|
|
p._reconstructActiveFormattingElements();
|
|
p.framesetOk = false;
|
|
p._switchToTextParsing(token, Tokenizer.MODE.RAWTEXT);
|
|
}
|
|
|
|
function iframeStartTagInBody(p, token) {
|
|
p.framesetOk = false;
|
|
p._switchToTextParsing(token, Tokenizer.MODE.RAWTEXT);
|
|
}
|
|
|
|
//NOTE: here we assume that we always act as an user agent with enabled plugins, so we parse
|
|
//<noembed> as a rawtext.
|
|
function noembedStartTagInBody(p, token) {
|
|
p._switchToTextParsing(token, Tokenizer.MODE.RAWTEXT);
|
|
}
|
|
|
|
function selectStartTagInBody(p, token) {
|
|
p._reconstructActiveFormattingElements();
|
|
p._insertElement(token, NS.HTML);
|
|
p.framesetOk = false;
|
|
|
|
if (
|
|
p.insertionMode === IN_TABLE_MODE ||
|
|
p.insertionMode === IN_CAPTION_MODE ||
|
|
p.insertionMode === IN_TABLE_BODY_MODE ||
|
|
p.insertionMode === IN_ROW_MODE ||
|
|
p.insertionMode === IN_CELL_MODE
|
|
) {
|
|
p.insertionMode = IN_SELECT_IN_TABLE_MODE;
|
|
} else {
|
|
p.insertionMode = IN_SELECT_MODE;
|
|
}
|
|
}
|
|
|
|
function optgroupStartTagInBody(p, token) {
|
|
if (p.openElements.currentTagName === $.OPTION) {
|
|
p.openElements.pop();
|
|
}
|
|
|
|
p._reconstructActiveFormattingElements();
|
|
p._insertElement(token, NS.HTML);
|
|
}
|
|
|
|
function rbStartTagInBody(p, token) {
|
|
if (p.openElements.hasInScope($.RUBY)) {
|
|
p.openElements.generateImpliedEndTags();
|
|
}
|
|
|
|
p._insertElement(token, NS.HTML);
|
|
}
|
|
|
|
function rtStartTagInBody(p, token) {
|
|
if (p.openElements.hasInScope($.RUBY)) {
|
|
p.openElements.generateImpliedEndTagsWithExclusion($.RTC);
|
|
}
|
|
|
|
p._insertElement(token, NS.HTML);
|
|
}
|
|
|
|
function menuStartTagInBody(p, token) {
|
|
if (p.openElements.hasInButtonScope($.P)) {
|
|
p._closePElement();
|
|
}
|
|
|
|
p._insertElement(token, NS.HTML);
|
|
}
|
|
|
|
function mathStartTagInBody(p, token) {
|
|
p._reconstructActiveFormattingElements();
|
|
|
|
foreignContent.adjustTokenMathMLAttrs(token);
|
|
foreignContent.adjustTokenXMLAttrs(token);
|
|
|
|
if (token.selfClosing) {
|
|
p._appendElement(token, NS.MATHML);
|
|
} else {
|
|
p._insertElement(token, NS.MATHML);
|
|
}
|
|
|
|
token.ackSelfClosing = true;
|
|
}
|
|
|
|
function svgStartTagInBody(p, token) {
|
|
p._reconstructActiveFormattingElements();
|
|
|
|
foreignContent.adjustTokenSVGAttrs(token);
|
|
foreignContent.adjustTokenXMLAttrs(token);
|
|
|
|
if (token.selfClosing) {
|
|
p._appendElement(token, NS.SVG);
|
|
} else {
|
|
p._insertElement(token, NS.SVG);
|
|
}
|
|
|
|
token.ackSelfClosing = true;
|
|
}
|
|
|
|
function genericStartTagInBody(p, token) {
|
|
p._reconstructActiveFormattingElements();
|
|
p._insertElement(token, NS.HTML);
|
|
}
|
|
|
|
//OPTIMIZATION: Integer comparisons are low-cost, so we can use very fast tag name length filters here.
|
|
//It's faster than using dictionary.
|
|
function startTagInBody(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
switch (tn.length) {
|
|
case 1:
|
|
if (tn === $.I || tn === $.S || tn === $.B || tn === $.U) {
|
|
bStartTagInBody(p, token);
|
|
} else if (tn === $.P) {
|
|
addressStartTagInBody(p, token);
|
|
} else if (tn === $.A) {
|
|
aStartTagInBody(p, token);
|
|
} else {
|
|
genericStartTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
if (tn === $.DL || tn === $.OL || tn === $.UL) {
|
|
addressStartTagInBody(p, token);
|
|
} else if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6) {
|
|
numberedHeaderStartTagInBody(p, token);
|
|
} else if (tn === $.LI || tn === $.DD || tn === $.DT) {
|
|
listItemStartTagInBody(p, token);
|
|
} else if (tn === $.EM || tn === $.TT) {
|
|
bStartTagInBody(p, token);
|
|
} else if (tn === $.BR) {
|
|
areaStartTagInBody(p, token);
|
|
} else if (tn === $.HR) {
|
|
hrStartTagInBody(p, token);
|
|
} else if (tn === $.RB) {
|
|
rbStartTagInBody(p, token);
|
|
} else if (tn === $.RT || tn === $.RP) {
|
|
rtStartTagInBody(p, token);
|
|
} else if (tn !== $.TH && tn !== $.TD && tn !== $.TR) {
|
|
genericStartTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
|
if (tn === $.DIV || tn === $.DIR || tn === $.NAV) {
|
|
addressStartTagInBody(p, token);
|
|
} else if (tn === $.PRE) {
|
|
preStartTagInBody(p, token);
|
|
} else if (tn === $.BIG) {
|
|
bStartTagInBody(p, token);
|
|
} else if (tn === $.IMG || tn === $.WBR) {
|
|
areaStartTagInBody(p, token);
|
|
} else if (tn === $.XMP) {
|
|
xmpStartTagInBody(p, token);
|
|
} else if (tn === $.SVG) {
|
|
svgStartTagInBody(p, token);
|
|
} else if (tn === $.RTC) {
|
|
rbStartTagInBody(p, token);
|
|
} else if (tn !== $.COL) {
|
|
genericStartTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
if (tn === $.HTML) {
|
|
htmlStartTagInBody(p, token);
|
|
} else if (tn === $.BASE || tn === $.LINK || tn === $.META) {
|
|
startTagInHead(p, token);
|
|
} else if (tn === $.BODY) {
|
|
bodyStartTagInBody(p, token);
|
|
} else if (tn === $.MAIN || tn === $.MENU) {
|
|
addressStartTagInBody(p, token);
|
|
} else if (tn === $.FORM) {
|
|
formStartTagInBody(p, token);
|
|
} else if (tn === $.CODE || tn === $.FONT) {
|
|
bStartTagInBody(p, token);
|
|
} else if (tn === $.NOBR) {
|
|
nobrStartTagInBody(p, token);
|
|
} else if (tn === $.AREA) {
|
|
areaStartTagInBody(p, token);
|
|
} else if (tn === $.MATH) {
|
|
mathStartTagInBody(p, token);
|
|
} else if (tn === $.MENU) {
|
|
menuStartTagInBody(p, token);
|
|
} else if (tn !== $.HEAD) {
|
|
genericStartTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 5:
|
|
if (tn === $.STYLE || tn === $.TITLE) {
|
|
startTagInHead(p, token);
|
|
} else if (tn === $.ASIDE) {
|
|
addressStartTagInBody(p, token);
|
|
} else if (tn === $.SMALL) {
|
|
bStartTagInBody(p, token);
|
|
} else if (tn === $.TABLE) {
|
|
tableStartTagInBody(p, token);
|
|
} else if (tn === $.EMBED) {
|
|
areaStartTagInBody(p, token);
|
|
} else if (tn === $.INPUT) {
|
|
inputStartTagInBody(p, token);
|
|
} else if (tn === $.PARAM || tn === $.TRACK) {
|
|
paramStartTagInBody(p, token);
|
|
} else if (tn === $.IMAGE) {
|
|
imageStartTagInBody(p, token);
|
|
} else if (tn !== $.FRAME && tn !== $.TBODY && tn !== $.TFOOT && tn !== $.THEAD) {
|
|
genericStartTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 6:
|
|
if (tn === $.SCRIPT) {
|
|
startTagInHead(p, token);
|
|
} else if (
|
|
tn === $.CENTER ||
|
|
tn === $.FIGURE ||
|
|
tn === $.FOOTER ||
|
|
tn === $.HEADER ||
|
|
tn === $.HGROUP ||
|
|
tn === $.DIALOG
|
|
) {
|
|
addressStartTagInBody(p, token);
|
|
} else if (tn === $.BUTTON) {
|
|
buttonStartTagInBody(p, token);
|
|
} else if (tn === $.STRIKE || tn === $.STRONG) {
|
|
bStartTagInBody(p, token);
|
|
} else if (tn === $.APPLET || tn === $.OBJECT) {
|
|
appletStartTagInBody(p, token);
|
|
} else if (tn === $.KEYGEN) {
|
|
areaStartTagInBody(p, token);
|
|
} else if (tn === $.SOURCE) {
|
|
paramStartTagInBody(p, token);
|
|
} else if (tn === $.IFRAME) {
|
|
iframeStartTagInBody(p, token);
|
|
} else if (tn === $.SELECT) {
|
|
selectStartTagInBody(p, token);
|
|
} else if (tn === $.OPTION) {
|
|
optgroupStartTagInBody(p, token);
|
|
} else {
|
|
genericStartTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 7:
|
|
if (tn === $.BGSOUND) {
|
|
startTagInHead(p, token);
|
|
} else if (
|
|
tn === $.DETAILS ||
|
|
tn === $.ADDRESS ||
|
|
tn === $.ARTICLE ||
|
|
tn === $.SECTION ||
|
|
tn === $.SUMMARY
|
|
) {
|
|
addressStartTagInBody(p, token);
|
|
} else if (tn === $.LISTING) {
|
|
preStartTagInBody(p, token);
|
|
} else if (tn === $.MARQUEE) {
|
|
appletStartTagInBody(p, token);
|
|
} else if (tn === $.NOEMBED) {
|
|
noembedStartTagInBody(p, token);
|
|
} else if (tn !== $.CAPTION) {
|
|
genericStartTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
|
if (tn === $.BASEFONT) {
|
|
startTagInHead(p, token);
|
|
} else if (tn === $.FRAMESET) {
|
|
framesetStartTagInBody(p, token);
|
|
} else if (tn === $.FIELDSET) {
|
|
addressStartTagInBody(p, token);
|
|
} else if (tn === $.TEXTAREA) {
|
|
textareaStartTagInBody(p, token);
|
|
} else if (tn === $.TEMPLATE) {
|
|
startTagInHead(p, token);
|
|
} else if (tn === $.NOSCRIPT) {
|
|
if (p.options.scriptingEnabled) {
|
|
noembedStartTagInBody(p, token);
|
|
} else {
|
|
genericStartTagInBody(p, token);
|
|
}
|
|
} else if (tn === $.OPTGROUP) {
|
|
optgroupStartTagInBody(p, token);
|
|
} else if (tn !== $.COLGROUP) {
|
|
genericStartTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 9:
|
|
if (tn === $.PLAINTEXT) {
|
|
plaintextStartTagInBody(p, token);
|
|
} else {
|
|
genericStartTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 10:
|
|
if (tn === $.BLOCKQUOTE || tn === $.FIGCAPTION) {
|
|
addressStartTagInBody(p, token);
|
|
} else {
|
|
genericStartTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
genericStartTagInBody(p, token);
|
|
}
|
|
}
|
|
|
|
function bodyEndTagInBody(p) {
|
|
if (p.openElements.hasInScope($.BODY)) {
|
|
p.insertionMode = AFTER_BODY_MODE;
|
|
}
|
|
}
|
|
|
|
function htmlEndTagInBody(p, token) {
|
|
if (p.openElements.hasInScope($.BODY)) {
|
|
p.insertionMode = AFTER_BODY_MODE;
|
|
p._processToken(token);
|
|
}
|
|
}
|
|
|
|
function addressEndTagInBody(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (p.openElements.hasInScope(tn)) {
|
|
p.openElements.generateImpliedEndTags();
|
|
p.openElements.popUntilTagNamePopped(tn);
|
|
}
|
|
}
|
|
|
|
function formEndTagInBody(p) {
|
|
const inTemplate = p.openElements.tmplCount > 0;
|
|
const formElement = p.formElement;
|
|
|
|
if (!inTemplate) {
|
|
p.formElement = null;
|
|
}
|
|
|
|
if ((formElement || inTemplate) && p.openElements.hasInScope($.FORM)) {
|
|
p.openElements.generateImpliedEndTags();
|
|
|
|
if (inTemplate) {
|
|
p.openElements.popUntilTagNamePopped($.FORM);
|
|
} else {
|
|
p.openElements.remove(formElement);
|
|
}
|
|
}
|
|
}
|
|
|
|
function pEndTagInBody(p) {
|
|
if (!p.openElements.hasInButtonScope($.P)) {
|
|
p._insertFakeElement($.P);
|
|
}
|
|
|
|
p._closePElement();
|
|
}
|
|
|
|
function liEndTagInBody(p) {
|
|
if (p.openElements.hasInListItemScope($.LI)) {
|
|
p.openElements.generateImpliedEndTagsWithExclusion($.LI);
|
|
p.openElements.popUntilTagNamePopped($.LI);
|
|
}
|
|
}
|
|
|
|
function ddEndTagInBody(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (p.openElements.hasInScope(tn)) {
|
|
p.openElements.generateImpliedEndTagsWithExclusion(tn);
|
|
p.openElements.popUntilTagNamePopped(tn);
|
|
}
|
|
}
|
|
|
|
function numberedHeaderEndTagInBody(p) {
|
|
if (p.openElements.hasNumberedHeaderInScope()) {
|
|
p.openElements.generateImpliedEndTags();
|
|
p.openElements.popUntilNumberedHeaderPopped();
|
|
}
|
|
}
|
|
|
|
function appletEndTagInBody(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (p.openElements.hasInScope(tn)) {
|
|
p.openElements.generateImpliedEndTags();
|
|
p.openElements.popUntilTagNamePopped(tn);
|
|
p.activeFormattingElements.clearToLastMarker();
|
|
}
|
|
}
|
|
|
|
function brEndTagInBody(p) {
|
|
p._reconstructActiveFormattingElements();
|
|
p._insertFakeElement($.BR);
|
|
p.openElements.pop();
|
|
p.framesetOk = false;
|
|
}
|
|
|
|
function genericEndTagInBody(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
for (let i = p.openElements.stackTop; i > 0; i--) {
|
|
const element = p.openElements.items[i];
|
|
|
|
if (p.treeAdapter.getTagName(element) === tn) {
|
|
p.openElements.generateImpliedEndTagsWithExclusion(tn);
|
|
p.openElements.popUntilElementPopped(element);
|
|
break;
|
|
}
|
|
|
|
if (p._isSpecialElement(element)) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//OPTIMIZATION: Integer comparisons are low-cost, so we can use very fast tag name length filters here.
|
|
//It's faster than using dictionary.
|
|
function endTagInBody(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
switch (tn.length) {
|
|
case 1:
|
|
if (tn === $.A || tn === $.B || tn === $.I || tn === $.S || tn === $.U) {
|
|
callAdoptionAgency(p, token);
|
|
} else if (tn === $.P) {
|
|
pEndTagInBody(p, token);
|
|
} else {
|
|
genericEndTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
if (tn === $.DL || tn === $.UL || tn === $.OL) {
|
|
addressEndTagInBody(p, token);
|
|
} else if (tn === $.LI) {
|
|
liEndTagInBody(p, token);
|
|
} else if (tn === $.DD || tn === $.DT) {
|
|
ddEndTagInBody(p, token);
|
|
} else if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6) {
|
|
numberedHeaderEndTagInBody(p, token);
|
|
} else if (tn === $.BR) {
|
|
brEndTagInBody(p, token);
|
|
} else if (tn === $.EM || tn === $.TT) {
|
|
callAdoptionAgency(p, token);
|
|
} else {
|
|
genericEndTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
|
if (tn === $.BIG) {
|
|
callAdoptionAgency(p, token);
|
|
} else if (tn === $.DIR || tn === $.DIV || tn === $.NAV || tn === $.PRE) {
|
|
addressEndTagInBody(p, token);
|
|
} else {
|
|
genericEndTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
if (tn === $.BODY) {
|
|
bodyEndTagInBody(p, token);
|
|
} else if (tn === $.HTML) {
|
|
htmlEndTagInBody(p, token);
|
|
} else if (tn === $.FORM) {
|
|
formEndTagInBody(p, token);
|
|
} else if (tn === $.CODE || tn === $.FONT || tn === $.NOBR) {
|
|
callAdoptionAgency(p, token);
|
|
} else if (tn === $.MAIN || tn === $.MENU) {
|
|
addressEndTagInBody(p, token);
|
|
} else {
|
|
genericEndTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 5:
|
|
if (tn === $.ASIDE) {
|
|
addressEndTagInBody(p, token);
|
|
} else if (tn === $.SMALL) {
|
|
callAdoptionAgency(p, token);
|
|
} else {
|
|
genericEndTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 6:
|
|
if (
|
|
tn === $.CENTER ||
|
|
tn === $.FIGURE ||
|
|
tn === $.FOOTER ||
|
|
tn === $.HEADER ||
|
|
tn === $.HGROUP ||
|
|
tn === $.DIALOG
|
|
) {
|
|
addressEndTagInBody(p, token);
|
|
} else if (tn === $.APPLET || tn === $.OBJECT) {
|
|
appletEndTagInBody(p, token);
|
|
} else if (tn === $.STRIKE || tn === $.STRONG) {
|
|
callAdoptionAgency(p, token);
|
|
} else {
|
|
genericEndTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 7:
|
|
if (
|
|
tn === $.ADDRESS ||
|
|
tn === $.ARTICLE ||
|
|
tn === $.DETAILS ||
|
|
tn === $.SECTION ||
|
|
tn === $.SUMMARY ||
|
|
tn === $.LISTING
|
|
) {
|
|
addressEndTagInBody(p, token);
|
|
} else if (tn === $.MARQUEE) {
|
|
appletEndTagInBody(p, token);
|
|
} else {
|
|
genericEndTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
|
if (tn === $.FIELDSET) {
|
|
addressEndTagInBody(p, token);
|
|
} else if (tn === $.TEMPLATE) {
|
|
endTagInHead(p, token);
|
|
} else {
|
|
genericEndTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 10:
|
|
if (tn === $.BLOCKQUOTE || tn === $.FIGCAPTION) {
|
|
addressEndTagInBody(p, token);
|
|
} else {
|
|
genericEndTagInBody(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
genericEndTagInBody(p, token);
|
|
}
|
|
}
|
|
|
|
function eofInBody(p, token) {
|
|
if (p.tmplInsertionModeStackTop > -1) {
|
|
eofInTemplate(p, token);
|
|
} else {
|
|
p.stopped = true;
|
|
}
|
|
}
|
|
|
|
// The "text" insertion mode
|
|
//------------------------------------------------------------------
|
|
function endTagInText(p, token) {
|
|
if (token.tagName === $.SCRIPT) {
|
|
p.pendingScript = p.openElements.current;
|
|
}
|
|
|
|
p.openElements.pop();
|
|
p.insertionMode = p.originalInsertionMode;
|
|
}
|
|
|
|
function eofInText(p, token) {
|
|
p._err(ERR.eofInElementThatCanContainOnlyText);
|
|
p.openElements.pop();
|
|
p.insertionMode = p.originalInsertionMode;
|
|
p._processToken(token);
|
|
}
|
|
|
|
// The "in table" insertion mode
|
|
//------------------------------------------------------------------
|
|
function characterInTable(p, token) {
|
|
const curTn = p.openElements.currentTagName;
|
|
|
|
if (curTn === $.TABLE || curTn === $.TBODY || curTn === $.TFOOT || curTn === $.THEAD || curTn === $.TR) {
|
|
p.pendingCharacterTokens = [];
|
|
p.hasNonWhitespacePendingCharacterToken = false;
|
|
p.originalInsertionMode = p.insertionMode;
|
|
p.insertionMode = IN_TABLE_TEXT_MODE;
|
|
p._processToken(token);
|
|
} else {
|
|
tokenInTable(p, token);
|
|
}
|
|
}
|
|
|
|
function captionStartTagInTable(p, token) {
|
|
p.openElements.clearBackToTableContext();
|
|
p.activeFormattingElements.insertMarker();
|
|
p._insertElement(token, NS.HTML);
|
|
p.insertionMode = IN_CAPTION_MODE;
|
|
}
|
|
|
|
function colgroupStartTagInTable(p, token) {
|
|
p.openElements.clearBackToTableContext();
|
|
p._insertElement(token, NS.HTML);
|
|
p.insertionMode = IN_COLUMN_GROUP_MODE;
|
|
}
|
|
|
|
function colStartTagInTable(p, token) {
|
|
p.openElements.clearBackToTableContext();
|
|
p._insertFakeElement($.COLGROUP);
|
|
p.insertionMode = IN_COLUMN_GROUP_MODE;
|
|
p._processToken(token);
|
|
}
|
|
|
|
function tbodyStartTagInTable(p, token) {
|
|
p.openElements.clearBackToTableContext();
|
|
p._insertElement(token, NS.HTML);
|
|
p.insertionMode = IN_TABLE_BODY_MODE;
|
|
}
|
|
|
|
function tdStartTagInTable(p, token) {
|
|
p.openElements.clearBackToTableContext();
|
|
p._insertFakeElement($.TBODY);
|
|
p.insertionMode = IN_TABLE_BODY_MODE;
|
|
p._processToken(token);
|
|
}
|
|
|
|
function tableStartTagInTable(p, token) {
|
|
if (p.openElements.hasInTableScope($.TABLE)) {
|
|
p.openElements.popUntilTagNamePopped($.TABLE);
|
|
p._resetInsertionMode();
|
|
p._processToken(token);
|
|
}
|
|
}
|
|
|
|
function inputStartTagInTable(p, token) {
|
|
const inputType = Tokenizer.getTokenAttr(token, ATTRS.TYPE);
|
|
|
|
if (inputType && inputType.toLowerCase() === HIDDEN_INPUT_TYPE) {
|
|
p._appendElement(token, NS.HTML);
|
|
} else {
|
|
tokenInTable(p, token);
|
|
}
|
|
|
|
token.ackSelfClosing = true;
|
|
}
|
|
|
|
function formStartTagInTable(p, token) {
|
|
if (!p.formElement && p.openElements.tmplCount === 0) {
|
|
p._insertElement(token, NS.HTML);
|
|
p.formElement = p.openElements.current;
|
|
p.openElements.pop();
|
|
}
|
|
}
|
|
|
|
function startTagInTable(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
switch (tn.length) {
|
|
case 2:
|
|
if (tn === $.TD || tn === $.TH || tn === $.TR) {
|
|
tdStartTagInTable(p, token);
|
|
} else {
|
|
tokenInTable(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
|
if (tn === $.COL) {
|
|
colStartTagInTable(p, token);
|
|
} else {
|
|
tokenInTable(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
if (tn === $.FORM) {
|
|
formStartTagInTable(p, token);
|
|
} else {
|
|
tokenInTable(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 5:
|
|
if (tn === $.TABLE) {
|
|
tableStartTagInTable(p, token);
|
|
} else if (tn === $.STYLE) {
|
|
startTagInHead(p, token);
|
|
} else if (tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD) {
|
|
tbodyStartTagInTable(p, token);
|
|
} else if (tn === $.INPUT) {
|
|
inputStartTagInTable(p, token);
|
|
} else {
|
|
tokenInTable(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 6:
|
|
if (tn === $.SCRIPT) {
|
|
startTagInHead(p, token);
|
|
} else {
|
|
tokenInTable(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 7:
|
|
if (tn === $.CAPTION) {
|
|
captionStartTagInTable(p, token);
|
|
} else {
|
|
tokenInTable(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
|
if (tn === $.COLGROUP) {
|
|
colgroupStartTagInTable(p, token);
|
|
} else if (tn === $.TEMPLATE) {
|
|
startTagInHead(p, token);
|
|
} else {
|
|
tokenInTable(p, token);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
tokenInTable(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagInTable(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.TABLE) {
|
|
if (p.openElements.hasInTableScope($.TABLE)) {
|
|
p.openElements.popUntilTagNamePopped($.TABLE);
|
|
p._resetInsertionMode();
|
|
}
|
|
} else if (tn === $.TEMPLATE) {
|
|
endTagInHead(p, token);
|
|
} else if (
|
|
tn !== $.BODY &&
|
|
tn !== $.CAPTION &&
|
|
tn !== $.COL &&
|
|
tn !== $.COLGROUP &&
|
|
tn !== $.HTML &&
|
|
tn !== $.TBODY &&
|
|
tn !== $.TD &&
|
|
tn !== $.TFOOT &&
|
|
tn !== $.TH &&
|
|
tn !== $.THEAD &&
|
|
tn !== $.TR
|
|
) {
|
|
tokenInTable(p, token);
|
|
}
|
|
}
|
|
|
|
function tokenInTable(p, token) {
|
|
const savedFosterParentingState = p.fosterParentingEnabled;
|
|
|
|
p.fosterParentingEnabled = true;
|
|
p._processTokenInBodyMode(token);
|
|
p.fosterParentingEnabled = savedFosterParentingState;
|
|
}
|
|
|
|
// The "in table text" insertion mode
|
|
//------------------------------------------------------------------
|
|
function whitespaceCharacterInTableText(p, token) {
|
|
p.pendingCharacterTokens.push(token);
|
|
}
|
|
|
|
function characterInTableText(p, token) {
|
|
p.pendingCharacterTokens.push(token);
|
|
p.hasNonWhitespacePendingCharacterToken = true;
|
|
}
|
|
|
|
function tokenInTableText(p, token) {
|
|
let i = 0;
|
|
|
|
if (p.hasNonWhitespacePendingCharacterToken) {
|
|
for (; i < p.pendingCharacterTokens.length; i++) {
|
|
tokenInTable(p, p.pendingCharacterTokens[i]);
|
|
}
|
|
} else {
|
|
for (; i < p.pendingCharacterTokens.length; i++) {
|
|
p._insertCharacters(p.pendingCharacterTokens[i]);
|
|
}
|
|
}
|
|
|
|
p.insertionMode = p.originalInsertionMode;
|
|
p._processToken(token);
|
|
}
|
|
|
|
// The "in caption" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagInCaption(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (
|
|
tn === $.CAPTION ||
|
|
tn === $.COL ||
|
|
tn === $.COLGROUP ||
|
|
tn === $.TBODY ||
|
|
tn === $.TD ||
|
|
tn === $.TFOOT ||
|
|
tn === $.TH ||
|
|
tn === $.THEAD ||
|
|
tn === $.TR
|
|
) {
|
|
if (p.openElements.hasInTableScope($.CAPTION)) {
|
|
p.openElements.generateImpliedEndTags();
|
|
p.openElements.popUntilTagNamePopped($.CAPTION);
|
|
p.activeFormattingElements.clearToLastMarker();
|
|
p.insertionMode = IN_TABLE_MODE;
|
|
p._processToken(token);
|
|
}
|
|
} else {
|
|
startTagInBody(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagInCaption(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.CAPTION || tn === $.TABLE) {
|
|
if (p.openElements.hasInTableScope($.CAPTION)) {
|
|
p.openElements.generateImpliedEndTags();
|
|
p.openElements.popUntilTagNamePopped($.CAPTION);
|
|
p.activeFormattingElements.clearToLastMarker();
|
|
p.insertionMode = IN_TABLE_MODE;
|
|
|
|
if (tn === $.TABLE) {
|
|
p._processToken(token);
|
|
}
|
|
}
|
|
} else if (
|
|
tn !== $.BODY &&
|
|
tn !== $.COL &&
|
|
tn !== $.COLGROUP &&
|
|
tn !== $.HTML &&
|
|
tn !== $.TBODY &&
|
|
tn !== $.TD &&
|
|
tn !== $.TFOOT &&
|
|
tn !== $.TH &&
|
|
tn !== $.THEAD &&
|
|
tn !== $.TR
|
|
) {
|
|
endTagInBody(p, token);
|
|
}
|
|
}
|
|
|
|
// The "in column group" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagInColumnGroup(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.HTML) {
|
|
startTagInBody(p, token);
|
|
} else if (tn === $.COL) {
|
|
p._appendElement(token, NS.HTML);
|
|
token.ackSelfClosing = true;
|
|
} else if (tn === $.TEMPLATE) {
|
|
startTagInHead(p, token);
|
|
} else {
|
|
tokenInColumnGroup(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagInColumnGroup(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.COLGROUP) {
|
|
if (p.openElements.currentTagName === $.COLGROUP) {
|
|
p.openElements.pop();
|
|
p.insertionMode = IN_TABLE_MODE;
|
|
}
|
|
} else if (tn === $.TEMPLATE) {
|
|
endTagInHead(p, token);
|
|
} else if (tn !== $.COL) {
|
|
tokenInColumnGroup(p, token);
|
|
}
|
|
}
|
|
|
|
function tokenInColumnGroup(p, token) {
|
|
if (p.openElements.currentTagName === $.COLGROUP) {
|
|
p.openElements.pop();
|
|
p.insertionMode = IN_TABLE_MODE;
|
|
p._processToken(token);
|
|
}
|
|
}
|
|
|
|
// The "in table body" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagInTableBody(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.TR) {
|
|
p.openElements.clearBackToTableBodyContext();
|
|
p._insertElement(token, NS.HTML);
|
|
p.insertionMode = IN_ROW_MODE;
|
|
} else if (tn === $.TH || tn === $.TD) {
|
|
p.openElements.clearBackToTableBodyContext();
|
|
p._insertFakeElement($.TR);
|
|
p.insertionMode = IN_ROW_MODE;
|
|
p._processToken(token);
|
|
} else if (
|
|
tn === $.CAPTION ||
|
|
tn === $.COL ||
|
|
tn === $.COLGROUP ||
|
|
tn === $.TBODY ||
|
|
tn === $.TFOOT ||
|
|
tn === $.THEAD
|
|
) {
|
|
if (p.openElements.hasTableBodyContextInTableScope()) {
|
|
p.openElements.clearBackToTableBodyContext();
|
|
p.openElements.pop();
|
|
p.insertionMode = IN_TABLE_MODE;
|
|
p._processToken(token);
|
|
}
|
|
} else {
|
|
startTagInTable(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagInTableBody(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD) {
|
|
if (p.openElements.hasInTableScope(tn)) {
|
|
p.openElements.clearBackToTableBodyContext();
|
|
p.openElements.pop();
|
|
p.insertionMode = IN_TABLE_MODE;
|
|
}
|
|
} else if (tn === $.TABLE) {
|
|
if (p.openElements.hasTableBodyContextInTableScope()) {
|
|
p.openElements.clearBackToTableBodyContext();
|
|
p.openElements.pop();
|
|
p.insertionMode = IN_TABLE_MODE;
|
|
p._processToken(token);
|
|
}
|
|
} else if (
|
|
(tn !== $.BODY && tn !== $.CAPTION && tn !== $.COL && tn !== $.COLGROUP) ||
|
|
(tn !== $.HTML && tn !== $.TD && tn !== $.TH && tn !== $.TR)
|
|
) {
|
|
endTagInTable(p, token);
|
|
}
|
|
}
|
|
|
|
// The "in row" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagInRow(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.TH || tn === $.TD) {
|
|
p.openElements.clearBackToTableRowContext();
|
|
p._insertElement(token, NS.HTML);
|
|
p.insertionMode = IN_CELL_MODE;
|
|
p.activeFormattingElements.insertMarker();
|
|
} else if (
|
|
tn === $.CAPTION ||
|
|
tn === $.COL ||
|
|
tn === $.COLGROUP ||
|
|
tn === $.TBODY ||
|
|
tn === $.TFOOT ||
|
|
tn === $.THEAD ||
|
|
tn === $.TR
|
|
) {
|
|
if (p.openElements.hasInTableScope($.TR)) {
|
|
p.openElements.clearBackToTableRowContext();
|
|
p.openElements.pop();
|
|
p.insertionMode = IN_TABLE_BODY_MODE;
|
|
p._processToken(token);
|
|
}
|
|
} else {
|
|
startTagInTable(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagInRow(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.TR) {
|
|
if (p.openElements.hasInTableScope($.TR)) {
|
|
p.openElements.clearBackToTableRowContext();
|
|
p.openElements.pop();
|
|
p.insertionMode = IN_TABLE_BODY_MODE;
|
|
}
|
|
} else if (tn === $.TABLE) {
|
|
if (p.openElements.hasInTableScope($.TR)) {
|
|
p.openElements.clearBackToTableRowContext();
|
|
p.openElements.pop();
|
|
p.insertionMode = IN_TABLE_BODY_MODE;
|
|
p._processToken(token);
|
|
}
|
|
} else if (tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD) {
|
|
if (p.openElements.hasInTableScope(tn) || p.openElements.hasInTableScope($.TR)) {
|
|
p.openElements.clearBackToTableRowContext();
|
|
p.openElements.pop();
|
|
p.insertionMode = IN_TABLE_BODY_MODE;
|
|
p._processToken(token);
|
|
}
|
|
} else if (
|
|
(tn !== $.BODY && tn !== $.CAPTION && tn !== $.COL && tn !== $.COLGROUP) ||
|
|
(tn !== $.HTML && tn !== $.TD && tn !== $.TH)
|
|
) {
|
|
endTagInTable(p, token);
|
|
}
|
|
}
|
|
|
|
// The "in cell" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagInCell(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (
|
|
tn === $.CAPTION ||
|
|
tn === $.COL ||
|
|
tn === $.COLGROUP ||
|
|
tn === $.TBODY ||
|
|
tn === $.TD ||
|
|
tn === $.TFOOT ||
|
|
tn === $.TH ||
|
|
tn === $.THEAD ||
|
|
tn === $.TR
|
|
) {
|
|
if (p.openElements.hasInTableScope($.TD) || p.openElements.hasInTableScope($.TH)) {
|
|
p._closeTableCell();
|
|
p._processToken(token);
|
|
}
|
|
} else {
|
|
startTagInBody(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagInCell(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.TD || tn === $.TH) {
|
|
if (p.openElements.hasInTableScope(tn)) {
|
|
p.openElements.generateImpliedEndTags();
|
|
p.openElements.popUntilTagNamePopped(tn);
|
|
p.activeFormattingElements.clearToLastMarker();
|
|
p.insertionMode = IN_ROW_MODE;
|
|
}
|
|
} else if (tn === $.TABLE || tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD || tn === $.TR) {
|
|
if (p.openElements.hasInTableScope(tn)) {
|
|
p._closeTableCell();
|
|
p._processToken(token);
|
|
}
|
|
} else if (tn !== $.BODY && tn !== $.CAPTION && tn !== $.COL && tn !== $.COLGROUP && tn !== $.HTML) {
|
|
endTagInBody(p, token);
|
|
}
|
|
}
|
|
|
|
// The "in select" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagInSelect(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.HTML) {
|
|
startTagInBody(p, token);
|
|
} else if (tn === $.OPTION) {
|
|
if (p.openElements.currentTagName === $.OPTION) {
|
|
p.openElements.pop();
|
|
}
|
|
|
|
p._insertElement(token, NS.HTML);
|
|
} else if (tn === $.OPTGROUP) {
|
|
if (p.openElements.currentTagName === $.OPTION) {
|
|
p.openElements.pop();
|
|
}
|
|
|
|
if (p.openElements.currentTagName === $.OPTGROUP) {
|
|
p.openElements.pop();
|
|
}
|
|
|
|
p._insertElement(token, NS.HTML);
|
|
} else if (tn === $.INPUT || tn === $.KEYGEN || tn === $.TEXTAREA || tn === $.SELECT) {
|
|
if (p.openElements.hasInSelectScope($.SELECT)) {
|
|
p.openElements.popUntilTagNamePopped($.SELECT);
|
|
p._resetInsertionMode();
|
|
|
|
if (tn !== $.SELECT) {
|
|
p._processToken(token);
|
|
}
|
|
}
|
|
} else if (tn === $.SCRIPT || tn === $.TEMPLATE) {
|
|
startTagInHead(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagInSelect(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.OPTGROUP) {
|
|
const prevOpenElement = p.openElements.items[p.openElements.stackTop - 1];
|
|
const prevOpenElementTn = prevOpenElement && p.treeAdapter.getTagName(prevOpenElement);
|
|
|
|
if (p.openElements.currentTagName === $.OPTION && prevOpenElementTn === $.OPTGROUP) {
|
|
p.openElements.pop();
|
|
}
|
|
|
|
if (p.openElements.currentTagName === $.OPTGROUP) {
|
|
p.openElements.pop();
|
|
}
|
|
} else if (tn === $.OPTION) {
|
|
if (p.openElements.currentTagName === $.OPTION) {
|
|
p.openElements.pop();
|
|
}
|
|
} else if (tn === $.SELECT && p.openElements.hasInSelectScope($.SELECT)) {
|
|
p.openElements.popUntilTagNamePopped($.SELECT);
|
|
p._resetInsertionMode();
|
|
} else if (tn === $.TEMPLATE) {
|
|
endTagInHead(p, token);
|
|
}
|
|
}
|
|
|
|
//12.2.5.4.17 The "in select in table" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagInSelectInTable(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (
|
|
tn === $.CAPTION ||
|
|
tn === $.TABLE ||
|
|
tn === $.TBODY ||
|
|
tn === $.TFOOT ||
|
|
tn === $.THEAD ||
|
|
tn === $.TR ||
|
|
tn === $.TD ||
|
|
tn === $.TH
|
|
) {
|
|
p.openElements.popUntilTagNamePopped($.SELECT);
|
|
p._resetInsertionMode();
|
|
p._processToken(token);
|
|
} else {
|
|
startTagInSelect(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagInSelectInTable(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (
|
|
tn === $.CAPTION ||
|
|
tn === $.TABLE ||
|
|
tn === $.TBODY ||
|
|
tn === $.TFOOT ||
|
|
tn === $.THEAD ||
|
|
tn === $.TR ||
|
|
tn === $.TD ||
|
|
tn === $.TH
|
|
) {
|
|
if (p.openElements.hasInTableScope(tn)) {
|
|
p.openElements.popUntilTagNamePopped($.SELECT);
|
|
p._resetInsertionMode();
|
|
p._processToken(token);
|
|
}
|
|
} else {
|
|
endTagInSelect(p, token);
|
|
}
|
|
}
|
|
|
|
// The "in template" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagInTemplate(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (
|
|
tn === $.BASE ||
|
|
tn === $.BASEFONT ||
|
|
tn === $.BGSOUND ||
|
|
tn === $.LINK ||
|
|
tn === $.META ||
|
|
tn === $.NOFRAMES ||
|
|
tn === $.SCRIPT ||
|
|
tn === $.STYLE ||
|
|
tn === $.TEMPLATE ||
|
|
tn === $.TITLE
|
|
) {
|
|
startTagInHead(p, token);
|
|
} else {
|
|
const newInsertionMode = TEMPLATE_INSERTION_MODE_SWITCH_MAP[tn] || IN_BODY_MODE;
|
|
|
|
p._popTmplInsertionMode();
|
|
p._pushTmplInsertionMode(newInsertionMode);
|
|
p.insertionMode = newInsertionMode;
|
|
p._processToken(token);
|
|
}
|
|
}
|
|
|
|
function endTagInTemplate(p, token) {
|
|
if (token.tagName === $.TEMPLATE) {
|
|
endTagInHead(p, token);
|
|
}
|
|
}
|
|
|
|
function eofInTemplate(p, token) {
|
|
if (p.openElements.tmplCount > 0) {
|
|
p.openElements.popUntilTagNamePopped($.TEMPLATE);
|
|
p.activeFormattingElements.clearToLastMarker();
|
|
p._popTmplInsertionMode();
|
|
p._resetInsertionMode();
|
|
p._processToken(token);
|
|
} else {
|
|
p.stopped = true;
|
|
}
|
|
}
|
|
|
|
// The "after body" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagAfterBody(p, token) {
|
|
if (token.tagName === $.HTML) {
|
|
startTagInBody(p, token);
|
|
} else {
|
|
tokenAfterBody(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagAfterBody(p, token) {
|
|
if (token.tagName === $.HTML) {
|
|
if (!p.fragmentContext) {
|
|
p.insertionMode = AFTER_AFTER_BODY_MODE;
|
|
}
|
|
} else {
|
|
tokenAfterBody(p, token);
|
|
}
|
|
}
|
|
|
|
function tokenAfterBody(p, token) {
|
|
p.insertionMode = IN_BODY_MODE;
|
|
p._processToken(token);
|
|
}
|
|
|
|
// The "in frameset" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagInFrameset(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.HTML) {
|
|
startTagInBody(p, token);
|
|
} else if (tn === $.FRAMESET) {
|
|
p._insertElement(token, NS.HTML);
|
|
} else if (tn === $.FRAME) {
|
|
p._appendElement(token, NS.HTML);
|
|
token.ackSelfClosing = true;
|
|
} else if (tn === $.NOFRAMES) {
|
|
startTagInHead(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagInFrameset(p, token) {
|
|
if (token.tagName === $.FRAMESET && !p.openElements.isRootHtmlElementCurrent()) {
|
|
p.openElements.pop();
|
|
|
|
if (!p.fragmentContext && p.openElements.currentTagName !== $.FRAMESET) {
|
|
p.insertionMode = AFTER_FRAMESET_MODE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// The "after frameset" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagAfterFrameset(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.HTML) {
|
|
startTagInBody(p, token);
|
|
} else if (tn === $.NOFRAMES) {
|
|
startTagInHead(p, token);
|
|
}
|
|
}
|
|
|
|
function endTagAfterFrameset(p, token) {
|
|
if (token.tagName === $.HTML) {
|
|
p.insertionMode = AFTER_AFTER_FRAMESET_MODE;
|
|
}
|
|
}
|
|
|
|
// The "after after body" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagAfterAfterBody(p, token) {
|
|
if (token.tagName === $.HTML) {
|
|
startTagInBody(p, token);
|
|
} else {
|
|
tokenAfterAfterBody(p, token);
|
|
}
|
|
}
|
|
|
|
function tokenAfterAfterBody(p, token) {
|
|
p.insertionMode = IN_BODY_MODE;
|
|
p._processToken(token);
|
|
}
|
|
|
|
// The "after after frameset" insertion mode
|
|
//------------------------------------------------------------------
|
|
function startTagAfterAfterFrameset(p, token) {
|
|
const tn = token.tagName;
|
|
|
|
if (tn === $.HTML) {
|
|
startTagInBody(p, token);
|
|
} else if (tn === $.NOFRAMES) {
|
|
startTagInHead(p, token);
|
|
}
|
|
}
|
|
|
|
// The rules for parsing tokens in foreign content
|
|
//------------------------------------------------------------------
|
|
function nullCharacterInForeignContent(p, token) {
|
|
token.chars = unicode.REPLACEMENT_CHARACTER;
|
|
p._insertCharacters(token);
|
|
}
|
|
|
|
function characterInForeignContent(p, token) {
|
|
p._insertCharacters(token);
|
|
p.framesetOk = false;
|
|
}
|
|
|
|
function startTagInForeignContent(p, token) {
|
|
if (foreignContent.causesExit(token) && !p.fragmentContext) {
|
|
while (
|
|
p.treeAdapter.getNamespaceURI(p.openElements.current) !== NS.HTML &&
|
|
!p._isIntegrationPoint(p.openElements.current)
|
|
) {
|
|
p.openElements.pop();
|
|
}
|
|
|
|
p._processToken(token);
|
|
} else {
|
|
const current = p._getAdjustedCurrentElement();
|
|
const currentNs = p.treeAdapter.getNamespaceURI(current);
|
|
|
|
if (currentNs === NS.MATHML) {
|
|
foreignContent.adjustTokenMathMLAttrs(token);
|
|
} else if (currentNs === NS.SVG) {
|
|
foreignContent.adjustTokenSVGTagName(token);
|
|
foreignContent.adjustTokenSVGAttrs(token);
|
|
}
|
|
|
|
foreignContent.adjustTokenXMLAttrs(token);
|
|
|
|
if (token.selfClosing) {
|
|
p._appendElement(token, currentNs);
|
|
} else {
|
|
p._insertElement(token, currentNs);
|
|
}
|
|
|
|
token.ackSelfClosing = true;
|
|
}
|
|
}
|
|
|
|
function endTagInForeignContent(p, token) {
|
|
for (let i = p.openElements.stackTop; i > 0; i--) {
|
|
const element = p.openElements.items[i];
|
|
|
|
if (p.treeAdapter.getNamespaceURI(element) === NS.HTML) {
|
|
p._processToken(token);
|
|
break;
|
|
}
|
|
|
|
if (p.treeAdapter.getTagName(element).toLowerCase() === token.tagName) {
|
|
p.openElements.popUntilElementPopped(element);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
},{"../common/doctype":64,"../common/error-codes":65,"../common/foreign-content":66,"../common/html":67,"../common/unicode":68,"../extensions/error-reporting/parser-mixin":70,"../extensions/location-info/parser-mixin":74,"../tokenizer":82,"../tree-adapters/default":85,"../utils/merge-options":86,"../utils/mixin":87,"./formatting-element-list":78,"./open-element-stack":80}],80:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const HTML = require('../common/html');
|
|
|
|
//Aliases
|
|
const $ = HTML.TAG_NAMES;
|
|
const NS = HTML.NAMESPACES;
|
|
|
|
//Element utils
|
|
|
|
//OPTIMIZATION: Integer comparisons are low-cost, so we can use very fast tag name length filters here.
|
|
//It's faster than using dictionary.
|
|
function isImpliedEndTagRequired(tn) {
|
|
switch (tn.length) {
|
|
case 1:
|
|
return tn === $.P;
|
|
|
|
case 2:
|
|
return tn === $.RB || tn === $.RP || tn === $.RT || tn === $.DD || tn === $.DT || tn === $.LI;
|
|
|
|
case 3:
|
|
return tn === $.RTC;
|
|
|
|
case 6:
|
|
return tn === $.OPTION;
|
|
|
|
case 8:
|
|
return tn === $.OPTGROUP;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function isImpliedEndTagRequiredThoroughly(tn) {
|
|
switch (tn.length) {
|
|
case 1:
|
|
return tn === $.P;
|
|
|
|
case 2:
|
|
return (
|
|
tn === $.RB ||
|
|
tn === $.RP ||
|
|
tn === $.RT ||
|
|
tn === $.DD ||
|
|
tn === $.DT ||
|
|
tn === $.LI ||
|
|
tn === $.TD ||
|
|
tn === $.TH ||
|
|
tn === $.TR
|
|
);
|
|
|
|
case 3:
|
|
return tn === $.RTC;
|
|
|
|
case 5:
|
|
return tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD;
|
|
|
|
case 6:
|
|
return tn === $.OPTION;
|
|
|
|
case 7:
|
|
return tn === $.CAPTION;
|
|
|
|
case 8:
|
|
return tn === $.OPTGROUP || tn === $.COLGROUP;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function isScopingElement(tn, ns) {
|
|
switch (tn.length) {
|
|
case 2:
|
|
if (tn === $.TD || tn === $.TH) {
|
|
return ns === NS.HTML;
|
|
} else if (tn === $.MI || tn === $.MO || tn === $.MN || tn === $.MS) {
|
|
return ns === NS.MATHML;
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
if (tn === $.HTML) {
|
|
return ns === NS.HTML;
|
|
} else if (tn === $.DESC) {
|
|
return ns === NS.SVG;
|
|
}
|
|
|
|
break;
|
|
|
|
case 5:
|
|
if (tn === $.TABLE) {
|
|
return ns === NS.HTML;
|
|
} else if (tn === $.MTEXT) {
|
|
return ns === NS.MATHML;
|
|
} else if (tn === $.TITLE) {
|
|
return ns === NS.SVG;
|
|
}
|
|
|
|
break;
|
|
|
|
case 6:
|
|
return (tn === $.APPLET || tn === $.OBJECT) && ns === NS.HTML;
|
|
|
|
case 7:
|
|
return (tn === $.CAPTION || tn === $.MARQUEE) && ns === NS.HTML;
|
|
|
|
case 8:
|
|
return tn === $.TEMPLATE && ns === NS.HTML;
|
|
|
|
case 13:
|
|
return tn === $.FOREIGN_OBJECT && ns === NS.SVG;
|
|
|
|
case 14:
|
|
return tn === $.ANNOTATION_XML && ns === NS.MATHML;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//Stack of open elements
|
|
class OpenElementStack {
|
|
constructor(document, treeAdapter) {
|
|
this.stackTop = -1;
|
|
this.items = [];
|
|
this.current = document;
|
|
this.currentTagName = null;
|
|
this.currentTmplContent = null;
|
|
this.tmplCount = 0;
|
|
this.treeAdapter = treeAdapter;
|
|
}
|
|
|
|
//Index of element
|
|
_indexOf(element) {
|
|
let idx = -1;
|
|
|
|
for (let i = this.stackTop; i >= 0; i--) {
|
|
if (this.items[i] === element) {
|
|
idx = i;
|
|
break;
|
|
}
|
|
}
|
|
return idx;
|
|
}
|
|
|
|
//Update current element
|
|
_isInTemplate() {
|
|
return this.currentTagName === $.TEMPLATE && this.treeAdapter.getNamespaceURI(this.current) === NS.HTML;
|
|
}
|
|
|
|
_updateCurrentElement() {
|
|
this.current = this.items[this.stackTop];
|
|
this.currentTagName = this.current && this.treeAdapter.getTagName(this.current);
|
|
|
|
this.currentTmplContent = this._isInTemplate() ? this.treeAdapter.getTemplateContent(this.current) : null;
|
|
}
|
|
|
|
//Mutations
|
|
push(element) {
|
|
this.items[++this.stackTop] = element;
|
|
this._updateCurrentElement();
|
|
|
|
if (this._isInTemplate()) {
|
|
this.tmplCount++;
|
|
}
|
|
}
|
|
|
|
pop() {
|
|
this.stackTop--;
|
|
|
|
if (this.tmplCount > 0 && this._isInTemplate()) {
|
|
this.tmplCount--;
|
|
}
|
|
|
|
this._updateCurrentElement();
|
|
}
|
|
|
|
replace(oldElement, newElement) {
|
|
const idx = this._indexOf(oldElement);
|
|
|
|
this.items[idx] = newElement;
|
|
|
|
if (idx === this.stackTop) {
|
|
this._updateCurrentElement();
|
|
}
|
|
}
|
|
|
|
insertAfter(referenceElement, newElement) {
|
|
const insertionIdx = this._indexOf(referenceElement) + 1;
|
|
|
|
this.items.splice(insertionIdx, 0, newElement);
|
|
|
|
if (insertionIdx === ++this.stackTop) {
|
|
this._updateCurrentElement();
|
|
}
|
|
}
|
|
|
|
popUntilTagNamePopped(tagName) {
|
|
while (this.stackTop > -1) {
|
|
const tn = this.currentTagName;
|
|
const ns = this.treeAdapter.getNamespaceURI(this.current);
|
|
|
|
this.pop();
|
|
|
|
if (tn === tagName && ns === NS.HTML) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
popUntilElementPopped(element) {
|
|
while (this.stackTop > -1) {
|
|
const poppedElement = this.current;
|
|
|
|
this.pop();
|
|
|
|
if (poppedElement === element) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
popUntilNumberedHeaderPopped() {
|
|
while (this.stackTop > -1) {
|
|
const tn = this.currentTagName;
|
|
const ns = this.treeAdapter.getNamespaceURI(this.current);
|
|
|
|
this.pop();
|
|
|
|
if (
|
|
tn === $.H1 ||
|
|
tn === $.H2 ||
|
|
tn === $.H3 ||
|
|
tn === $.H4 ||
|
|
tn === $.H5 ||
|
|
(tn === $.H6 && ns === NS.HTML)
|
|
) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
popUntilTableCellPopped() {
|
|
while (this.stackTop > -1) {
|
|
const tn = this.currentTagName;
|
|
const ns = this.treeAdapter.getNamespaceURI(this.current);
|
|
|
|
this.pop();
|
|
|
|
if (tn === $.TD || (tn === $.TH && ns === NS.HTML)) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
popAllUpToHtmlElement() {
|
|
//NOTE: here we assume that root <html> element is always first in the open element stack, so
|
|
//we perform this fast stack clean up.
|
|
this.stackTop = 0;
|
|
this._updateCurrentElement();
|
|
}
|
|
|
|
clearBackToTableContext() {
|
|
while (
|
|
(this.currentTagName !== $.TABLE && this.currentTagName !== $.TEMPLATE && this.currentTagName !== $.HTML) ||
|
|
this.treeAdapter.getNamespaceURI(this.current) !== NS.HTML
|
|
) {
|
|
this.pop();
|
|
}
|
|
}
|
|
|
|
clearBackToTableBodyContext() {
|
|
while (
|
|
(this.currentTagName !== $.TBODY &&
|
|
this.currentTagName !== $.TFOOT &&
|
|
this.currentTagName !== $.THEAD &&
|
|
this.currentTagName !== $.TEMPLATE &&
|
|
this.currentTagName !== $.HTML) ||
|
|
this.treeAdapter.getNamespaceURI(this.current) !== NS.HTML
|
|
) {
|
|
this.pop();
|
|
}
|
|
}
|
|
|
|
clearBackToTableRowContext() {
|
|
while (
|
|
(this.currentTagName !== $.TR && this.currentTagName !== $.TEMPLATE && this.currentTagName !== $.HTML) ||
|
|
this.treeAdapter.getNamespaceURI(this.current) !== NS.HTML
|
|
) {
|
|
this.pop();
|
|
}
|
|
}
|
|
|
|
remove(element) {
|
|
for (let i = this.stackTop; i >= 0; i--) {
|
|
if (this.items[i] === element) {
|
|
this.items.splice(i, 1);
|
|
this.stackTop--;
|
|
this._updateCurrentElement();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Search
|
|
tryPeekProperlyNestedBodyElement() {
|
|
//Properly nested <body> element (should be second element in stack).
|
|
const element = this.items[1];
|
|
|
|
return element && this.treeAdapter.getTagName(element) === $.BODY ? element : null;
|
|
}
|
|
|
|
contains(element) {
|
|
return this._indexOf(element) > -1;
|
|
}
|
|
|
|
getCommonAncestor(element) {
|
|
let elementIdx = this._indexOf(element);
|
|
|
|
return --elementIdx >= 0 ? this.items[elementIdx] : null;
|
|
}
|
|
|
|
isRootHtmlElementCurrent() {
|
|
return this.stackTop === 0 && this.currentTagName === $.HTML;
|
|
}
|
|
|
|
//Element in scope
|
|
hasInScope(tagName) {
|
|
for (let i = this.stackTop; i >= 0; i--) {
|
|
const tn = this.treeAdapter.getTagName(this.items[i]);
|
|
const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
|
|
|
|
if (tn === tagName && ns === NS.HTML) {
|
|
return true;
|
|
}
|
|
|
|
if (isScopingElement(tn, ns)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
hasNumberedHeaderInScope() {
|
|
for (let i = this.stackTop; i >= 0; i--) {
|
|
const tn = this.treeAdapter.getTagName(this.items[i]);
|
|
const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
|
|
|
|
if (
|
|
(tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6) &&
|
|
ns === NS.HTML
|
|
) {
|
|
return true;
|
|
}
|
|
|
|
if (isScopingElement(tn, ns)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
hasInListItemScope(tagName) {
|
|
for (let i = this.stackTop; i >= 0; i--) {
|
|
const tn = this.treeAdapter.getTagName(this.items[i]);
|
|
const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
|
|
|
|
if (tn === tagName && ns === NS.HTML) {
|
|
return true;
|
|
}
|
|
|
|
if (((tn === $.UL || tn === $.OL) && ns === NS.HTML) || isScopingElement(tn, ns)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
hasInButtonScope(tagName) {
|
|
for (let i = this.stackTop; i >= 0; i--) {
|
|
const tn = this.treeAdapter.getTagName(this.items[i]);
|
|
const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
|
|
|
|
if (tn === tagName && ns === NS.HTML) {
|
|
return true;
|
|
}
|
|
|
|
if ((tn === $.BUTTON && ns === NS.HTML) || isScopingElement(tn, ns)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
hasInTableScope(tagName) {
|
|
for (let i = this.stackTop; i >= 0; i--) {
|
|
const tn = this.treeAdapter.getTagName(this.items[i]);
|
|
const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
|
|
|
|
if (ns !== NS.HTML) {
|
|
continue;
|
|
}
|
|
|
|
if (tn === tagName) {
|
|
return true;
|
|
}
|
|
|
|
if (tn === $.TABLE || tn === $.TEMPLATE || tn === $.HTML) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
hasTableBodyContextInTableScope() {
|
|
for (let i = this.stackTop; i >= 0; i--) {
|
|
const tn = this.treeAdapter.getTagName(this.items[i]);
|
|
const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
|
|
|
|
if (ns !== NS.HTML) {
|
|
continue;
|
|
}
|
|
|
|
if (tn === $.TBODY || tn === $.THEAD || tn === $.TFOOT) {
|
|
return true;
|
|
}
|
|
|
|
if (tn === $.TABLE || tn === $.HTML) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
hasInSelectScope(tagName) {
|
|
for (let i = this.stackTop; i >= 0; i--) {
|
|
const tn = this.treeAdapter.getTagName(this.items[i]);
|
|
const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
|
|
|
|
if (ns !== NS.HTML) {
|
|
continue;
|
|
}
|
|
|
|
if (tn === tagName) {
|
|
return true;
|
|
}
|
|
|
|
if (tn !== $.OPTION && tn !== $.OPTGROUP) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//Implied end tags
|
|
generateImpliedEndTags() {
|
|
while (isImpliedEndTagRequired(this.currentTagName)) {
|
|
this.pop();
|
|
}
|
|
}
|
|
|
|
generateImpliedEndTagsThoroughly() {
|
|
while (isImpliedEndTagRequiredThoroughly(this.currentTagName)) {
|
|
this.pop();
|
|
}
|
|
}
|
|
|
|
generateImpliedEndTagsWithExclusion(exclusionTagName) {
|
|
while (isImpliedEndTagRequired(this.currentTagName) && this.currentTagName !== exclusionTagName) {
|
|
this.pop();
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = OpenElementStack;
|
|
|
|
},{"../common/html":67}],81:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const defaultTreeAdapter = require('../tree-adapters/default');
|
|
const mergeOptions = require('../utils/merge-options');
|
|
const doctype = require('../common/doctype');
|
|
const HTML = require('../common/html');
|
|
|
|
//Aliases
|
|
const $ = HTML.TAG_NAMES;
|
|
const NS = HTML.NAMESPACES;
|
|
|
|
//Default serializer options
|
|
const DEFAULT_OPTIONS = {
|
|
treeAdapter: defaultTreeAdapter
|
|
};
|
|
|
|
//Escaping regexes
|
|
const AMP_REGEX = /&/g;
|
|
const NBSP_REGEX = /\u00a0/g;
|
|
const DOUBLE_QUOTE_REGEX = /"/g;
|
|
const LT_REGEX = /</g;
|
|
const GT_REGEX = />/g;
|
|
|
|
//Serializer
|
|
class Serializer {
|
|
constructor(node, options) {
|
|
this.options = mergeOptions(DEFAULT_OPTIONS, options);
|
|
this.treeAdapter = this.options.treeAdapter;
|
|
|
|
this.html = '';
|
|
this.startNode = node;
|
|
}
|
|
|
|
//API
|
|
serialize() {
|
|
this._serializeChildNodes(this.startNode);
|
|
|
|
return this.html;
|
|
}
|
|
|
|
//Internals
|
|
_serializeChildNodes(parentNode) {
|
|
const childNodes = this.treeAdapter.getChildNodes(parentNode);
|
|
|
|
if (childNodes) {
|
|
for (let i = 0, cnLength = childNodes.length; i < cnLength; i++) {
|
|
const currentNode = childNodes[i];
|
|
|
|
if (this.treeAdapter.isElementNode(currentNode)) {
|
|
this._serializeElement(currentNode);
|
|
} else if (this.treeAdapter.isTextNode(currentNode)) {
|
|
this._serializeTextNode(currentNode);
|
|
} else if (this.treeAdapter.isCommentNode(currentNode)) {
|
|
this._serializeCommentNode(currentNode);
|
|
} else if (this.treeAdapter.isDocumentTypeNode(currentNode)) {
|
|
this._serializeDocumentTypeNode(currentNode);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
_serializeElement(node) {
|
|
const tn = this.treeAdapter.getTagName(node);
|
|
const ns = this.treeAdapter.getNamespaceURI(node);
|
|
|
|
this.html += '<' + tn;
|
|
this._serializeAttributes(node);
|
|
this.html += '>';
|
|
|
|
if (
|
|
tn !== $.AREA &&
|
|
tn !== $.BASE &&
|
|
tn !== $.BASEFONT &&
|
|
tn !== $.BGSOUND &&
|
|
tn !== $.BR &&
|
|
tn !== $.COL &&
|
|
tn !== $.EMBED &&
|
|
tn !== $.FRAME &&
|
|
tn !== $.HR &&
|
|
tn !== $.IMG &&
|
|
tn !== $.INPUT &&
|
|
tn !== $.KEYGEN &&
|
|
tn !== $.LINK &&
|
|
tn !== $.META &&
|
|
tn !== $.PARAM &&
|
|
tn !== $.SOURCE &&
|
|
tn !== $.TRACK &&
|
|
tn !== $.WBR
|
|
) {
|
|
const childNodesHolder =
|
|
tn === $.TEMPLATE && ns === NS.HTML ? this.treeAdapter.getTemplateContent(node) : node;
|
|
|
|
this._serializeChildNodes(childNodesHolder);
|
|
this.html += '</' + tn + '>';
|
|
}
|
|
}
|
|
|
|
_serializeAttributes(node) {
|
|
const attrs = this.treeAdapter.getAttrList(node);
|
|
|
|
for (let i = 0, attrsLength = attrs.length; i < attrsLength; i++) {
|
|
const attr = attrs[i];
|
|
const value = Serializer.escapeString(attr.value, true);
|
|
|
|
this.html += ' ';
|
|
|
|
if (!attr.namespace) {
|
|
this.html += attr.name;
|
|
} else if (attr.namespace === NS.XML) {
|
|
this.html += 'xml:' + attr.name;
|
|
} else if (attr.namespace === NS.XMLNS) {
|
|
if (attr.name !== 'xmlns') {
|
|
this.html += 'xmlns:';
|
|
}
|
|
|
|
this.html += attr.name;
|
|
} else if (attr.namespace === NS.XLINK) {
|
|
this.html += 'xlink:' + attr.name;
|
|
} else {
|
|
this.html += attr.prefix + ':' + attr.name;
|
|
}
|
|
|
|
this.html += '="' + value + '"';
|
|
}
|
|
}
|
|
|
|
_serializeTextNode(node) {
|
|
const content = this.treeAdapter.getTextNodeContent(node);
|
|
const parent = this.treeAdapter.getParentNode(node);
|
|
let parentTn = void 0;
|
|
|
|
if (parent && this.treeAdapter.isElementNode(parent)) {
|
|
parentTn = this.treeAdapter.getTagName(parent);
|
|
}
|
|
|
|
if (
|
|
parentTn === $.STYLE ||
|
|
parentTn === $.SCRIPT ||
|
|
parentTn === $.XMP ||
|
|
parentTn === $.IFRAME ||
|
|
parentTn === $.NOEMBED ||
|
|
parentTn === $.NOFRAMES ||
|
|
parentTn === $.PLAINTEXT ||
|
|
parentTn === $.NOSCRIPT
|
|
) {
|
|
this.html += content;
|
|
} else {
|
|
this.html += Serializer.escapeString(content, false);
|
|
}
|
|
}
|
|
|
|
_serializeCommentNode(node) {
|
|
this.html += '<!--' + this.treeAdapter.getCommentNodeContent(node) + '-->';
|
|
}
|
|
|
|
_serializeDocumentTypeNode(node) {
|
|
const name = this.treeAdapter.getDocumentTypeNodeName(node);
|
|
|
|
this.html += '<' + doctype.serializeContent(name, null, null) + '>';
|
|
}
|
|
}
|
|
|
|
// NOTE: used in tests and by rewriting stream
|
|
Serializer.escapeString = function(str, attrMode) {
|
|
str = str.replace(AMP_REGEX, '&').replace(NBSP_REGEX, ' ');
|
|
|
|
if (attrMode) {
|
|
str = str.replace(DOUBLE_QUOTE_REGEX, '"');
|
|
} else {
|
|
str = str.replace(LT_REGEX, '<').replace(GT_REGEX, '>');
|
|
}
|
|
|
|
return str;
|
|
};
|
|
|
|
module.exports = Serializer;
|
|
|
|
},{"../common/doctype":64,"../common/html":67,"../tree-adapters/default":85,"../utils/merge-options":86}],82:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const Preprocessor = require('./preprocessor');
|
|
const unicode = require('../common/unicode');
|
|
const neTree = require('./named-entity-data');
|
|
const ERR = require('../common/error-codes');
|
|
|
|
//Aliases
|
|
const $ = unicode.CODE_POINTS;
|
|
const $$ = unicode.CODE_POINT_SEQUENCES;
|
|
|
|
//C1 Unicode control character reference replacements
|
|
const C1_CONTROLS_REFERENCE_REPLACEMENTS = {
|
|
0x80: 0x20ac,
|
|
0x82: 0x201a,
|
|
0x83: 0x0192,
|
|
0x84: 0x201e,
|
|
0x85: 0x2026,
|
|
0x86: 0x2020,
|
|
0x87: 0x2021,
|
|
0x88: 0x02c6,
|
|
0x89: 0x2030,
|
|
0x8a: 0x0160,
|
|
0x8b: 0x2039,
|
|
0x8c: 0x0152,
|
|
0x8e: 0x017d,
|
|
0x91: 0x2018,
|
|
0x92: 0x2019,
|
|
0x93: 0x201c,
|
|
0x94: 0x201d,
|
|
0x95: 0x2022,
|
|
0x96: 0x2013,
|
|
0x97: 0x2014,
|
|
0x98: 0x02dc,
|
|
0x99: 0x2122,
|
|
0x9a: 0x0161,
|
|
0x9b: 0x203a,
|
|
0x9c: 0x0153,
|
|
0x9e: 0x017e,
|
|
0x9f: 0x0178
|
|
};
|
|
|
|
// Named entity tree flags
|
|
const HAS_DATA_FLAG = 1 << 0;
|
|
const DATA_DUPLET_FLAG = 1 << 1;
|
|
const HAS_BRANCHES_FLAG = 1 << 2;
|
|
const MAX_BRANCH_MARKER_VALUE = HAS_DATA_FLAG | DATA_DUPLET_FLAG | HAS_BRANCHES_FLAG;
|
|
|
|
//States
|
|
const DATA_STATE = 'DATA_STATE';
|
|
const RCDATA_STATE = 'RCDATA_STATE';
|
|
const RAWTEXT_STATE = 'RAWTEXT_STATE';
|
|
const SCRIPT_DATA_STATE = 'SCRIPT_DATA_STATE';
|
|
const PLAINTEXT_STATE = 'PLAINTEXT_STATE';
|
|
const TAG_OPEN_STATE = 'TAG_OPEN_STATE';
|
|
const END_TAG_OPEN_STATE = 'END_TAG_OPEN_STATE';
|
|
const TAG_NAME_STATE = 'TAG_NAME_STATE';
|
|
const RCDATA_LESS_THAN_SIGN_STATE = 'RCDATA_LESS_THAN_SIGN_STATE';
|
|
const RCDATA_END_TAG_OPEN_STATE = 'RCDATA_END_TAG_OPEN_STATE';
|
|
const RCDATA_END_TAG_NAME_STATE = 'RCDATA_END_TAG_NAME_STATE';
|
|
const RAWTEXT_LESS_THAN_SIGN_STATE = 'RAWTEXT_LESS_THAN_SIGN_STATE';
|
|
const RAWTEXT_END_TAG_OPEN_STATE = 'RAWTEXT_END_TAG_OPEN_STATE';
|
|
const RAWTEXT_END_TAG_NAME_STATE = 'RAWTEXT_END_TAG_NAME_STATE';
|
|
const SCRIPT_DATA_LESS_THAN_SIGN_STATE = 'SCRIPT_DATA_LESS_THAN_SIGN_STATE';
|
|
const SCRIPT_DATA_END_TAG_OPEN_STATE = 'SCRIPT_DATA_END_TAG_OPEN_STATE';
|
|
const SCRIPT_DATA_END_TAG_NAME_STATE = 'SCRIPT_DATA_END_TAG_NAME_STATE';
|
|
const SCRIPT_DATA_ESCAPE_START_STATE = 'SCRIPT_DATA_ESCAPE_START_STATE';
|
|
const SCRIPT_DATA_ESCAPE_START_DASH_STATE = 'SCRIPT_DATA_ESCAPE_START_DASH_STATE';
|
|
const SCRIPT_DATA_ESCAPED_STATE = 'SCRIPT_DATA_ESCAPED_STATE';
|
|
const SCRIPT_DATA_ESCAPED_DASH_STATE = 'SCRIPT_DATA_ESCAPED_DASH_STATE';
|
|
const SCRIPT_DATA_ESCAPED_DASH_DASH_STATE = 'SCRIPT_DATA_ESCAPED_DASH_DASH_STATE';
|
|
const SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE = 'SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE';
|
|
const SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE = 'SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE';
|
|
const SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE = 'SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE';
|
|
const SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE';
|
|
const SCRIPT_DATA_DOUBLE_ESCAPED_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_STATE';
|
|
const SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE';
|
|
const SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE';
|
|
const SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE';
|
|
const SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE';
|
|
const BEFORE_ATTRIBUTE_NAME_STATE = 'BEFORE_ATTRIBUTE_NAME_STATE';
|
|
const ATTRIBUTE_NAME_STATE = 'ATTRIBUTE_NAME_STATE';
|
|
const AFTER_ATTRIBUTE_NAME_STATE = 'AFTER_ATTRIBUTE_NAME_STATE';
|
|
const BEFORE_ATTRIBUTE_VALUE_STATE = 'BEFORE_ATTRIBUTE_VALUE_STATE';
|
|
const ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE = 'ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE';
|
|
const ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE = 'ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE';
|
|
const ATTRIBUTE_VALUE_UNQUOTED_STATE = 'ATTRIBUTE_VALUE_UNQUOTED_STATE';
|
|
const AFTER_ATTRIBUTE_VALUE_QUOTED_STATE = 'AFTER_ATTRIBUTE_VALUE_QUOTED_STATE';
|
|
const SELF_CLOSING_START_TAG_STATE = 'SELF_CLOSING_START_TAG_STATE';
|
|
const BOGUS_COMMENT_STATE = 'BOGUS_COMMENT_STATE';
|
|
const MARKUP_DECLARATION_OPEN_STATE = 'MARKUP_DECLARATION_OPEN_STATE';
|
|
const COMMENT_START_STATE = 'COMMENT_START_STATE';
|
|
const COMMENT_START_DASH_STATE = 'COMMENT_START_DASH_STATE';
|
|
const COMMENT_STATE = 'COMMENT_STATE';
|
|
const COMMENT_LESS_THAN_SIGN_STATE = 'COMMENT_LESS_THAN_SIGN_STATE';
|
|
const COMMENT_LESS_THAN_SIGN_BANG_STATE = 'COMMENT_LESS_THAN_SIGN_BANG_STATE';
|
|
const COMMENT_LESS_THAN_SIGN_BANG_DASH_STATE = 'COMMENT_LESS_THAN_SIGN_BANG_DASH_STATE';
|
|
const COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH_STATE = 'COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH_STATE';
|
|
const COMMENT_END_DASH_STATE = 'COMMENT_END_DASH_STATE';
|
|
const COMMENT_END_STATE = 'COMMENT_END_STATE';
|
|
const COMMENT_END_BANG_STATE = 'COMMENT_END_BANG_STATE';
|
|
const DOCTYPE_STATE = 'DOCTYPE_STATE';
|
|
const BEFORE_DOCTYPE_NAME_STATE = 'BEFORE_DOCTYPE_NAME_STATE';
|
|
const DOCTYPE_NAME_STATE = 'DOCTYPE_NAME_STATE';
|
|
const AFTER_DOCTYPE_NAME_STATE = 'AFTER_DOCTYPE_NAME_STATE';
|
|
const AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE = 'AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE';
|
|
const BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE = 'BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE';
|
|
const DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE = 'DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE';
|
|
const DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE = 'DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE';
|
|
const AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE = 'AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE';
|
|
const BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE = 'BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE';
|
|
const AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE = 'AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE';
|
|
const BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE = 'BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE';
|
|
const DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE = 'DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE';
|
|
const DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE = 'DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE';
|
|
const AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE = 'AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE';
|
|
const BOGUS_DOCTYPE_STATE = 'BOGUS_DOCTYPE_STATE';
|
|
const CDATA_SECTION_STATE = 'CDATA_SECTION_STATE';
|
|
const CDATA_SECTION_BRACKET_STATE = 'CDATA_SECTION_BRACKET_STATE';
|
|
const CDATA_SECTION_END_STATE = 'CDATA_SECTION_END_STATE';
|
|
const CHARACTER_REFERENCE_STATE = 'CHARACTER_REFERENCE_STATE';
|
|
const NAMED_CHARACTER_REFERENCE_STATE = 'NAMED_CHARACTER_REFERENCE_STATE';
|
|
const AMBIGUOUS_AMPERSAND_STATE = 'AMBIGUOS_AMPERSAND_STATE';
|
|
const NUMERIC_CHARACTER_REFERENCE_STATE = 'NUMERIC_CHARACTER_REFERENCE_STATE';
|
|
const HEXADEMICAL_CHARACTER_REFERENCE_START_STATE = 'HEXADEMICAL_CHARACTER_REFERENCE_START_STATE';
|
|
const DECIMAL_CHARACTER_REFERENCE_START_STATE = 'DECIMAL_CHARACTER_REFERENCE_START_STATE';
|
|
const HEXADEMICAL_CHARACTER_REFERENCE_STATE = 'HEXADEMICAL_CHARACTER_REFERENCE_STATE';
|
|
const DECIMAL_CHARACTER_REFERENCE_STATE = 'DECIMAL_CHARACTER_REFERENCE_STATE';
|
|
const NUMERIC_CHARACTER_REFERENCE_END_STATE = 'NUMERIC_CHARACTER_REFERENCE_END_STATE';
|
|
|
|
//Utils
|
|
|
|
//OPTIMIZATION: these utility functions should not be moved out of this module. V8 Crankshaft will not inline
|
|
//this functions if they will be situated in another module due to context switch.
|
|
//Always perform inlining check before modifying this functions ('node --trace-inlining').
|
|
function isWhitespace(cp) {
|
|
return cp === $.SPACE || cp === $.LINE_FEED || cp === $.TABULATION || cp === $.FORM_FEED;
|
|
}
|
|
|
|
function isAsciiDigit(cp) {
|
|
return cp >= $.DIGIT_0 && cp <= $.DIGIT_9;
|
|
}
|
|
|
|
function isAsciiUpper(cp) {
|
|
return cp >= $.LATIN_CAPITAL_A && cp <= $.LATIN_CAPITAL_Z;
|
|
}
|
|
|
|
function isAsciiLower(cp) {
|
|
return cp >= $.LATIN_SMALL_A && cp <= $.LATIN_SMALL_Z;
|
|
}
|
|
|
|
function isAsciiLetter(cp) {
|
|
return isAsciiLower(cp) || isAsciiUpper(cp);
|
|
}
|
|
|
|
function isAsciiAlphaNumeric(cp) {
|
|
return isAsciiLetter(cp) || isAsciiDigit(cp);
|
|
}
|
|
|
|
function isAsciiUpperHexDigit(cp) {
|
|
return cp >= $.LATIN_CAPITAL_A && cp <= $.LATIN_CAPITAL_F;
|
|
}
|
|
|
|
function isAsciiLowerHexDigit(cp) {
|
|
return cp >= $.LATIN_SMALL_A && cp <= $.LATIN_SMALL_F;
|
|
}
|
|
|
|
function isAsciiHexDigit(cp) {
|
|
return isAsciiDigit(cp) || isAsciiUpperHexDigit(cp) || isAsciiLowerHexDigit(cp);
|
|
}
|
|
|
|
function toAsciiLowerCodePoint(cp) {
|
|
return cp + 0x0020;
|
|
}
|
|
|
|
//NOTE: String.fromCharCode() function can handle only characters from BMP subset.
|
|
//So, we need to workaround this manually.
|
|
//(see: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/fromCharCode#Getting_it_to_work_with_higher_values)
|
|
function toChar(cp) {
|
|
if (cp <= 0xffff) {
|
|
return String.fromCharCode(cp);
|
|
}
|
|
|
|
cp -= 0x10000;
|
|
return String.fromCharCode(((cp >>> 10) & 0x3ff) | 0xd800) + String.fromCharCode(0xdc00 | (cp & 0x3ff));
|
|
}
|
|
|
|
function toAsciiLowerChar(cp) {
|
|
return String.fromCharCode(toAsciiLowerCodePoint(cp));
|
|
}
|
|
|
|
function findNamedEntityTreeBranch(nodeIx, cp) {
|
|
const branchCount = neTree[++nodeIx];
|
|
let lo = ++nodeIx;
|
|
let hi = lo + branchCount - 1;
|
|
|
|
while (lo <= hi) {
|
|
const mid = (lo + hi) >>> 1;
|
|
const midCp = neTree[mid];
|
|
|
|
if (midCp < cp) {
|
|
lo = mid + 1;
|
|
} else if (midCp > cp) {
|
|
hi = mid - 1;
|
|
} else {
|
|
return neTree[mid + branchCount];
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
//Tokenizer
|
|
class Tokenizer {
|
|
constructor() {
|
|
this.preprocessor = new Preprocessor();
|
|
|
|
this.tokenQueue = [];
|
|
|
|
this.allowCDATA = false;
|
|
|
|
this.state = DATA_STATE;
|
|
this.returnState = '';
|
|
|
|
this.charRefCode = -1;
|
|
this.tempBuff = [];
|
|
this.lastStartTagName = '';
|
|
|
|
this.consumedAfterSnapshot = -1;
|
|
this.active = false;
|
|
|
|
this.currentCharacterToken = null;
|
|
this.currentToken = null;
|
|
this.currentAttr = null;
|
|
}
|
|
|
|
//Errors
|
|
_err() {
|
|
// NOTE: err reporting is noop by default. Enabled by mixin.
|
|
}
|
|
|
|
_errOnNextCodePoint(err) {
|
|
this._consume();
|
|
this._err(err);
|
|
this._unconsume();
|
|
}
|
|
|
|
//API
|
|
getNextToken() {
|
|
while (!this.tokenQueue.length && this.active) {
|
|
this.consumedAfterSnapshot = 0;
|
|
|
|
const cp = this._consume();
|
|
|
|
if (!this._ensureHibernation()) {
|
|
this[this.state](cp);
|
|
}
|
|
}
|
|
|
|
return this.tokenQueue.shift();
|
|
}
|
|
|
|
write(chunk, isLastChunk) {
|
|
this.active = true;
|
|
this.preprocessor.write(chunk, isLastChunk);
|
|
}
|
|
|
|
insertHtmlAtCurrentPos(chunk) {
|
|
this.active = true;
|
|
this.preprocessor.insertHtmlAtCurrentPos(chunk);
|
|
}
|
|
|
|
//Hibernation
|
|
_ensureHibernation() {
|
|
if (this.preprocessor.endOfChunkHit) {
|
|
for (; this.consumedAfterSnapshot > 0; this.consumedAfterSnapshot--) {
|
|
this.preprocessor.retreat();
|
|
}
|
|
|
|
this.active = false;
|
|
this.tokenQueue.push({ type: Tokenizer.HIBERNATION_TOKEN });
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//Consumption
|
|
_consume() {
|
|
this.consumedAfterSnapshot++;
|
|
return this.preprocessor.advance();
|
|
}
|
|
|
|
_unconsume() {
|
|
this.consumedAfterSnapshot--;
|
|
this.preprocessor.retreat();
|
|
}
|
|
|
|
_reconsumeInState(state) {
|
|
this.state = state;
|
|
this._unconsume();
|
|
}
|
|
|
|
_consumeSequenceIfMatch(pattern, startCp, caseSensitive) {
|
|
let consumedCount = 0;
|
|
let isMatch = true;
|
|
const patternLength = pattern.length;
|
|
let patternPos = 0;
|
|
let cp = startCp;
|
|
let patternCp = void 0;
|
|
|
|
for (; patternPos < patternLength; patternPos++) {
|
|
if (patternPos > 0) {
|
|
cp = this._consume();
|
|
consumedCount++;
|
|
}
|
|
|
|
if (cp === $.EOF) {
|
|
isMatch = false;
|
|
break;
|
|
}
|
|
|
|
patternCp = pattern[patternPos];
|
|
|
|
if (cp !== patternCp && (caseSensitive || cp !== toAsciiLowerCodePoint(patternCp))) {
|
|
isMatch = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isMatch) {
|
|
while (consumedCount--) {
|
|
this._unconsume();
|
|
}
|
|
}
|
|
|
|
return isMatch;
|
|
}
|
|
|
|
//Temp buffer
|
|
_isTempBufferEqualToScriptString() {
|
|
if (this.tempBuff.length !== $$.SCRIPT_STRING.length) {
|
|
return false;
|
|
}
|
|
|
|
for (let i = 0; i < this.tempBuff.length; i++) {
|
|
if (this.tempBuff[i] !== $$.SCRIPT_STRING[i]) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//Token creation
|
|
_createStartTagToken() {
|
|
this.currentToken = {
|
|
type: Tokenizer.START_TAG_TOKEN,
|
|
tagName: '',
|
|
selfClosing: false,
|
|
ackSelfClosing: false,
|
|
attrs: []
|
|
};
|
|
}
|
|
|
|
_createEndTagToken() {
|
|
this.currentToken = {
|
|
type: Tokenizer.END_TAG_TOKEN,
|
|
tagName: '',
|
|
selfClosing: false,
|
|
attrs: []
|
|
};
|
|
}
|
|
|
|
_createCommentToken() {
|
|
this.currentToken = {
|
|
type: Tokenizer.COMMENT_TOKEN,
|
|
data: ''
|
|
};
|
|
}
|
|
|
|
_createDoctypeToken(initialName) {
|
|
this.currentToken = {
|
|
type: Tokenizer.DOCTYPE_TOKEN,
|
|
name: initialName,
|
|
forceQuirks: false,
|
|
publicId: null,
|
|
systemId: null
|
|
};
|
|
}
|
|
|
|
_createCharacterToken(type, ch) {
|
|
this.currentCharacterToken = {
|
|
type: type,
|
|
chars: ch
|
|
};
|
|
}
|
|
|
|
_createEOFToken() {
|
|
this.currentToken = { type: Tokenizer.EOF_TOKEN };
|
|
}
|
|
|
|
//Tag attributes
|
|
_createAttr(attrNameFirstCh) {
|
|
this.currentAttr = {
|
|
name: attrNameFirstCh,
|
|
value: ''
|
|
};
|
|
}
|
|
|
|
_leaveAttrName(toState) {
|
|
if (Tokenizer.getTokenAttr(this.currentToken, this.currentAttr.name) === null) {
|
|
this.currentToken.attrs.push(this.currentAttr);
|
|
} else {
|
|
this._err(ERR.duplicateAttribute);
|
|
}
|
|
|
|
this.state = toState;
|
|
}
|
|
|
|
_leaveAttrValue(toState) {
|
|
this.state = toState;
|
|
}
|
|
|
|
//Token emission
|
|
_emitCurrentToken() {
|
|
this._emitCurrentCharacterToken();
|
|
|
|
const ct = this.currentToken;
|
|
|
|
this.currentToken = null;
|
|
|
|
//NOTE: store emited start tag's tagName to determine is the following end tag token is appropriate.
|
|
if (ct.type === Tokenizer.START_TAG_TOKEN) {
|
|
this.lastStartTagName = ct.tagName;
|
|
} else if (ct.type === Tokenizer.END_TAG_TOKEN) {
|
|
if (ct.attrs.length > 0) {
|
|
this._err(ERR.endTagWithAttributes);
|
|
}
|
|
|
|
if (ct.selfClosing) {
|
|
this._err(ERR.endTagWithTrailingSolidus);
|
|
}
|
|
}
|
|
|
|
this.tokenQueue.push(ct);
|
|
}
|
|
|
|
_emitCurrentCharacterToken() {
|
|
if (this.currentCharacterToken) {
|
|
this.tokenQueue.push(this.currentCharacterToken);
|
|
this.currentCharacterToken = null;
|
|
}
|
|
}
|
|
|
|
_emitEOFToken() {
|
|
this._createEOFToken();
|
|
this._emitCurrentToken();
|
|
}
|
|
|
|
//Characters emission
|
|
|
|
//OPTIMIZATION: specification uses only one type of character tokens (one token per character).
|
|
//This causes a huge memory overhead and a lot of unnecessary parser loops. parse5 uses 3 groups of characters.
|
|
//If we have a sequence of characters that belong to the same group, parser can process it
|
|
//as a single solid character token.
|
|
//So, there are 3 types of character tokens in parse5:
|
|
//1)NULL_CHARACTER_TOKEN - \u0000-character sequences (e.g. '\u0000\u0000\u0000')
|
|
//2)WHITESPACE_CHARACTER_TOKEN - any whitespace/new-line character sequences (e.g. '\n \r\t \f')
|
|
//3)CHARACTER_TOKEN - any character sequence which don't belong to groups 1 and 2 (e.g. 'abcdef1234@@#$%^')
|
|
_appendCharToCurrentCharacterToken(type, ch) {
|
|
if (this.currentCharacterToken && this.currentCharacterToken.type !== type) {
|
|
this._emitCurrentCharacterToken();
|
|
}
|
|
|
|
if (this.currentCharacterToken) {
|
|
this.currentCharacterToken.chars += ch;
|
|
} else {
|
|
this._createCharacterToken(type, ch);
|
|
}
|
|
}
|
|
|
|
_emitCodePoint(cp) {
|
|
let type = Tokenizer.CHARACTER_TOKEN;
|
|
|
|
if (isWhitespace(cp)) {
|
|
type = Tokenizer.WHITESPACE_CHARACTER_TOKEN;
|
|
} else if (cp === $.NULL) {
|
|
type = Tokenizer.NULL_CHARACTER_TOKEN;
|
|
}
|
|
|
|
this._appendCharToCurrentCharacterToken(type, toChar(cp));
|
|
}
|
|
|
|
_emitSeveralCodePoints(codePoints) {
|
|
for (let i = 0; i < codePoints.length; i++) {
|
|
this._emitCodePoint(codePoints[i]);
|
|
}
|
|
}
|
|
|
|
//NOTE: used then we emit character explicitly. This is always a non-whitespace and a non-null character.
|
|
//So we can avoid additional checks here.
|
|
_emitChars(ch) {
|
|
this._appendCharToCurrentCharacterToken(Tokenizer.CHARACTER_TOKEN, ch);
|
|
}
|
|
|
|
// Character reference helpers
|
|
_matchNamedCharacterReference(startCp) {
|
|
let result = null;
|
|
let excess = 1;
|
|
let i = findNamedEntityTreeBranch(0, startCp);
|
|
|
|
this.tempBuff.push(startCp);
|
|
|
|
while (i > -1) {
|
|
const current = neTree[i];
|
|
const inNode = current < MAX_BRANCH_MARKER_VALUE;
|
|
const nodeWithData = inNode && current & HAS_DATA_FLAG;
|
|
|
|
if (nodeWithData) {
|
|
//NOTE: we use greedy search, so we continue lookup at this point
|
|
result = current & DATA_DUPLET_FLAG ? [neTree[++i], neTree[++i]] : [neTree[++i]];
|
|
excess = 0;
|
|
}
|
|
|
|
const cp = this._consume();
|
|
|
|
this.tempBuff.push(cp);
|
|
excess++;
|
|
|
|
if (cp === $.EOF) {
|
|
break;
|
|
}
|
|
|
|
if (inNode) {
|
|
i = current & HAS_BRANCHES_FLAG ? findNamedEntityTreeBranch(i, cp) : -1;
|
|
} else {
|
|
i = cp === current ? ++i : -1;
|
|
}
|
|
}
|
|
|
|
while (excess--) {
|
|
this.tempBuff.pop();
|
|
this._unconsume();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
_isCharacterReferenceInAttribute() {
|
|
return (
|
|
this.returnState === ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE ||
|
|
this.returnState === ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE ||
|
|
this.returnState === ATTRIBUTE_VALUE_UNQUOTED_STATE
|
|
);
|
|
}
|
|
|
|
_isCharacterReferenceAttributeQuirk(withSemicolon) {
|
|
if (!withSemicolon && this._isCharacterReferenceInAttribute()) {
|
|
const nextCp = this._consume();
|
|
|
|
this._unconsume();
|
|
|
|
return nextCp === $.EQUALS_SIGN || isAsciiAlphaNumeric(nextCp);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
_flushCodePointsConsumedAsCharacterReference() {
|
|
if (this._isCharacterReferenceInAttribute()) {
|
|
for (let i = 0; i < this.tempBuff.length; i++) {
|
|
this.currentAttr.value += toChar(this.tempBuff[i]);
|
|
}
|
|
} else {
|
|
this._emitSeveralCodePoints(this.tempBuff);
|
|
}
|
|
|
|
this.tempBuff = [];
|
|
}
|
|
|
|
// State machine
|
|
|
|
// Data state
|
|
//------------------------------------------------------------------
|
|
[DATA_STATE](cp) {
|
|
this.preprocessor.dropParsedChunk();
|
|
|
|
if (cp === $.LESS_THAN_SIGN) {
|
|
this.state = TAG_OPEN_STATE;
|
|
} else if (cp === $.AMPERSAND) {
|
|
this.returnState = DATA_STATE;
|
|
this.state = CHARACTER_REFERENCE_STATE;
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this._emitCodePoint(cp);
|
|
} else if (cp === $.EOF) {
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._emitCodePoint(cp);
|
|
}
|
|
}
|
|
|
|
// RCDATA state
|
|
//------------------------------------------------------------------
|
|
[RCDATA_STATE](cp) {
|
|
this.preprocessor.dropParsedChunk();
|
|
|
|
if (cp === $.AMPERSAND) {
|
|
this.returnState = RCDATA_STATE;
|
|
this.state = CHARACTER_REFERENCE_STATE;
|
|
} else if (cp === $.LESS_THAN_SIGN) {
|
|
this.state = RCDATA_LESS_THAN_SIGN_STATE;
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
} else if (cp === $.EOF) {
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._emitCodePoint(cp);
|
|
}
|
|
}
|
|
|
|
// RAWTEXT state
|
|
//------------------------------------------------------------------
|
|
[RAWTEXT_STATE](cp) {
|
|
this.preprocessor.dropParsedChunk();
|
|
|
|
if (cp === $.LESS_THAN_SIGN) {
|
|
this.state = RAWTEXT_LESS_THAN_SIGN_STATE;
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
} else if (cp === $.EOF) {
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._emitCodePoint(cp);
|
|
}
|
|
}
|
|
|
|
// Script data state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_STATE](cp) {
|
|
this.preprocessor.dropParsedChunk();
|
|
|
|
if (cp === $.LESS_THAN_SIGN) {
|
|
this.state = SCRIPT_DATA_LESS_THAN_SIGN_STATE;
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
} else if (cp === $.EOF) {
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._emitCodePoint(cp);
|
|
}
|
|
}
|
|
|
|
// PLAINTEXT state
|
|
//------------------------------------------------------------------
|
|
[PLAINTEXT_STATE](cp) {
|
|
this.preprocessor.dropParsedChunk();
|
|
|
|
if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
} else if (cp === $.EOF) {
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._emitCodePoint(cp);
|
|
}
|
|
}
|
|
|
|
// Tag open state
|
|
//------------------------------------------------------------------
|
|
[TAG_OPEN_STATE](cp) {
|
|
if (cp === $.EXCLAMATION_MARK) {
|
|
this.state = MARKUP_DECLARATION_OPEN_STATE;
|
|
} else if (cp === $.SOLIDUS) {
|
|
this.state = END_TAG_OPEN_STATE;
|
|
} else if (isAsciiLetter(cp)) {
|
|
this._createStartTagToken();
|
|
this._reconsumeInState(TAG_NAME_STATE);
|
|
} else if (cp === $.QUESTION_MARK) {
|
|
this._err(ERR.unexpectedQuestionMarkInsteadOfTagName);
|
|
this._createCommentToken();
|
|
this._reconsumeInState(BOGUS_COMMENT_STATE);
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofBeforeTagName);
|
|
this._emitChars('<');
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._err(ERR.invalidFirstCharacterOfTagName);
|
|
this._emitChars('<');
|
|
this._reconsumeInState(DATA_STATE);
|
|
}
|
|
}
|
|
|
|
// End tag open state
|
|
//------------------------------------------------------------------
|
|
[END_TAG_OPEN_STATE](cp) {
|
|
if (isAsciiLetter(cp)) {
|
|
this._createEndTagToken();
|
|
this._reconsumeInState(TAG_NAME_STATE);
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._err(ERR.missingEndTagName);
|
|
this.state = DATA_STATE;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofBeforeTagName);
|
|
this._emitChars('</');
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._err(ERR.invalidFirstCharacterOfTagName);
|
|
this._createCommentToken();
|
|
this._reconsumeInState(BOGUS_COMMENT_STATE);
|
|
}
|
|
}
|
|
|
|
// Tag name state
|
|
//------------------------------------------------------------------
|
|
[TAG_NAME_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
this.state = BEFORE_ATTRIBUTE_NAME_STATE;
|
|
} else if (cp === $.SOLIDUS) {
|
|
this.state = SELF_CLOSING_START_TAG_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else if (isAsciiUpper(cp)) {
|
|
this.currentToken.tagName += toAsciiLowerChar(cp);
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.currentToken.tagName += unicode.REPLACEMENT_CHARACTER;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInTag);
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.currentToken.tagName += toChar(cp);
|
|
}
|
|
}
|
|
|
|
// RCDATA less-than sign state
|
|
//------------------------------------------------------------------
|
|
[RCDATA_LESS_THAN_SIGN_STATE](cp) {
|
|
if (cp === $.SOLIDUS) {
|
|
this.tempBuff = [];
|
|
this.state = RCDATA_END_TAG_OPEN_STATE;
|
|
} else {
|
|
this._emitChars('<');
|
|
this._reconsumeInState(RCDATA_STATE);
|
|
}
|
|
}
|
|
|
|
// RCDATA end tag open state
|
|
//------------------------------------------------------------------
|
|
[RCDATA_END_TAG_OPEN_STATE](cp) {
|
|
if (isAsciiLetter(cp)) {
|
|
this._createEndTagToken();
|
|
this._reconsumeInState(RCDATA_END_TAG_NAME_STATE);
|
|
} else {
|
|
this._emitChars('</');
|
|
this._reconsumeInState(RCDATA_STATE);
|
|
}
|
|
}
|
|
|
|
// RCDATA end tag name state
|
|
//------------------------------------------------------------------
|
|
[RCDATA_END_TAG_NAME_STATE](cp) {
|
|
if (isAsciiUpper(cp)) {
|
|
this.currentToken.tagName += toAsciiLowerChar(cp);
|
|
this.tempBuff.push(cp);
|
|
} else if (isAsciiLower(cp)) {
|
|
this.currentToken.tagName += toChar(cp);
|
|
this.tempBuff.push(cp);
|
|
} else {
|
|
if (this.lastStartTagName === this.currentToken.tagName) {
|
|
if (isWhitespace(cp)) {
|
|
this.state = BEFORE_ATTRIBUTE_NAME_STATE;
|
|
return;
|
|
}
|
|
|
|
if (cp === $.SOLIDUS) {
|
|
this.state = SELF_CLOSING_START_TAG_STATE;
|
|
return;
|
|
}
|
|
|
|
if (cp === $.GREATER_THAN_SIGN) {
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
return;
|
|
}
|
|
}
|
|
|
|
this._emitChars('</');
|
|
this._emitSeveralCodePoints(this.tempBuff);
|
|
this._reconsumeInState(RCDATA_STATE);
|
|
}
|
|
}
|
|
|
|
// RAWTEXT less-than sign state
|
|
//------------------------------------------------------------------
|
|
[RAWTEXT_LESS_THAN_SIGN_STATE](cp) {
|
|
if (cp === $.SOLIDUS) {
|
|
this.tempBuff = [];
|
|
this.state = RAWTEXT_END_TAG_OPEN_STATE;
|
|
} else {
|
|
this._emitChars('<');
|
|
this._reconsumeInState(RAWTEXT_STATE);
|
|
}
|
|
}
|
|
|
|
// RAWTEXT end tag open state
|
|
//------------------------------------------------------------------
|
|
[RAWTEXT_END_TAG_OPEN_STATE](cp) {
|
|
if (isAsciiLetter(cp)) {
|
|
this._createEndTagToken();
|
|
this._reconsumeInState(RAWTEXT_END_TAG_NAME_STATE);
|
|
} else {
|
|
this._emitChars('</');
|
|
this._reconsumeInState(RAWTEXT_STATE);
|
|
}
|
|
}
|
|
|
|
// RAWTEXT end tag name state
|
|
//------------------------------------------------------------------
|
|
[RAWTEXT_END_TAG_NAME_STATE](cp) {
|
|
if (isAsciiUpper(cp)) {
|
|
this.currentToken.tagName += toAsciiLowerChar(cp);
|
|
this.tempBuff.push(cp);
|
|
} else if (isAsciiLower(cp)) {
|
|
this.currentToken.tagName += toChar(cp);
|
|
this.tempBuff.push(cp);
|
|
} else {
|
|
if (this.lastStartTagName === this.currentToken.tagName) {
|
|
if (isWhitespace(cp)) {
|
|
this.state = BEFORE_ATTRIBUTE_NAME_STATE;
|
|
return;
|
|
}
|
|
|
|
if (cp === $.SOLIDUS) {
|
|
this.state = SELF_CLOSING_START_TAG_STATE;
|
|
return;
|
|
}
|
|
|
|
if (cp === $.GREATER_THAN_SIGN) {
|
|
this._emitCurrentToken();
|
|
this.state = DATA_STATE;
|
|
return;
|
|
}
|
|
}
|
|
|
|
this._emitChars('</');
|
|
this._emitSeveralCodePoints(this.tempBuff);
|
|
this._reconsumeInState(RAWTEXT_STATE);
|
|
}
|
|
}
|
|
|
|
// Script data less-than sign state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_LESS_THAN_SIGN_STATE](cp) {
|
|
if (cp === $.SOLIDUS) {
|
|
this.tempBuff = [];
|
|
this.state = SCRIPT_DATA_END_TAG_OPEN_STATE;
|
|
} else if (cp === $.EXCLAMATION_MARK) {
|
|
this.state = SCRIPT_DATA_ESCAPE_START_STATE;
|
|
this._emitChars('<!');
|
|
} else {
|
|
this._emitChars('<');
|
|
this._reconsumeInState(SCRIPT_DATA_STATE);
|
|
}
|
|
}
|
|
|
|
// Script data end tag open state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_END_TAG_OPEN_STATE](cp) {
|
|
if (isAsciiLetter(cp)) {
|
|
this._createEndTagToken();
|
|
this._reconsumeInState(SCRIPT_DATA_END_TAG_NAME_STATE);
|
|
} else {
|
|
this._emitChars('</');
|
|
this._reconsumeInState(SCRIPT_DATA_STATE);
|
|
}
|
|
}
|
|
|
|
// Script data end tag name state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_END_TAG_NAME_STATE](cp) {
|
|
if (isAsciiUpper(cp)) {
|
|
this.currentToken.tagName += toAsciiLowerChar(cp);
|
|
this.tempBuff.push(cp);
|
|
} else if (isAsciiLower(cp)) {
|
|
this.currentToken.tagName += toChar(cp);
|
|
this.tempBuff.push(cp);
|
|
} else {
|
|
if (this.lastStartTagName === this.currentToken.tagName) {
|
|
if (isWhitespace(cp)) {
|
|
this.state = BEFORE_ATTRIBUTE_NAME_STATE;
|
|
return;
|
|
} else if (cp === $.SOLIDUS) {
|
|
this.state = SELF_CLOSING_START_TAG_STATE;
|
|
return;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._emitCurrentToken();
|
|
this.state = DATA_STATE;
|
|
return;
|
|
}
|
|
}
|
|
|
|
this._emitChars('</');
|
|
this._emitSeveralCodePoints(this.tempBuff);
|
|
this._reconsumeInState(SCRIPT_DATA_STATE);
|
|
}
|
|
}
|
|
|
|
// Script data escape start state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_ESCAPE_START_STATE](cp) {
|
|
if (cp === $.HYPHEN_MINUS) {
|
|
this.state = SCRIPT_DATA_ESCAPE_START_DASH_STATE;
|
|
this._emitChars('-');
|
|
} else {
|
|
this._reconsumeInState(SCRIPT_DATA_STATE);
|
|
}
|
|
}
|
|
|
|
// Script data escape start dash state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_ESCAPE_START_DASH_STATE](cp) {
|
|
if (cp === $.HYPHEN_MINUS) {
|
|
this.state = SCRIPT_DATA_ESCAPED_DASH_DASH_STATE;
|
|
this._emitChars('-');
|
|
} else {
|
|
this._reconsumeInState(SCRIPT_DATA_STATE);
|
|
}
|
|
}
|
|
|
|
// Script data escaped state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_ESCAPED_STATE](cp) {
|
|
if (cp === $.HYPHEN_MINUS) {
|
|
this.state = SCRIPT_DATA_ESCAPED_DASH_STATE;
|
|
this._emitChars('-');
|
|
} else if (cp === $.LESS_THAN_SIGN) {
|
|
this.state = SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE;
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInScriptHtmlCommentLikeText);
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._emitCodePoint(cp);
|
|
}
|
|
}
|
|
|
|
// Script data escaped dash state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_ESCAPED_DASH_STATE](cp) {
|
|
if (cp === $.HYPHEN_MINUS) {
|
|
this.state = SCRIPT_DATA_ESCAPED_DASH_DASH_STATE;
|
|
this._emitChars('-');
|
|
} else if (cp === $.LESS_THAN_SIGN) {
|
|
this.state = SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE;
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.state = SCRIPT_DATA_ESCAPED_STATE;
|
|
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInScriptHtmlCommentLikeText);
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.state = SCRIPT_DATA_ESCAPED_STATE;
|
|
this._emitCodePoint(cp);
|
|
}
|
|
}
|
|
|
|
// Script data escaped dash dash state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_ESCAPED_DASH_DASH_STATE](cp) {
|
|
if (cp === $.HYPHEN_MINUS) {
|
|
this._emitChars('-');
|
|
} else if (cp === $.LESS_THAN_SIGN) {
|
|
this.state = SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this.state = SCRIPT_DATA_STATE;
|
|
this._emitChars('>');
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.state = SCRIPT_DATA_ESCAPED_STATE;
|
|
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInScriptHtmlCommentLikeText);
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.state = SCRIPT_DATA_ESCAPED_STATE;
|
|
this._emitCodePoint(cp);
|
|
}
|
|
}
|
|
|
|
// Script data escaped less-than sign state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE](cp) {
|
|
if (cp === $.SOLIDUS) {
|
|
this.tempBuff = [];
|
|
this.state = SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE;
|
|
} else if (isAsciiLetter(cp)) {
|
|
this.tempBuff = [];
|
|
this._emitChars('<');
|
|
this._reconsumeInState(SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE);
|
|
} else {
|
|
this._emitChars('<');
|
|
this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
|
|
}
|
|
}
|
|
|
|
// Script data escaped end tag open state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE](cp) {
|
|
if (isAsciiLetter(cp)) {
|
|
this._createEndTagToken();
|
|
this._reconsumeInState(SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE);
|
|
} else {
|
|
this._emitChars('</');
|
|
this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
|
|
}
|
|
}
|
|
|
|
// Script data escaped end tag name state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE](cp) {
|
|
if (isAsciiUpper(cp)) {
|
|
this.currentToken.tagName += toAsciiLowerChar(cp);
|
|
this.tempBuff.push(cp);
|
|
} else if (isAsciiLower(cp)) {
|
|
this.currentToken.tagName += toChar(cp);
|
|
this.tempBuff.push(cp);
|
|
} else {
|
|
if (this.lastStartTagName === this.currentToken.tagName) {
|
|
if (isWhitespace(cp)) {
|
|
this.state = BEFORE_ATTRIBUTE_NAME_STATE;
|
|
return;
|
|
}
|
|
|
|
if (cp === $.SOLIDUS) {
|
|
this.state = SELF_CLOSING_START_TAG_STATE;
|
|
return;
|
|
}
|
|
|
|
if (cp === $.GREATER_THAN_SIGN) {
|
|
this._emitCurrentToken();
|
|
this.state = DATA_STATE;
|
|
return;
|
|
}
|
|
}
|
|
|
|
this._emitChars('</');
|
|
this._emitSeveralCodePoints(this.tempBuff);
|
|
this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
|
|
}
|
|
}
|
|
|
|
// Script data double escape start state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE](cp) {
|
|
if (isWhitespace(cp) || cp === $.SOLIDUS || cp === $.GREATER_THAN_SIGN) {
|
|
this.state = this._isTempBufferEqualToScriptString()
|
|
? SCRIPT_DATA_DOUBLE_ESCAPED_STATE
|
|
: SCRIPT_DATA_ESCAPED_STATE;
|
|
this._emitCodePoint(cp);
|
|
} else if (isAsciiUpper(cp)) {
|
|
this.tempBuff.push(toAsciiLowerCodePoint(cp));
|
|
this._emitCodePoint(cp);
|
|
} else if (isAsciiLower(cp)) {
|
|
this.tempBuff.push(cp);
|
|
this._emitCodePoint(cp);
|
|
} else {
|
|
this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
|
|
}
|
|
}
|
|
|
|
// Script data double escaped state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_DOUBLE_ESCAPED_STATE](cp) {
|
|
if (cp === $.HYPHEN_MINUS) {
|
|
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE;
|
|
this._emitChars('-');
|
|
} else if (cp === $.LESS_THAN_SIGN) {
|
|
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE;
|
|
this._emitChars('<');
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInScriptHtmlCommentLikeText);
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._emitCodePoint(cp);
|
|
}
|
|
}
|
|
|
|
// Script data double escaped dash state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE](cp) {
|
|
if (cp === $.HYPHEN_MINUS) {
|
|
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE;
|
|
this._emitChars('-');
|
|
} else if (cp === $.LESS_THAN_SIGN) {
|
|
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE;
|
|
this._emitChars('<');
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
|
|
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInScriptHtmlCommentLikeText);
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
|
|
this._emitCodePoint(cp);
|
|
}
|
|
}
|
|
|
|
// Script data double escaped dash dash state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE](cp) {
|
|
if (cp === $.HYPHEN_MINUS) {
|
|
this._emitChars('-');
|
|
} else if (cp === $.LESS_THAN_SIGN) {
|
|
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE;
|
|
this._emitChars('<');
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this.state = SCRIPT_DATA_STATE;
|
|
this._emitChars('>');
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
|
|
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInScriptHtmlCommentLikeText);
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
|
|
this._emitCodePoint(cp);
|
|
}
|
|
}
|
|
|
|
// Script data double escaped less-than sign state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE](cp) {
|
|
if (cp === $.SOLIDUS) {
|
|
this.tempBuff = [];
|
|
this.state = SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE;
|
|
this._emitChars('/');
|
|
} else {
|
|
this._reconsumeInState(SCRIPT_DATA_DOUBLE_ESCAPED_STATE);
|
|
}
|
|
}
|
|
|
|
// Script data double escape end state
|
|
//------------------------------------------------------------------
|
|
[SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE](cp) {
|
|
if (isWhitespace(cp) || cp === $.SOLIDUS || cp === $.GREATER_THAN_SIGN) {
|
|
this.state = this._isTempBufferEqualToScriptString()
|
|
? SCRIPT_DATA_ESCAPED_STATE
|
|
: SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
|
|
|
|
this._emitCodePoint(cp);
|
|
} else if (isAsciiUpper(cp)) {
|
|
this.tempBuff.push(toAsciiLowerCodePoint(cp));
|
|
this._emitCodePoint(cp);
|
|
} else if (isAsciiLower(cp)) {
|
|
this.tempBuff.push(cp);
|
|
this._emitCodePoint(cp);
|
|
} else {
|
|
this._reconsumeInState(SCRIPT_DATA_DOUBLE_ESCAPED_STATE);
|
|
}
|
|
}
|
|
|
|
// Before attribute name state
|
|
//------------------------------------------------------------------
|
|
[BEFORE_ATTRIBUTE_NAME_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
return;
|
|
}
|
|
|
|
if (cp === $.SOLIDUS || cp === $.GREATER_THAN_SIGN || cp === $.EOF) {
|
|
this._reconsumeInState(AFTER_ATTRIBUTE_NAME_STATE);
|
|
} else if (cp === $.EQUALS_SIGN) {
|
|
this._err(ERR.unexpectedEqualsSignBeforeAttributeName);
|
|
this._createAttr('=');
|
|
this.state = ATTRIBUTE_NAME_STATE;
|
|
} else {
|
|
this._createAttr('');
|
|
this._reconsumeInState(ATTRIBUTE_NAME_STATE);
|
|
}
|
|
}
|
|
|
|
// Attribute name state
|
|
//------------------------------------------------------------------
|
|
[ATTRIBUTE_NAME_STATE](cp) {
|
|
if (isWhitespace(cp) || cp === $.SOLIDUS || cp === $.GREATER_THAN_SIGN || cp === $.EOF) {
|
|
this._leaveAttrName(AFTER_ATTRIBUTE_NAME_STATE);
|
|
this._unconsume();
|
|
} else if (cp === $.EQUALS_SIGN) {
|
|
this._leaveAttrName(BEFORE_ATTRIBUTE_VALUE_STATE);
|
|
} else if (isAsciiUpper(cp)) {
|
|
this.currentAttr.name += toAsciiLowerChar(cp);
|
|
} else if (cp === $.QUOTATION_MARK || cp === $.APOSTROPHE || cp === $.LESS_THAN_SIGN) {
|
|
this._err(ERR.unexpectedCharacterInAttributeName);
|
|
this.currentAttr.name += toChar(cp);
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.currentAttr.name += unicode.REPLACEMENT_CHARACTER;
|
|
} else {
|
|
this.currentAttr.name += toChar(cp);
|
|
}
|
|
}
|
|
|
|
// After attribute name state
|
|
//------------------------------------------------------------------
|
|
[AFTER_ATTRIBUTE_NAME_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
return;
|
|
}
|
|
|
|
if (cp === $.SOLIDUS) {
|
|
this.state = SELF_CLOSING_START_TAG_STATE;
|
|
} else if (cp === $.EQUALS_SIGN) {
|
|
this.state = BEFORE_ATTRIBUTE_VALUE_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInTag);
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._createAttr('');
|
|
this._reconsumeInState(ATTRIBUTE_NAME_STATE);
|
|
}
|
|
}
|
|
|
|
// Before attribute value state
|
|
//------------------------------------------------------------------
|
|
[BEFORE_ATTRIBUTE_VALUE_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
return;
|
|
}
|
|
|
|
if (cp === $.QUOTATION_MARK) {
|
|
this.state = ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE;
|
|
} else if (cp === $.APOSTROPHE) {
|
|
this.state = ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._err(ERR.missingAttributeValue);
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else {
|
|
this._reconsumeInState(ATTRIBUTE_VALUE_UNQUOTED_STATE);
|
|
}
|
|
}
|
|
|
|
// Attribute value (double-quoted) state
|
|
//------------------------------------------------------------------
|
|
[ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE](cp) {
|
|
if (cp === $.QUOTATION_MARK) {
|
|
this.state = AFTER_ATTRIBUTE_VALUE_QUOTED_STATE;
|
|
} else if (cp === $.AMPERSAND) {
|
|
this.returnState = ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE;
|
|
this.state = CHARACTER_REFERENCE_STATE;
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.currentAttr.value += unicode.REPLACEMENT_CHARACTER;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInTag);
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.currentAttr.value += toChar(cp);
|
|
}
|
|
}
|
|
|
|
// Attribute value (single-quoted) state
|
|
//------------------------------------------------------------------
|
|
[ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE](cp) {
|
|
if (cp === $.APOSTROPHE) {
|
|
this.state = AFTER_ATTRIBUTE_VALUE_QUOTED_STATE;
|
|
} else if (cp === $.AMPERSAND) {
|
|
this.returnState = ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE;
|
|
this.state = CHARACTER_REFERENCE_STATE;
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.currentAttr.value += unicode.REPLACEMENT_CHARACTER;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInTag);
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.currentAttr.value += toChar(cp);
|
|
}
|
|
}
|
|
|
|
// Attribute value (unquoted) state
|
|
//------------------------------------------------------------------
|
|
[ATTRIBUTE_VALUE_UNQUOTED_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
this._leaveAttrValue(BEFORE_ATTRIBUTE_NAME_STATE);
|
|
} else if (cp === $.AMPERSAND) {
|
|
this.returnState = ATTRIBUTE_VALUE_UNQUOTED_STATE;
|
|
this.state = CHARACTER_REFERENCE_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._leaveAttrValue(DATA_STATE);
|
|
this._emitCurrentToken();
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.currentAttr.value += unicode.REPLACEMENT_CHARACTER;
|
|
} else if (
|
|
cp === $.QUOTATION_MARK ||
|
|
cp === $.APOSTROPHE ||
|
|
cp === $.LESS_THAN_SIGN ||
|
|
cp === $.EQUALS_SIGN ||
|
|
cp === $.GRAVE_ACCENT
|
|
) {
|
|
this._err(ERR.unexpectedCharacterInUnquotedAttributeValue);
|
|
this.currentAttr.value += toChar(cp);
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInTag);
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.currentAttr.value += toChar(cp);
|
|
}
|
|
}
|
|
|
|
// After attribute value (quoted) state
|
|
//------------------------------------------------------------------
|
|
[AFTER_ATTRIBUTE_VALUE_QUOTED_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
this._leaveAttrValue(BEFORE_ATTRIBUTE_NAME_STATE);
|
|
} else if (cp === $.SOLIDUS) {
|
|
this._leaveAttrValue(SELF_CLOSING_START_TAG_STATE);
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._leaveAttrValue(DATA_STATE);
|
|
this._emitCurrentToken();
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInTag);
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._err(ERR.missingWhitespaceBetweenAttributes);
|
|
this._reconsumeInState(BEFORE_ATTRIBUTE_NAME_STATE);
|
|
}
|
|
}
|
|
|
|
// Self-closing start tag state
|
|
//------------------------------------------------------------------
|
|
[SELF_CLOSING_START_TAG_STATE](cp) {
|
|
if (cp === $.GREATER_THAN_SIGN) {
|
|
this.currentToken.selfClosing = true;
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInTag);
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._err(ERR.unexpectedSolidusInTag);
|
|
this._reconsumeInState(BEFORE_ATTRIBUTE_NAME_STATE);
|
|
}
|
|
}
|
|
|
|
// Bogus comment state
|
|
//------------------------------------------------------------------
|
|
[BOGUS_COMMENT_STATE](cp) {
|
|
if (cp === $.GREATER_THAN_SIGN) {
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else if (cp === $.EOF) {
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.currentToken.data += unicode.REPLACEMENT_CHARACTER;
|
|
} else {
|
|
this.currentToken.data += toChar(cp);
|
|
}
|
|
}
|
|
|
|
// Markup declaration open state
|
|
//------------------------------------------------------------------
|
|
[MARKUP_DECLARATION_OPEN_STATE](cp) {
|
|
if (this._consumeSequenceIfMatch($$.DASH_DASH_STRING, cp, true)) {
|
|
this._createCommentToken();
|
|
this.state = COMMENT_START_STATE;
|
|
} else if (this._consumeSequenceIfMatch($$.DOCTYPE_STRING, cp, false)) {
|
|
this.state = DOCTYPE_STATE;
|
|
} else if (this._consumeSequenceIfMatch($$.CDATA_START_STRING, cp, true)) {
|
|
if (this.allowCDATA) {
|
|
this.state = CDATA_SECTION_STATE;
|
|
} else {
|
|
this._err(ERR.cdataInHtmlContent);
|
|
this._createCommentToken();
|
|
this.currentToken.data = '[CDATA[';
|
|
this.state = BOGUS_COMMENT_STATE;
|
|
}
|
|
}
|
|
|
|
//NOTE: sequence lookup can be abrupted by hibernation. In that case lookup
|
|
//results are no longer valid and we will need to start over.
|
|
else if (!this._ensureHibernation()) {
|
|
this._err(ERR.incorrectlyOpenedComment);
|
|
this._createCommentToken();
|
|
this._reconsumeInState(BOGUS_COMMENT_STATE);
|
|
}
|
|
}
|
|
|
|
// Comment start state
|
|
//------------------------------------------------------------------
|
|
[COMMENT_START_STATE](cp) {
|
|
if (cp === $.HYPHEN_MINUS) {
|
|
this.state = COMMENT_START_DASH_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._err(ERR.abruptClosingOfEmptyComment);
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else {
|
|
this._reconsumeInState(COMMENT_STATE);
|
|
}
|
|
}
|
|
|
|
// Comment start dash state
|
|
//------------------------------------------------------------------
|
|
[COMMENT_START_DASH_STATE](cp) {
|
|
if (cp === $.HYPHEN_MINUS) {
|
|
this.state = COMMENT_END_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._err(ERR.abruptClosingOfEmptyComment);
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInComment);
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.currentToken.data += '-';
|
|
this._reconsumeInState(COMMENT_STATE);
|
|
}
|
|
}
|
|
|
|
// Comment state
|
|
//------------------------------------------------------------------
|
|
[COMMENT_STATE](cp) {
|
|
if (cp === $.HYPHEN_MINUS) {
|
|
this.state = COMMENT_END_DASH_STATE;
|
|
} else if (cp === $.LESS_THAN_SIGN) {
|
|
this.currentToken.data += '<';
|
|
this.state = COMMENT_LESS_THAN_SIGN_STATE;
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.currentToken.data += unicode.REPLACEMENT_CHARACTER;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInComment);
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.currentToken.data += toChar(cp);
|
|
}
|
|
}
|
|
|
|
// Comment less-than sign state
|
|
//------------------------------------------------------------------
|
|
[COMMENT_LESS_THAN_SIGN_STATE](cp) {
|
|
if (cp === $.EXCLAMATION_MARK) {
|
|
this.currentToken.data += '!';
|
|
this.state = COMMENT_LESS_THAN_SIGN_BANG_STATE;
|
|
} else if (cp === $.LESS_THAN_SIGN) {
|
|
this.currentToken.data += '!';
|
|
} else {
|
|
this._reconsumeInState(COMMENT_STATE);
|
|
}
|
|
}
|
|
|
|
// Comment less-than sign bang state
|
|
//------------------------------------------------------------------
|
|
[COMMENT_LESS_THAN_SIGN_BANG_STATE](cp) {
|
|
if (cp === $.HYPHEN_MINUS) {
|
|
this.state = COMMENT_LESS_THAN_SIGN_BANG_DASH_STATE;
|
|
} else {
|
|
this._reconsumeInState(COMMENT_STATE);
|
|
}
|
|
}
|
|
|
|
// Comment less-than sign bang dash state
|
|
//------------------------------------------------------------------
|
|
[COMMENT_LESS_THAN_SIGN_BANG_DASH_STATE](cp) {
|
|
if (cp === $.HYPHEN_MINUS) {
|
|
this.state = COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH_STATE;
|
|
} else {
|
|
this._reconsumeInState(COMMENT_END_DASH_STATE);
|
|
}
|
|
}
|
|
|
|
// Comment less-than sign bang dash dash state
|
|
//------------------------------------------------------------------
|
|
[COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH_STATE](cp) {
|
|
if (cp !== $.GREATER_THAN_SIGN && cp !== $.EOF) {
|
|
this._err(ERR.nestedComment);
|
|
}
|
|
|
|
this._reconsumeInState(COMMENT_END_STATE);
|
|
}
|
|
|
|
// Comment end dash state
|
|
//------------------------------------------------------------------
|
|
[COMMENT_END_DASH_STATE](cp) {
|
|
if (cp === $.HYPHEN_MINUS) {
|
|
this.state = COMMENT_END_STATE;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInComment);
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.currentToken.data += '-';
|
|
this._reconsumeInState(COMMENT_STATE);
|
|
}
|
|
}
|
|
|
|
// Comment end state
|
|
//------------------------------------------------------------------
|
|
[COMMENT_END_STATE](cp) {
|
|
if (cp === $.GREATER_THAN_SIGN) {
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else if (cp === $.EXCLAMATION_MARK) {
|
|
this.state = COMMENT_END_BANG_STATE;
|
|
} else if (cp === $.HYPHEN_MINUS) {
|
|
this.currentToken.data += '-';
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInComment);
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.currentToken.data += '--';
|
|
this._reconsumeInState(COMMENT_STATE);
|
|
}
|
|
}
|
|
|
|
// Comment end bang state
|
|
//------------------------------------------------------------------
|
|
[COMMENT_END_BANG_STATE](cp) {
|
|
if (cp === $.HYPHEN_MINUS) {
|
|
this.currentToken.data += '--!';
|
|
this.state = COMMENT_END_DASH_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._err(ERR.incorrectlyClosedComment);
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInComment);
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.currentToken.data += '--!';
|
|
this._reconsumeInState(COMMENT_STATE);
|
|
}
|
|
}
|
|
|
|
// DOCTYPE state
|
|
//------------------------------------------------------------------
|
|
[DOCTYPE_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
this.state = BEFORE_DOCTYPE_NAME_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._reconsumeInState(BEFORE_DOCTYPE_NAME_STATE);
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInDoctype);
|
|
this._createDoctypeToken(null);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._err(ERR.missingWhitespaceBeforeDoctypeName);
|
|
this._reconsumeInState(BEFORE_DOCTYPE_NAME_STATE);
|
|
}
|
|
}
|
|
|
|
// Before DOCTYPE name state
|
|
//------------------------------------------------------------------
|
|
[BEFORE_DOCTYPE_NAME_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
return;
|
|
}
|
|
|
|
if (isAsciiUpper(cp)) {
|
|
this._createDoctypeToken(toAsciiLowerChar(cp));
|
|
this.state = DOCTYPE_NAME_STATE;
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this._createDoctypeToken(unicode.REPLACEMENT_CHARACTER);
|
|
this.state = DOCTYPE_NAME_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._err(ERR.missingDoctypeName);
|
|
this._createDoctypeToken(null);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this.state = DATA_STATE;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInDoctype);
|
|
this._createDoctypeToken(null);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._createDoctypeToken(toChar(cp));
|
|
this.state = DOCTYPE_NAME_STATE;
|
|
}
|
|
}
|
|
|
|
// DOCTYPE name state
|
|
//------------------------------------------------------------------
|
|
[DOCTYPE_NAME_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
this.state = AFTER_DOCTYPE_NAME_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else if (isAsciiUpper(cp)) {
|
|
this.currentToken.name += toAsciiLowerChar(cp);
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.currentToken.name += unicode.REPLACEMENT_CHARACTER;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInDoctype);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.currentToken.name += toChar(cp);
|
|
}
|
|
}
|
|
|
|
// After DOCTYPE name state
|
|
//------------------------------------------------------------------
|
|
[AFTER_DOCTYPE_NAME_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
return;
|
|
}
|
|
|
|
if (cp === $.GREATER_THAN_SIGN) {
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInDoctype);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else if (this._consumeSequenceIfMatch($$.PUBLIC_STRING, cp, false)) {
|
|
this.state = AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE;
|
|
} else if (this._consumeSequenceIfMatch($$.SYSTEM_STRING, cp, false)) {
|
|
this.state = AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE;
|
|
}
|
|
//NOTE: sequence lookup can be abrupted by hibernation. In that case lookup
|
|
//results are no longer valid and we will need to start over.
|
|
else if (!this._ensureHibernation()) {
|
|
this._err(ERR.invalidCharacterSequenceAfterDoctypeName);
|
|
this.currentToken.forceQuirks = true;
|
|
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
}
|
|
}
|
|
|
|
// After DOCTYPE public keyword state
|
|
//------------------------------------------------------------------
|
|
[AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
this.state = BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE;
|
|
} else if (cp === $.QUOTATION_MARK) {
|
|
this._err(ERR.missingWhitespaceAfterDoctypePublicKeyword);
|
|
this.currentToken.publicId = '';
|
|
this.state = DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE;
|
|
} else if (cp === $.APOSTROPHE) {
|
|
this._err(ERR.missingWhitespaceAfterDoctypePublicKeyword);
|
|
this.currentToken.publicId = '';
|
|
this.state = DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._err(ERR.missingDoctypePublicIdentifier);
|
|
this.currentToken.forceQuirks = true;
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInDoctype);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._err(ERR.missingQuoteBeforeDoctypePublicIdentifier);
|
|
this.currentToken.forceQuirks = true;
|
|
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
}
|
|
}
|
|
|
|
// Before DOCTYPE public identifier state
|
|
//------------------------------------------------------------------
|
|
[BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
return;
|
|
}
|
|
|
|
if (cp === $.QUOTATION_MARK) {
|
|
this.currentToken.publicId = '';
|
|
this.state = DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE;
|
|
} else if (cp === $.APOSTROPHE) {
|
|
this.currentToken.publicId = '';
|
|
this.state = DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._err(ERR.missingDoctypePublicIdentifier);
|
|
this.currentToken.forceQuirks = true;
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInDoctype);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._err(ERR.missingQuoteBeforeDoctypePublicIdentifier);
|
|
this.currentToken.forceQuirks = true;
|
|
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
}
|
|
}
|
|
|
|
// DOCTYPE public identifier (double-quoted) state
|
|
//------------------------------------------------------------------
|
|
[DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE](cp) {
|
|
if (cp === $.QUOTATION_MARK) {
|
|
this.state = AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE;
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.currentToken.publicId += unicode.REPLACEMENT_CHARACTER;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._err(ERR.abruptDoctypePublicIdentifier);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this.state = DATA_STATE;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInDoctype);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.currentToken.publicId += toChar(cp);
|
|
}
|
|
}
|
|
|
|
// DOCTYPE public identifier (single-quoted) state
|
|
//------------------------------------------------------------------
|
|
[DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE](cp) {
|
|
if (cp === $.APOSTROPHE) {
|
|
this.state = AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE;
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.currentToken.publicId += unicode.REPLACEMENT_CHARACTER;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._err(ERR.abruptDoctypePublicIdentifier);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this.state = DATA_STATE;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInDoctype);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.currentToken.publicId += toChar(cp);
|
|
}
|
|
}
|
|
|
|
// After DOCTYPE public identifier state
|
|
//------------------------------------------------------------------
|
|
[AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
this.state = BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else if (cp === $.QUOTATION_MARK) {
|
|
this._err(ERR.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers);
|
|
this.currentToken.systemId = '';
|
|
this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
|
|
} else if (cp === $.APOSTROPHE) {
|
|
this._err(ERR.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers);
|
|
this.currentToken.systemId = '';
|
|
this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInDoctype);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
|
|
this.currentToken.forceQuirks = true;
|
|
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
}
|
|
}
|
|
|
|
// Between DOCTYPE public and system identifiers state
|
|
//------------------------------------------------------------------
|
|
[BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
return;
|
|
}
|
|
|
|
if (cp === $.GREATER_THAN_SIGN) {
|
|
this._emitCurrentToken();
|
|
this.state = DATA_STATE;
|
|
} else if (cp === $.QUOTATION_MARK) {
|
|
this.currentToken.systemId = '';
|
|
this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
|
|
} else if (cp === $.APOSTROPHE) {
|
|
this.currentToken.systemId = '';
|
|
this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInDoctype);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
|
|
this.currentToken.forceQuirks = true;
|
|
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
}
|
|
}
|
|
|
|
// After DOCTYPE system keyword state
|
|
//------------------------------------------------------------------
|
|
[AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
this.state = BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
|
|
} else if (cp === $.QUOTATION_MARK) {
|
|
this._err(ERR.missingWhitespaceAfterDoctypeSystemKeyword);
|
|
this.currentToken.systemId = '';
|
|
this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
|
|
} else if (cp === $.APOSTROPHE) {
|
|
this._err(ERR.missingWhitespaceAfterDoctypeSystemKeyword);
|
|
this.currentToken.systemId = '';
|
|
this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._err(ERR.missingDoctypeSystemIdentifier);
|
|
this.currentToken.forceQuirks = true;
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInDoctype);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
|
|
this.currentToken.forceQuirks = true;
|
|
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
}
|
|
}
|
|
|
|
// Before DOCTYPE system identifier state
|
|
//------------------------------------------------------------------
|
|
[BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
return;
|
|
}
|
|
|
|
if (cp === $.QUOTATION_MARK) {
|
|
this.currentToken.systemId = '';
|
|
this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
|
|
} else if (cp === $.APOSTROPHE) {
|
|
this.currentToken.systemId = '';
|
|
this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._err(ERR.missingDoctypeSystemIdentifier);
|
|
this.currentToken.forceQuirks = true;
|
|
this.state = DATA_STATE;
|
|
this._emitCurrentToken();
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInDoctype);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
|
|
this.currentToken.forceQuirks = true;
|
|
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
}
|
|
}
|
|
|
|
// DOCTYPE system identifier (double-quoted) state
|
|
//------------------------------------------------------------------
|
|
[DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE](cp) {
|
|
if (cp === $.QUOTATION_MARK) {
|
|
this.state = AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.currentToken.systemId += unicode.REPLACEMENT_CHARACTER;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._err(ERR.abruptDoctypeSystemIdentifier);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this.state = DATA_STATE;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInDoctype);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.currentToken.systemId += toChar(cp);
|
|
}
|
|
}
|
|
|
|
// DOCTYPE system identifier (single-quoted) state
|
|
//------------------------------------------------------------------
|
|
[DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE](cp) {
|
|
if (cp === $.APOSTROPHE) {
|
|
this.state = AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
this.currentToken.systemId += unicode.REPLACEMENT_CHARACTER;
|
|
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
this._err(ERR.abruptDoctypeSystemIdentifier);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this.state = DATA_STATE;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInDoctype);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this.currentToken.systemId += toChar(cp);
|
|
}
|
|
}
|
|
|
|
// After DOCTYPE system identifier state
|
|
//------------------------------------------------------------------
|
|
[AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE](cp) {
|
|
if (isWhitespace(cp)) {
|
|
return;
|
|
}
|
|
|
|
if (cp === $.GREATER_THAN_SIGN) {
|
|
this._emitCurrentToken();
|
|
this.state = DATA_STATE;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInDoctype);
|
|
this.currentToken.forceQuirks = true;
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._err(ERR.unexpectedCharacterAfterDoctypeSystemIdentifier);
|
|
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
}
|
|
}
|
|
|
|
// Bogus DOCTYPE state
|
|
//------------------------------------------------------------------
|
|
[BOGUS_DOCTYPE_STATE](cp) {
|
|
if (cp === $.GREATER_THAN_SIGN) {
|
|
this._emitCurrentToken();
|
|
this.state = DATA_STATE;
|
|
} else if (cp === $.NULL) {
|
|
this._err(ERR.unexpectedNullCharacter);
|
|
} else if (cp === $.EOF) {
|
|
this._emitCurrentToken();
|
|
this._emitEOFToken();
|
|
}
|
|
}
|
|
|
|
// CDATA section state
|
|
//------------------------------------------------------------------
|
|
[CDATA_SECTION_STATE](cp) {
|
|
if (cp === $.RIGHT_SQUARE_BRACKET) {
|
|
this.state = CDATA_SECTION_BRACKET_STATE;
|
|
} else if (cp === $.EOF) {
|
|
this._err(ERR.eofInCdata);
|
|
this._emitEOFToken();
|
|
} else {
|
|
this._emitCodePoint(cp);
|
|
}
|
|
}
|
|
|
|
// CDATA section bracket state
|
|
//------------------------------------------------------------------
|
|
[CDATA_SECTION_BRACKET_STATE](cp) {
|
|
if (cp === $.RIGHT_SQUARE_BRACKET) {
|
|
this.state = CDATA_SECTION_END_STATE;
|
|
} else {
|
|
this._emitChars(']');
|
|
this._reconsumeInState(CDATA_SECTION_STATE);
|
|
}
|
|
}
|
|
|
|
// CDATA section end state
|
|
//------------------------------------------------------------------
|
|
[CDATA_SECTION_END_STATE](cp) {
|
|
if (cp === $.GREATER_THAN_SIGN) {
|
|
this.state = DATA_STATE;
|
|
} else if (cp === $.RIGHT_SQUARE_BRACKET) {
|
|
this._emitChars(']');
|
|
} else {
|
|
this._emitChars(']]');
|
|
this._reconsumeInState(CDATA_SECTION_STATE);
|
|
}
|
|
}
|
|
|
|
// Character reference state
|
|
//------------------------------------------------------------------
|
|
[CHARACTER_REFERENCE_STATE](cp) {
|
|
this.tempBuff = [$.AMPERSAND];
|
|
|
|
if (cp === $.NUMBER_SIGN) {
|
|
this.tempBuff.push(cp);
|
|
this.state = NUMERIC_CHARACTER_REFERENCE_STATE;
|
|
} else if (isAsciiAlphaNumeric(cp)) {
|
|
this._reconsumeInState(NAMED_CHARACTER_REFERENCE_STATE);
|
|
} else {
|
|
this._flushCodePointsConsumedAsCharacterReference();
|
|
this._reconsumeInState(this.returnState);
|
|
}
|
|
}
|
|
|
|
// Named character reference state
|
|
//------------------------------------------------------------------
|
|
[NAMED_CHARACTER_REFERENCE_STATE](cp) {
|
|
const matchResult = this._matchNamedCharacterReference(cp);
|
|
|
|
//NOTE: matching can be abrupted by hibernation. In that case match
|
|
//results are no longer valid and we will need to start over.
|
|
if (this._ensureHibernation()) {
|
|
this.tempBuff = [$.AMPERSAND];
|
|
} else if (matchResult) {
|
|
const withSemicolon = this.tempBuff[this.tempBuff.length - 1] === $.SEMICOLON;
|
|
|
|
if (!this._isCharacterReferenceAttributeQuirk(withSemicolon)) {
|
|
if (!withSemicolon) {
|
|
this._errOnNextCodePoint(ERR.missingSemicolonAfterCharacterReference);
|
|
}
|
|
|
|
this.tempBuff = matchResult;
|
|
}
|
|
|
|
this._flushCodePointsConsumedAsCharacterReference();
|
|
this.state = this.returnState;
|
|
} else {
|
|
this._flushCodePointsConsumedAsCharacterReference();
|
|
this.state = AMBIGUOUS_AMPERSAND_STATE;
|
|
}
|
|
}
|
|
|
|
// Ambiguos ampersand state
|
|
//------------------------------------------------------------------
|
|
[AMBIGUOUS_AMPERSAND_STATE](cp) {
|
|
if (isAsciiAlphaNumeric(cp)) {
|
|
if (this._isCharacterReferenceInAttribute()) {
|
|
this.currentAttr.value += toChar(cp);
|
|
} else {
|
|
this._emitCodePoint(cp);
|
|
}
|
|
} else {
|
|
if (cp === $.SEMICOLON) {
|
|
this._err(ERR.unknownNamedCharacterReference);
|
|
}
|
|
|
|
this._reconsumeInState(this.returnState);
|
|
}
|
|
}
|
|
|
|
// Numeric character reference state
|
|
//------------------------------------------------------------------
|
|
[NUMERIC_CHARACTER_REFERENCE_STATE](cp) {
|
|
this.charRefCode = 0;
|
|
|
|
if (cp === $.LATIN_SMALL_X || cp === $.LATIN_CAPITAL_X) {
|
|
this.tempBuff.push(cp);
|
|
this.state = HEXADEMICAL_CHARACTER_REFERENCE_START_STATE;
|
|
} else {
|
|
this._reconsumeInState(DECIMAL_CHARACTER_REFERENCE_START_STATE);
|
|
}
|
|
}
|
|
|
|
// Hexademical character reference start state
|
|
//------------------------------------------------------------------
|
|
[HEXADEMICAL_CHARACTER_REFERENCE_START_STATE](cp) {
|
|
if (isAsciiHexDigit(cp)) {
|
|
this._reconsumeInState(HEXADEMICAL_CHARACTER_REFERENCE_STATE);
|
|
} else {
|
|
this._err(ERR.absenceOfDigitsInNumericCharacterReference);
|
|
this._flushCodePointsConsumedAsCharacterReference();
|
|
this._reconsumeInState(this.returnState);
|
|
}
|
|
}
|
|
|
|
// Decimal character reference start state
|
|
//------------------------------------------------------------------
|
|
[DECIMAL_CHARACTER_REFERENCE_START_STATE](cp) {
|
|
if (isAsciiDigit(cp)) {
|
|
this._reconsumeInState(DECIMAL_CHARACTER_REFERENCE_STATE);
|
|
} else {
|
|
this._err(ERR.absenceOfDigitsInNumericCharacterReference);
|
|
this._flushCodePointsConsumedAsCharacterReference();
|
|
this._reconsumeInState(this.returnState);
|
|
}
|
|
}
|
|
|
|
// Hexademical character reference state
|
|
//------------------------------------------------------------------
|
|
[HEXADEMICAL_CHARACTER_REFERENCE_STATE](cp) {
|
|
if (isAsciiUpperHexDigit(cp)) {
|
|
this.charRefCode = this.charRefCode * 16 + cp - 0x37;
|
|
} else if (isAsciiLowerHexDigit(cp)) {
|
|
this.charRefCode = this.charRefCode * 16 + cp - 0x57;
|
|
} else if (isAsciiDigit(cp)) {
|
|
this.charRefCode = this.charRefCode * 16 + cp - 0x30;
|
|
} else if (cp === $.SEMICOLON) {
|
|
this.state = NUMERIC_CHARACTER_REFERENCE_END_STATE;
|
|
} else {
|
|
this._err(ERR.missingSemicolonAfterCharacterReference);
|
|
this._reconsumeInState(NUMERIC_CHARACTER_REFERENCE_END_STATE);
|
|
}
|
|
}
|
|
|
|
// Decimal character reference state
|
|
//------------------------------------------------------------------
|
|
[DECIMAL_CHARACTER_REFERENCE_STATE](cp) {
|
|
if (isAsciiDigit(cp)) {
|
|
this.charRefCode = this.charRefCode * 10 + cp - 0x30;
|
|
} else if (cp === $.SEMICOLON) {
|
|
this.state = NUMERIC_CHARACTER_REFERENCE_END_STATE;
|
|
} else {
|
|
this._err(ERR.missingSemicolonAfterCharacterReference);
|
|
this._reconsumeInState(NUMERIC_CHARACTER_REFERENCE_END_STATE);
|
|
}
|
|
}
|
|
|
|
// Numeric character reference end state
|
|
//------------------------------------------------------------------
|
|
[NUMERIC_CHARACTER_REFERENCE_END_STATE]() {
|
|
if (this.charRefCode === $.NULL) {
|
|
this._err(ERR.nullCharacterReference);
|
|
this.charRefCode = $.REPLACEMENT_CHARACTER;
|
|
} else if (this.charRefCode > 0x10ffff) {
|
|
this._err(ERR.characterReferenceOutsideUnicodeRange);
|
|
this.charRefCode = $.REPLACEMENT_CHARACTER;
|
|
} else if (unicode.isSurrogate(this.charRefCode)) {
|
|
this._err(ERR.surrogateCharacterReference);
|
|
this.charRefCode = $.REPLACEMENT_CHARACTER;
|
|
} else if (unicode.isUndefinedCodePoint(this.charRefCode)) {
|
|
this._err(ERR.noncharacterCharacterReference);
|
|
} else if (unicode.isControlCodePoint(this.charRefCode) || this.charRefCode === $.CARRIAGE_RETURN) {
|
|
this._err(ERR.controlCharacterReference);
|
|
|
|
const replacement = C1_CONTROLS_REFERENCE_REPLACEMENTS[this.charRefCode];
|
|
|
|
if (replacement) {
|
|
this.charRefCode = replacement;
|
|
}
|
|
}
|
|
|
|
this.tempBuff = [this.charRefCode];
|
|
|
|
this._flushCodePointsConsumedAsCharacterReference();
|
|
this._reconsumeInState(this.returnState);
|
|
}
|
|
}
|
|
|
|
//Token types
|
|
Tokenizer.CHARACTER_TOKEN = 'CHARACTER_TOKEN';
|
|
Tokenizer.NULL_CHARACTER_TOKEN = 'NULL_CHARACTER_TOKEN';
|
|
Tokenizer.WHITESPACE_CHARACTER_TOKEN = 'WHITESPACE_CHARACTER_TOKEN';
|
|
Tokenizer.START_TAG_TOKEN = 'START_TAG_TOKEN';
|
|
Tokenizer.END_TAG_TOKEN = 'END_TAG_TOKEN';
|
|
Tokenizer.COMMENT_TOKEN = 'COMMENT_TOKEN';
|
|
Tokenizer.DOCTYPE_TOKEN = 'DOCTYPE_TOKEN';
|
|
Tokenizer.EOF_TOKEN = 'EOF_TOKEN';
|
|
Tokenizer.HIBERNATION_TOKEN = 'HIBERNATION_TOKEN';
|
|
|
|
//Tokenizer initial states for different modes
|
|
Tokenizer.MODE = {
|
|
DATA: DATA_STATE,
|
|
RCDATA: RCDATA_STATE,
|
|
RAWTEXT: RAWTEXT_STATE,
|
|
SCRIPT_DATA: SCRIPT_DATA_STATE,
|
|
PLAINTEXT: PLAINTEXT_STATE
|
|
};
|
|
|
|
//Static
|
|
Tokenizer.getTokenAttr = function(token, attrName) {
|
|
for (let i = token.attrs.length - 1; i >= 0; i--) {
|
|
if (token.attrs[i].name === attrName) {
|
|
return token.attrs[i].value;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
module.exports = Tokenizer;
|
|
|
|
},{"../common/error-codes":65,"../common/unicode":68,"./named-entity-data":83,"./preprocessor":84}],83:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
//NOTE: this file contains auto-generated array mapped radix tree that is used for the named entity references consumption
|
|
//(details: https://github.com/inikulin/parse5/tree/master/scripts/generate-named-entity-data/README.md)
|
|
module.exports = new Uint16Array([4,52,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,106,303,412,810,1432,1701,1796,1987,2114,2360,2420,2484,3170,3251,4140,4393,4575,4610,5106,5512,5728,6117,6274,6315,6345,6427,6516,7002,7910,8733,9323,9870,10170,10631,10893,11318,11386,11467,12773,13092,14474,14922,15448,15542,16419,17666,18166,18611,19004,19095,19298,19397,4,16,69,77,97,98,99,102,103,108,109,110,111,112,114,115,116,117,140,150,158,169,176,194,199,210,216,222,226,242,256,266,283,294,108,105,103,5,198,1,59,148,1,198,80,5,38,1,59,156,1,38,99,117,116,101,5,193,1,59,167,1,193,114,101,118,101,59,1,258,4,2,105,121,182,191,114,99,5,194,1,59,189,1,194,59,1,1040,114,59,3,55349,56580,114,97,118,101,5,192,1,59,208,1,192,112,104,97,59,1,913,97,99,114,59,1,256,100,59,1,10835,4,2,103,112,232,237,111,110,59,1,260,102,59,3,55349,56632,112,108,121,70,117,110,99,116,105,111,110,59,1,8289,105,110,103,5,197,1,59,264,1,197,4,2,99,115,272,277,114,59,3,55349,56476,105,103,110,59,1,8788,105,108,100,101,5,195,1,59,292,1,195,109,108,5,196,1,59,301,1,196,4,8,97,99,101,102,111,114,115,117,321,350,354,383,388,394,400,405,4,2,99,114,327,336,107,115,108,97,115,104,59,1,8726,4,2,118,119,342,345,59,1,10983,101,100,59,1,8966,121,59,1,1041,4,3,99,114,116,362,369,379,97,117,115,101,59,1,8757,110,111,117,108,108,105,115,59,1,8492,97,59,1,914,114,59,3,55349,56581,112,102,59,3,55349,56633,101,118,101,59,1,728,99,114,59,1,8492,109,112,101,113,59,1,8782,4,14,72,79,97,99,100,101,102,104,105,108,111,114,115,117,442,447,456,504,542,547,569,573,577,616,678,784,790,796,99,121,59,1,1063,80,89,5,169,1,59,454,1,169,4,3,99,112,121,464,470,497,117,116,101,59,1,262,4,2,59,105,476,478,1,8914,116,97,108,68,105,102,102,101,114,101,110,116,105,97,108,68,59,1,8517,108,101,121,115,59,1,8493,4,4,97,101,105,111,514,520,530,535,114,111,110,59,1,268,100,105,108,5,199,1,59,528,1,199,114,99,59,1,264,110,105,110,116,59,1,8752,111,116,59,1,266,4,2,100,110,553,560,105,108,108,97,59,1,184,116,101,114,68,111,116,59,1,183,114,59,1,8493,105,59,1,935,114,99,108,101,4,4,68,77,80,84,591,596,603,609,111,116,59,1,8857,105,110,117,115,59,1,8854,108,117,115,59,1,8853,105,109,101,115,59,1,8855,111,4,2,99,115,623,646,107,119,105,115,101,67,111,110,116,111,117,114,73,110,116,101,103,114,97,108,59,1,8754,101,67,117,114,108,121,4,2,68,81,658,671,111,117,98,108,101,81,117,111,116,101,59,1,8221,117,111,116,101,59,1,8217,4,4,108,110,112,117,688,701,736,753,111,110,4,2,59,101,696,698,1,8759,59,1,10868,4,3,103,105,116,709,717,722,114,117,101,110,116,59,1,8801,110,116,59,1,8751,111,117,114,73,110,116,101,103,114,97,108,59,1,8750,4,2,102,114,742,745,59,1,8450,111,100,117,99,116,59,1,8720,110,116,101,114,67,108,111,99,107,119,105,115,101,67,111,110,116,111,117,114,73,110,116,101,103,114,97,108,59,1,8755,111,115,115,59,1,10799,99,114,59,3,55349,56478,112,4,2,59,67,803,805,1,8915,97,112,59,1,8781,4,11,68,74,83,90,97,99,101,102,105,111,115,834,850,855,860,865,888,903,916,921,1011,1415,4,2,59,111,840,842,1,8517,116,114,97,104,100,59,1,10513,99,121,59,1,1026,99,121,59,1,1029,99,121,59,1,1039,4,3,103,114,115,873,879,883,103,101,114,59,1,8225,114,59,1,8609,104,118,59,1,10980,4,2,97,121,894,900,114,111,110,59,1,270,59,1,1044,108,4,2,59,116,910,912,1,8711,97,59,1,916,114,59,3,55349,56583,4,2,97,102,927,998,4,2,99,109,933,992,114,105,116,105,99,97,108,4,4,65,68,71,84,950,957,978,985,99,117,116,101,59,1,180,111,4,2,116,117,964,967,59,1,729,98,108,101,65,99,117,116,101,59,1,733,114,97,118,101,59,1,96,105,108,100,101,59,1,732,111,110,100,59,1,8900,102,101,114,101,110,116,105,97,108,68,59,1,8518,4,4,112,116,117,119,1021,1026,1048,1249,102,59,3,55349,56635,4,3,59,68,69,1034,1036,1041,1,168,111,116,59,1,8412,113,117,97,108,59,1,8784,98,108,101,4,6,67,68,76,82,85,86,1065,1082,1101,1189,1211,1236,111,110,116,111,117,114,73,110,116,101,103,114,97,108,59,1,8751,111,4,2,116,119,1089,1092,59,1,168,110,65,114,114,111,119,59,1,8659,4,2,101,111,1107,1141,102,116,4,3,65,82,84,1117,1124,1136,114,114,111,119,59,1,8656,105,103,104,116,65,114,114,111,119,59,1,8660,101,101,59,1,10980,110,103,4,2,76,82,1149,1177,101,102,116,4,2,65,82,1158,1165,114,114,111,119,59,1,10232,105,103,104,116,65,114,114,111,119,59,1,10234,105,103,104,116,65,114,114,111,119,59,1,10233,105,103,104,116,4,2,65,84,1199,1206,114,114,111,119,59,1,8658,101,101,59,1,8872,112,4,2,65,68,1218,1225,114,114,111,119,59,1,8657,111,119,110,65,114,114,111,119,59,1,8661,101,114,116,105,99,97,108,66,97,114,59,1,8741,110,4,6,65,66,76,82,84,97,1264,1292,1299,1352,1391,1408,114,114,111,119,4,3,59,66,85,1276,1278,1283,1,8595,97,114,59,1,10515,112,65,114,114,111,119,59,1,8693,114,101,118,101,59,1,785,101,102,116,4,3,82,84,86,1310,1323,1334,105,103,104,116,86,101,99,116,111,114,59,1,10576,101,101,86,101,99,116,111,114,59,1,10590,101,99,116,111,114,4,2,59,66,1345,1347,1,8637,97,114,59,1,10582,105,103,104,116,4,2,84,86,1362,1373,101,101,86,101,99,116,111,114,59,1,10591,101,99,116,111,114,4,2,59,66,1384,1386,1,8641,97,114,59,1,10583,101,101,4,2,59,65,1399,1401,1,8868,114,114,111,119,59,1,8615,114,114,111,119,59,1,8659,4,2,99,116,1421,1426,114,59,3,55349,56479,114,111,107,59,1,272,4,16,78,84,97,99,100,102,103,108,109,111,112,113,115,116,117,120,1466,1470,1478,1489,1515,1520,1525,1536,1544,1593,1609,1617,1650,1664,1668,1677,71,59,1,330,72,5,208,1,59,1476,1,208,99,117,116,101,5,201,1,59,1487,1,201,4,3,97,105,121,1497,1503,1512,114,111,110,59,1,282,114,99,5,202,1,59,1510,1,202,59,1,1069,111,116,59,1,278,114,59,3,55349,56584,114,97,118,101,5,200,1,59,1534,1,200,101,109,101,110,116,59,1,8712,4,2,97,112,1550,1555,99,114,59,1,274,116,121,4,2,83,86,1563,1576,109,97,108,108,83,113,117,97,114,101,59,1,9723,101,114,121,83,109,97,108,108,83,113,117,97,114,101,59,1,9643,4,2,103,112,1599,1604,111,110,59,1,280,102,59,3,55349,56636,115,105,108,111,110,59,1,917,117,4,2,97,105,1624,1640,108,4,2,59,84,1631,1633,1,10869,105,108,100,101,59,1,8770,108,105,98,114,105,117,109,59,1,8652,4,2,99,105,1656,1660,114,59,1,8496,109,59,1,10867,97,59,1,919,109,108,5,203,1,59,1675,1,203,4,2,105,112,1683,1689,115,116,115,59,1,8707,111,110,101,110,116,105,97,108,69,59,1,8519,4,5,99,102,105,111,115,1713,1717,1722,1762,1791,121,59,1,1060,114,59,3,55349,56585,108,108,101,100,4,2,83,86,1732,1745,109,97,108,108,83,113,117,97,114,101,59,1,9724,101,114,121,83,109,97,108,108,83,113,117,97,114,101,59,1,9642,4,3,112,114,117,1770,1775,1781,102,59,3,55349,56637,65,108,108,59,1,8704,114,105,101,114,116,114,102,59,1,8497,99,114,59,1,8497,4,12,74,84,97,98,99,100,102,103,111,114,115,116,1822,1827,1834,1848,1855,1877,1882,1887,1890,1896,1978,1984,99,121,59,1,1027,5,62,1,59,1832,1,62,109,109,97,4,2,59,100,1843,1845,1,915,59,1,988,114,101,118,101,59,1,286,4,3,101,105,121,1863,1869,1874,100,105,108,59,1,290,114,99,59,1,284,59,1,1043,111,116,59,1,288,114,59,3,55349,56586,59,1,8921,112,102,59,3,55349,56638,101,97,116,101,114,4,6,69,70,71,76,83,84,1915,1933,1944,1953,1959,1971,113,117,97,108,4,2,59,76,1925,1927,1,8805,101,115,115,59,1,8923,117,108,108,69,113,117,97,108,59,1,8807,114,101,97,116,101,114,59,1,10914,101,115,115,59,1,8823,108,97,110,116,69,113,117,97,108,59,1,10878,105,108,100,101,59,1,8819,99,114,59,3,55349,56482,59,1,8811,4,8,65,97,99,102,105,111,115,117,2005,2012,2026,2032,2036,2049,2073,2089,82,68,99,121,59,1,1066,4,2,99,116,2018,2023,101,107,59,1,711,59,1,94,105,114,99,59,1,292,114,59,1,8460,108,98,101,114,116,83,112,97,99,101,59,1,8459,4,2,112,114,2055,2059,102,59,1,8461,105,122,111,110,116,97,108,76,105,110,101,59,1,9472,4,2,99,116,2079,2083,114,59,1,8459,114,111,107,59,1,294,109,112,4,2,68,69,2097,2107,111,119,110,72,117,109,112,59,1,8782,113,117,97,108,59,1,8783,4,14,69,74,79,97,99,100,102,103,109,110,111,115,116,117,2144,2149,2155,2160,2171,2189,2194,2198,2209,2245,2307,2329,2334,2341,99,121,59,1,1045,108,105,103,59,1,306,99,121,59,1,1025,99,117,116,101,5,205,1,59,2169,1,205,4,2,105,121,2177,2186,114,99,5,206,1,59,2184,1,206,59,1,1048,111,116,59,1,304,114,59,1,8465,114,97,118,101,5,204,1,59,2207,1,204,4,3,59,97,112,2217,2219,2238,1,8465,4,2,99,103,2225,2229,114,59,1,298,105,110,97,114,121,73,59,1,8520,108,105,101,115,59,1,8658,4,2,116,118,2251,2281,4,2,59,101,2257,2259,1,8748,4,2,103,114,2265,2271,114,97,108,59,1,8747,115,101,99,116,105,111,110,59,1,8898,105,115,105,98,108,101,4,2,67,84,2293,2300,111,109,109,97,59,1,8291,105,109,101,115,59,1,8290,4,3,103,112,116,2315,2320,2325,111,110,59,1,302,102,59,3,55349,56640,97,59,1,921,99,114,59,1,8464,105,108,100,101,59,1,296,4,2,107,109,2347,2352,99,121,59,1,1030,108,5,207,1,59,2358,1,207,4,5,99,102,111,115,117,2372,2386,2391,2397,2414,4,2,105,121,2378,2383,114,99,59,1,308,59,1,1049,114,59,3,55349,56589,112,102,59,3,55349,56641,4,2,99,101,2403,2408,114,59,3,55349,56485,114,99,121,59,1,1032,107,99,121,59,1,1028,4,7,72,74,97,99,102,111,115,2436,2441,2446,2452,2467,2472,2478,99,121,59,1,1061,99,121,59,1,1036,112,112,97,59,1,922,4,2,101,121,2458,2464,100,105,108,59,1,310,59,1,1050,114,59,3,55349,56590,112,102,59,3,55349,56642,99,114,59,3,55349,56486,4,11,74,84,97,99,101,102,108,109,111,115,116,2508,2513,2520,2562,2585,2981,2986,3004,3011,3146,3167,99,121,59,1,1033,5,60,1,59,2518,1,60,4,5,99,109,110,112,114,2532,2538,2544,2548,2558,117,116,101,59,1,313,98,100,97,59,1,923,103,59,1,10218,108,97,99,101,116,114,102,59,1,8466,114,59,1,8606,4,3,97,101,121,2570,2576,2582,114,111,110,59,1,317,100,105,108,59,1,315,59,1,1051,4,2,102,115,2591,2907,116,4,10,65,67,68,70,82,84,85,86,97,114,2614,2663,2672,2728,2735,2760,2820,2870,2888,2895,4,2,110,114,2620,2633,103,108,101,66,114,97,99,107,101,116,59,1,10216,114,111,119,4,3,59,66,82,2644,2646,2651,1,8592,97,114,59,1,8676,105,103,104,116,65,114,114,111,119,59,1,8646,101,105,108,105,110,103,59,1,8968,111,4,2,117,119,2679,2692,98,108,101,66,114,97,99,107,101,116,59,1,10214,110,4,2,84,86,2699,2710,101,101,86,101,99,116,111,114,59,1,10593,101,99,116,111,114,4,2,59,66,2721,2723,1,8643,97,114,59,1,10585,108,111,111,114,59,1,8970,105,103,104,116,4,2,65,86,2745,2752,114,114,111,119,59,1,8596,101,99,116,111,114,59,1,10574,4,2,101,114,2766,2792,101,4,3,59,65,86,2775,2777,2784,1,8867,114,114,111,119,59,1,8612,101,99,116,111,114,59,1,10586,105,97,110,103,108,101,4,3,59,66,69,2806,2808,2813,1,8882,97,114,59,1,10703,113,117,97,108,59,1,8884,112,4,3,68,84,86,2829,2841,2852,111,119,110,86,101,99,116,111,114,59,1,10577,101,101,86,101,99,116,111,114,59,1,10592,101,99,116,111,114,4,2,59,66,2863,2865,1,8639,97,114,59,1,10584,101,99,116,111,114,4,2,59,66,2881,2883,1,8636,97,114,59,1,10578,114,114,111,119,59,1,8656,105,103,104,116,97,114,114,111,119,59,1,8660,115,4,6,69,70,71,76,83,84,2922,2936,2947,2956,2962,2974,113,117,97,108,71,114,101,97,116,101,114,59,1,8922,117,108,108,69,113,117,97,108,59,1,8806,114,101,97,116,101,114,59,1,8822,101,115,115,59,1,10913,108,97,110,116,69,113,117,97,108,59,1,10877,105,108,100,101,59,1,8818,114,59,3,55349,56591,4,2,59,101,2992,2994,1,8920,102,116,97,114,114,111,119,59,1,8666,105,100,111,116,59,1,319,4,3,110,112,119,3019,3110,3115,103,4,4,76,82,108,114,3030,3058,3070,3098,101,102,116,4,2,65,82,3039,3046,114,114,111,119,59,1,10229,105,103,104,116,65,114,114,111,119,59,1,10231,105,103,104,116,65,114,114,111,119,59,1,10230,101,102,116,4,2,97,114,3079,3086,114,114,111,119,59,1,10232,105,103,104,116,97,114,114,111,119,59,1,10234,105,103,104,116,97,114,114,111,119,59,1,10233,102,59,3,55349,56643,101,114,4,2,76,82,3123,3134,101,102,116,65,114,114,111,119,59,1,8601,105,103,104,116,65,114,114,111,119,59,1,8600,4,3,99,104,116,3154,3158,3161,114,59,1,8466,59,1,8624,114,111,107,59,1,321,59,1,8810,4,8,97,99,101,102,105,111,115,117,3188,3192,3196,3222,3227,3237,3243,3248,112,59,1,10501,121,59,1,1052,4,2,100,108,3202,3213,105,117,109,83,112,97,99,101,59,1,8287,108,105,110,116,114,102,59,1,8499,114,59,3,55349,56592,110,117,115,80,108,117,115,59,1,8723,112,102,59,3,55349,56644,99,114,59,1,8499,59,1,924,4,9,74,97,99,101,102,111,115,116,117,3271,3276,3283,3306,3422,3427,4120,4126,4137,99,121,59,1,1034,99,117,116,101,59,1,323,4,3,97,101,121,3291,3297,3303,114,111,110,59,1,327,100,105,108,59,1,325,59,1,1053,4,3,103,115,119,3314,3380,3415,97,116,105,118,101,4,3,77,84,86,3327,3340,3365,101,100,105,117,109,83,112,97,99,101,59,1,8203,104,105,4,2,99,110,3348,3357,107,83,112,97,99,101,59,1,8203,83,112,97,99,101,59,1,8203,101,114,121,84,104,105,110,83,112,97,99,101,59,1,8203,116,101,100,4,2,71,76,3389,3405,114,101,97,116,101,114,71,114,101,97,116,101,114,59,1,8811,101,115,115,76,101,115,115,59,1,8810,76,105,110,101,59,1,10,114,59,3,55349,56593,4,4,66,110,112,116,3437,3444,3460,3464,114,101,97,107,59,1,8288,66,114,101,97,107,105,110,103,83,112,97,99,101,59,1,160,102,59,1,8469,4,13,59,67,68,69,71,72,76,78,80,82,83,84,86,3492,3494,3517,3536,3578,3657,3685,3784,3823,3860,3915,4066,4107,1,10988,4,2,111,117,3500,3510,110,103,114,117,101,110,116,59,1,8802,112,67,97,112,59,1,8813,111,117,98,108,101,86,101,114,116,105,99,97,108,66,97,114,59,1,8742,4,3,108,113,120,3544,3552,3571,101,109,101,110,116,59,1,8713,117,97,108,4,2,59,84,3561,3563,1,8800,105,108,100,101,59,3,8770,824,105,115,116,115,59,1,8708,114,101,97,116,101,114,4,7,59,69,70,71,76,83,84,3600,3602,3609,3621,3631,3637,3650,1,8815,113,117,97,108,59,1,8817,117,108,108,69,113,117,97,108,59,3,8807,824,114,101,97,116,101,114,59,3,8811,824,101,115,115,59,1,8825,108,97,110,116,69,113,117,97,108,59,3,10878,824,105,108,100,101,59,1,8821,117,109,112,4,2,68,69,3666,3677,111,119,110,72,117,109,112,59,3,8782,824,113,117,97,108,59,3,8783,824,101,4,2,102,115,3692,3724,116,84,114,105,97,110,103,108,101,4,3,59,66,69,3709,3711,3717,1,8938,97,114,59,3,10703,824,113,117,97,108,59,1,8940,115,4,6,59,69,71,76,83,84,3739,3741,3748,3757,3764,3777,1,8814,113,117,97,108,59,1,8816,114,101,97,116,101,114,59,1,8824,101,115,115,59,3,8810,824,108,97,110,116,69,113,117,97,108,59,3,10877,824,105,108,100,101,59,1,8820,101,115,116,101,100,4,2,71,76,3795,3812,114,101,97,116,101,114,71,114,101,97,116,101,114,59,3,10914,824,101,115,115,76,101,115,115,59,3,10913,824,114,101,99,101,100,101,115,4,3,59,69,83,3838,3840,3848,1,8832,113,117,97,108,59,3,10927,824,108,97,110,116,69,113,117,97,108,59,1,8928,4,2,101,105,3866,3881,118,101,114,115,101,69,108,101,109,101,110,116,59,1,8716,103,104,116,84,114,105,97,110,103,108,101,4,3,59,66,69,3900,3902,3908,1,8939,97,114,59,3,10704,824,113,117,97,108,59,1,8941,4,2,113,117,3921,3973,117,97,114,101,83,117,4,2,98,112,3933,3952,115,101,116,4,2,59,69,3942,3945,3,8847,824,113,117,97,108,59,1,8930,101,114,115,101,116,4,2,59,69,3963,3966,3,8848,824,113,117,97,108,59,1,8931,4,3,98,99,112,3981,4000,4045,115,101,116,4,2,59,69,3990,3993,3,8834,8402,113,117,97,108,59,1,8840,99,101,101,100,115,4,4,59,69,83,84,4015,4017,4025,4037,1,8833,113,117,97,108,59,3,10928,824,108,97,110,116,69,113,117,97,108,59,1,8929,105,108,100,101,59,3,8831,824,101,114,115,101,116,4,2,59,69,4056,4059,3,8835,8402,113,117,97,108,59,1,8841,105,108,100,101,4,4,59,69,70,84,4080,4082,4089,4100,1,8769,113,117,97,108,59,1,8772,117,108,108,69,113,117,97,108,59,1,8775,105,108,100,101,59,1,8777,101,114,116,105,99,97,108,66,97,114,59,1,8740,99,114,59,3,55349,56489,105,108,100,101,5,209,1,59,4135,1,209,59,1,925,4,14,69,97,99,100,102,103,109,111,112,114,115,116,117,118,4170,4176,4187,4205,4212,4217,4228,4253,4259,4292,4295,4316,4337,4346,108,105,103,59,1,338,99,117,116,101,5,211,1,59,4185,1,211,4,2,105,121,4193,4202,114,99,5,212,1,59,4200,1,212,59,1,1054,98,108,97,99,59,1,336,114,59,3,55349,56594,114,97,118,101,5,210,1,59,4226,1,210,4,3,97,101,105,4236,4241,4246,99,114,59,1,332,103,97,59,1,937,99,114,111,110,59,1,927,112,102,59,3,55349,56646,101,110,67,117,114,108,121,4,2,68,81,4272,4285,111,117,98,108,101,81,117,111,116,101,59,1,8220,117,111,116,101,59,1,8216,59,1,10836,4,2,99,108,4301,4306,114,59,3,55349,56490,97,115,104,5,216,1,59,4314,1,216,105,4,2,108,109,4323,4332,100,101,5,213,1,59,4330,1,213,101,115,59,1,10807,109,108,5,214,1,59,4344,1,214,101,114,4,2,66,80,4354,4380,4,2,97,114,4360,4364,114,59,1,8254,97,99,4,2,101,107,4372,4375,59,1,9182,101,116,59,1,9140,97,114,101,110,116,104,101,115,105,115,59,1,9180,4,9,97,99,102,104,105,108,111,114,115,4413,4422,4426,4431,4435,4438,4448,4471,4561,114,116,105,97,108,68,59,1,8706,121,59,1,1055,114,59,3,55349,56595,105,59,1,934,59,1,928,117,115,77,105,110,117,115,59,1,177,4,2,105,112,4454,4467,110,99,97,114,101,112,108,97,110,101,59,1,8460,102,59,1,8473,4,4,59,101,105,111,4481,4483,4526,4531,1,10939,99,101,100,101,115,4,4,59,69,83,84,4498,4500,4507,4519,1,8826,113,117,97,108,59,1,10927,108,97,110,116,69,113,117,97,108,59,1,8828,105,108,100,101,59,1,8830,109,101,59,1,8243,4,2,100,112,4537,4543,117,99,116,59,1,8719,111,114,116,105,111,110,4,2,59,97,4555,4557,1,8759,108,59,1,8733,4,2,99,105,4567,4572,114,59,3,55349,56491,59,1,936,4,4,85,102,111,115,4585,4594,4599,4604,79,84,5,34,1,59,4592,1,34,114,59,3,55349,56596,112,102,59,1,8474,99,114,59,3,55349,56492,4,12,66,69,97,99,101,102,104,105,111,114,115,117,4636,4642,4650,4681,4704,4763,4767,4771,5047,5069,5081,5094,97,114,114,59,1,10512,71,5,174,1,59,4648,1,174,4,3,99,110,114,4658,4664,4668,117,116,101,59,1,340,103,59,1,10219,114,4,2,59,116,4675,4677,1,8608,108,59,1,10518,4,3,97,101,121,4689,4695,4701,114,111,110,59,1,344,100,105,108,59,1,342,59,1,1056,4,2,59,118,4710,4712,1,8476,101,114,115,101,4,2,69,85,4722,4748,4,2,108,113,4728,4736,101,109,101,110,116,59,1,8715,117,105,108,105,98,114,105,117,109,59,1,8651,112,69,113,117,105,108,105,98,114,105,117,109,59,1,10607,114,59,1,8476,111,59,1,929,103,104,116,4,8,65,67,68,70,84,85,86,97,4792,4840,4849,4905,4912,4972,5022,5040,4,2,110,114,4798,4811,103,108,101,66,114,97,99,107,101,116,59,1,10217,114,111,119,4,3,59,66,76,4822,4824,4829,1,8594,97,114,59,1,8677,101,102,116,65,114,114,111,119,59,1,8644,101,105,108,105,110,103,59,1,8969,111,4,2,117,119,4856,4869,98,108,101,66,114,97,99,107,101,116,59,1,10215,110,4,2,84,86,4876,4887,101,101,86,101,99,116,111,114,59,1,10589,101,99,116,111,114,4,2,59,66,4898,4900,1,8642,97,114,59,1,10581,108,111,111,114,59,1,8971,4,2,101,114,4918,4944,101,4,3,59,65,86,4927,4929,4936,1,8866,114,114,111,119,59,1,8614,101,99,116,111,114,59,1,10587,105,97,110,103,108,101,4,3,59,66,69,4958,4960,4965,1,8883,97,114,59,1,10704,113,117,97,108,59,1,8885,112,4,3,68,84,86,4981,4993,5004,111,119,110,86,101,99,116,111,114,59,1,10575,101,101,86,101,99,116,111,114,59,1,10588,101,99,116,111,114,4,2,59,66,5015,5017,1,8638,97,114,59,1,10580,101,99,116,111,114,4,2,59,66,5033,5035,1,8640,97,114,59,1,10579,114,114,111,119,59,1,8658,4,2,112,117,5053,5057,102,59,1,8477,110,100,73,109,112,108,105,101,115,59,1,10608,105,103,104,116,97,114,114,111,119,59,1,8667,4,2,99,104,5087,5091,114,59,1,8475,59,1,8625,108,101,68,101,108,97,121,101,100,59,1,10740,4,13,72,79,97,99,102,104,105,109,111,113,115,116,117,5134,5150,5157,5164,5198,5203,5259,5265,5277,5283,5374,5380,5385,4,2,67,99,5140,5146,72,99,121,59,1,1065,121,59,1,1064,70,84,99,121,59,1,1068,99,117,116,101,59,1,346,4,5,59,97,101,105,121,5176,5178,5184,5190,5195,1,10940,114,111,110,59,1,352,100,105,108,59,1,350,114,99,59,1,348,59,1,1057,114,59,3,55349,56598,111,114,116,4,4,68,76,82,85,5216,5227,5238,5250,111,119,110,65,114,114,111,119,59,1,8595,101,102,116,65,114,114,111,119,59,1,8592,105,103,104,116,65,114,114,111,119,59,1,8594,112,65,114,114,111,119,59,1,8593,103,109,97,59,1,931,97,108,108,67,105,114,99,108,101,59,1,8728,112,102,59,3,55349,56650,4,2,114,117,5289,5293,116,59,1,8730,97,114,101,4,4,59,73,83,85,5306,5308,5322,5367,1,9633,110,116,101,114,115,101,99,116,105,111,110,59,1,8851,117,4,2,98,112,5329,5347,115,101,116,4,2,59,69,5338,5340,1,8847,113,117,97,108,59,1,8849,101,114,115,101,116,4,2,59,69,5358,5360,1,8848,113,117,97,108,59,1,8850,110,105,111,110,59,1,8852,99,114,59,3,55349,56494,97,114,59,1,8902,4,4,98,99,109,112,5395,5420,5475,5478,4,2,59,115,5401,5403,1,8912,101,116,4,2,59,69,5411,5413,1,8912,113,117,97,108,59,1,8838,4,2,99,104,5426,5468,101,101,100,115,4,4,59,69,83,84,5440,5442,5449,5461,1,8827,113,117,97,108,59,1,10928,108,97,110,116,69,113,117,97,108,59,1,8829,105,108,100,101,59,1,8831,84,104,97,116,59,1,8715,59,1,8721,4,3,59,101,115,5486,5488,5507,1,8913,114,115,101,116,4,2,59,69,5498,5500,1,8835,113,117,97,108,59,1,8839,101,116,59,1,8913,4,11,72,82,83,97,99,102,104,105,111,114,115,5536,5546,5552,5567,5579,5602,5607,5655,5695,5701,5711,79,82,78,5,222,1,59,5544,1,222,65,68,69,59,1,8482,4,2,72,99,5558,5563,99,121,59,1,1035,121,59,1,1062,4,2,98,117,5573,5576,59,1,9,59,1,932,4,3,97,101,121,5587,5593,5599,114,111,110,59,1,356,100,105,108,59,1,354,59,1,1058,114,59,3,55349,56599,4,2,101,105,5613,5631,4,2,114,116,5619,5627,101,102,111,114,101,59,1,8756,97,59,1,920,4,2,99,110,5637,5647,107,83,112,97,99,101,59,3,8287,8202,83,112,97,99,101,59,1,8201,108,100,101,4,4,59,69,70,84,5668,5670,5677,5688,1,8764,113,117,97,108,59,1,8771,117,108,108,69,113,117,97,108,59,1,8773,105,108,100,101,59,1,8776,112,102,59,3,55349,56651,105,112,108,101,68,111,116,59,1,8411,4,2,99,116,5717,5722,114,59,3,55349,56495,114,111,107,59,1,358,4,14,97,98,99,100,102,103,109,110,111,112,114,115,116,117,5758,5789,5805,5823,5830,5835,5846,5852,5921,5937,6089,6095,6101,6108,4,2,99,114,5764,5774,117,116,101,5,218,1,59,5772,1,218,114,4,2,59,111,5781,5783,1,8607,99,105,114,59,1,10569,114,4,2,99,101,5796,5800,121,59,1,1038,118,101,59,1,364,4,2,105,121,5811,5820,114,99,5,219,1,59,5818,1,219,59,1,1059,98,108,97,99,59,1,368,114,59,3,55349,56600,114,97,118,101,5,217,1,59,5844,1,217,97,99,114,59,1,362,4,2,100,105,5858,5905,101,114,4,2,66,80,5866,5892,4,2,97,114,5872,5876,114,59,1,95,97,99,4,2,101,107,5884,5887,59,1,9183,101,116,59,1,9141,97,114,101,110,116,104,101,115,105,115,59,1,9181,111,110,4,2,59,80,5913,5915,1,8899,108,117,115,59,1,8846,4,2,103,112,5927,5932,111,110,59,1,370,102,59,3,55349,56652,4,8,65,68,69,84,97,100,112,115,5955,5985,5996,6009,6026,6033,6044,6075,114,114,111,119,4,3,59,66,68,5967,5969,5974,1,8593,97,114,59,1,10514,111,119,110,65,114,114,111,119,59,1,8645,111,119,110,65,114,114,111,119,59,1,8597,113,117,105,108,105,98,114,105,117,109,59,1,10606,101,101,4,2,59,65,6017,6019,1,8869,114,114,111,119,59,1,8613,114,114,111,119,59,1,8657,111,119,110,97,114,114,111,119,59,1,8661,101,114,4,2,76,82,6052,6063,101,102,116,65,114,114,111,119,59,1,8598,105,103,104,116,65,114,114,111,119,59,1,8599,105,4,2,59,108,6082,6084,1,978,111,110,59,1,933,105,110,103,59,1,366,99,114,59,3,55349,56496,105,108,100,101,59,1,360,109,108,5,220,1,59,6115,1,220,4,9,68,98,99,100,101,102,111,115,118,6137,6143,6148,6152,6166,6250,6255,6261,6267,97,115,104,59,1,8875,97,114,59,1,10987,121,59,1,1042,97,115,104,4,2,59,108,6161,6163,1,8873,59,1,10982,4,2,101,114,6172,6175,59,1,8897,4,3,98,116,121,6183,6188,6238,97,114,59,1,8214,4,2,59,105,6194,6196,1,8214,99,97,108,4,4,66,76,83,84,6209,6214,6220,6231,97,114,59,1,8739,105,110,101,59,1,124,101,112,97,114,97,116,111,114,59,1,10072,105,108,100,101,59,1,8768,84,104,105,110,83,112,97,99,101,59,1,8202,114,59,3,55349,56601,112,102,59,3,55349,56653,99,114,59,3,55349,56497,100,97,115,104,59,1,8874,4,5,99,101,102,111,115,6286,6292,6298,6303,6309,105,114,99,59,1,372,100,103,101,59,1,8896,114,59,3,55349,56602,112,102,59,3,55349,56654,99,114,59,3,55349,56498,4,4,102,105,111,115,6325,6330,6333,6339,114,59,3,55349,56603,59,1,926,112,102,59,3,55349,56655,99,114,59,3,55349,56499,4,9,65,73,85,97,99,102,111,115,117,6365,6370,6375,6380,6391,6405,6410,6416,6422,99,121,59,1,1071,99,121,59,1,1031,99,121,59,1,1070,99,117,116,101,5,221,1,59,6389,1,221,4,2,105,121,6397,6402,114,99,59,1,374,59,1,1067,114,59,3,55349,56604,112,102,59,3,55349,56656,99,114,59,3,55349,56500,109,108,59,1,376,4,8,72,97,99,100,101,102,111,115,6445,6450,6457,6472,6477,6501,6505,6510,99,121,59,1,1046,99,117,116,101,59,1,377,4,2,97,121,6463,6469,114,111,110,59,1,381,59,1,1047,111,116,59,1,379,4,2,114,116,6483,6497,111,87,105,100,116,104,83,112,97,99,101,59,1,8203,97,59,1,918,114,59,1,8488,112,102,59,1,8484,99,114,59,3,55349,56501,4,16,97,98,99,101,102,103,108,109,110,111,112,114,115,116,117,119,6550,6561,6568,6612,6622,6634,6645,6672,6699,6854,6870,6923,6933,6963,6974,6983,99,117,116,101,5,225,1,59,6559,1,225,114,101,118,101,59,1,259,4,6,59,69,100,105,117,121,6582,6584,6588,6591,6600,6609,1,8766,59,3,8766,819,59,1,8767,114,99,5,226,1,59,6598,1,226,116,101,5,180,1,59,6607,1,180,59,1,1072,108,105,103,5,230,1,59,6620,1,230,4,2,59,114,6628,6630,1,8289,59,3,55349,56606,114,97,118,101,5,224,1,59,6643,1,224,4,2,101,112,6651,6667,4,2,102,112,6657,6663,115,121,109,59,1,8501,104,59,1,8501,104,97,59,1,945,4,2,97,112,6678,6692,4,2,99,108,6684,6688,114,59,1,257,103,59,1,10815,5,38,1,59,6697,1,38,4,2,100,103,6705,6737,4,5,59,97,100,115,118,6717,6719,6724,6727,6734,1,8743,110,100,59,1,10837,59,1,10844,108,111,112,101,59,1,10840,59,1,10842,4,7,59,101,108,109,114,115,122,6753,6755,6758,6762,6814,6835,6848,1,8736,59,1,10660,101,59,1,8736,115,100,4,2,59,97,6770,6772,1,8737,4,8,97,98,99,100,101,102,103,104,6790,6793,6796,6799,6802,6805,6808,6811,59,1,10664,59,1,10665,59,1,10666,59,1,10667,59,1,10668,59,1,10669,59,1,10670,59,1,10671,116,4,2,59,118,6821,6823,1,8735,98,4,2,59,100,6830,6832,1,8894,59,1,10653,4,2,112,116,6841,6845,104,59,1,8738,59,1,197,97,114,114,59,1,9084,4,2,103,112,6860,6865,111,110,59,1,261,102,59,3,55349,56658,4,7,59,69,97,101,105,111,112,6886,6888,6891,6897,6900,6904,6908,1,8776,59,1,10864,99,105,114,59,1,10863,59,1,8778,100,59,1,8779,115,59,1,39,114,111,120,4,2,59,101,6917,6919,1,8776,113,59,1,8778,105,110,103,5,229,1,59,6931,1,229,4,3,99,116,121,6941,6946,6949,114,59,3,55349,56502,59,1,42,109,112,4,2,59,101,6957,6959,1,8776,113,59,1,8781,105,108,100,101,5,227,1,59,6972,1,227,109,108,5,228,1,59,6981,1,228,4,2,99,105,6989,6997,111,110,105,110,116,59,1,8755,110,116,59,1,10769,4,16,78,97,98,99,100,101,102,105,107,108,110,111,112,114,115,117,7036,7041,7119,7135,7149,7155,7219,7224,7347,7354,7463,7489,7786,7793,7814,7866,111,116,59,1,10989,4,2,99,114,7047,7094,107,4,4,99,101,112,115,7058,7064,7073,7080,111,110,103,59,1,8780,112,115,105,108,111,110,59,1,1014,114,105,109,101,59,1,8245,105,109,4,2,59,101,7088,7090,1,8765,113,59,1,8909,4,2,118,119,7100,7105,101,101,59,1,8893,101,100,4,2,59,103,7113,7115,1,8965,101,59,1,8965,114,107,4,2,59,116,7127,7129,1,9141,98,114,107,59,1,9142,4,2,111,121,7141,7146,110,103,59,1,8780,59,1,1073,113,117,111,59,1,8222,4,5,99,109,112,114,116,7167,7181,7188,7193,7199,97,117,115,4,2,59,101,7176,7178,1,8757,59,1,8757,112,116,121,118,59,1,10672,115,105,59,1,1014,110,111,117,59,1,8492,4,3,97,104,119,7207,7210,7213,59,1,946,59,1,8502,101,101,110,59,1,8812,114,59,3,55349,56607,103,4,7,99,111,115,116,117,118,119,7241,7262,7288,7305,7328,7335,7340,4,3,97,105,117,7249,7253,7258,112,59,1,8898,114,99,59,1,9711,112,59,1,8899,4,3,100,112,116,7270,7275,7281,111,116,59,1,10752,108,117,115,59,1,10753,105,109,101,115,59,1,10754,4,2,113,116,7294,7300,99,117,112,59,1,10758,97,114,59,1,9733,114,105,97,110,103,108,101,4,2,100,117,7318,7324,111,119,110,59,1,9661,112,59,1,9651,112,108,117,115,59,1,10756,101,101,59,1,8897,101,100,103,101,59,1,8896,97,114,111,119,59,1,10509,4,3,97,107,111,7362,7436,7458,4,2,99,110,7368,7432,107,4,3,108,115,116,7377,7386,7394,111,122,101,110,103,101,59,1,10731,113,117,97,114,101,59,1,9642,114,105,97,110,103,108,101,4,4,59,100,108,114,7411,7413,7419,7425,1,9652,111,119,110,59,1,9662,101,102,116,59,1,9666,105,103,104,116,59,1,9656,107,59,1,9251,4,2,49,51,7442,7454,4,2,50,52,7448,7451,59,1,9618,59,1,9617,52,59,1,9619,99,107,59,1,9608,4,2,101,111,7469,7485,4,2,59,113,7475,7478,3,61,8421,117,105,118,59,3,8801,8421,116,59,1,8976,4,4,112,116,119,120,7499,7504,7517,7523,102,59,3,55349,56659,4,2,59,116,7510,7512,1,8869,111,109,59,1,8869,116,105,101,59,1,8904,4,12,68,72,85,86,98,100,104,109,112,116,117,118,7549,7571,7597,7619,7655,7660,7682,7708,7715,7721,7728,7750,4,4,76,82,108,114,7559,7562,7565,7568,59,1,9559,59,1,9556,59,1,9558,59,1,9555,4,5,59,68,85,100,117,7583,7585,7588,7591,7594,1,9552,59,1,9574,59,1,9577,59,1,9572,59,1,9575,4,4,76,82,108,114,7607,7610,7613,7616,59,1,9565,59,1,9562,59,1,9564,59,1,9561,4,7,59,72,76,82,104,108,114,7635,7637,7640,7643,7646,7649,7652,1,9553,59,1,9580,59,1,9571,59,1,9568,59,1,9579,59,1,9570,59,1,9567,111,120,59,1,10697,4,4,76,82,108,114,7670,7673,7676,7679,59,1,9557,59,1,9554,59,1,9488,59,1,9484,4,5,59,68,85,100,117,7694,7696,7699,7702,7705,1,9472,59,1,9573,59,1,9576,59,1,9516,59,1,9524,105,110,117,115,59,1,8863,108,117,115,59,1,8862,105,109,101,115,59,1,8864,4,4,76,82,108,114,7738,7741,7744,7747,59,1,9563,59,1,9560,59,1,9496,59,1,9492,4,7,59,72,76,82,104,108,114,7766,7768,7771,7774,7777,7780,7783,1,9474,59,1,9578,59,1,9569,59,1,9566,59,1,9532,59,1,9508,59,1,9500,114,105,109,101,59,1,8245,4,2,101,118,7799,7804,118,101,59,1,728,98,97,114,5,166,1,59,7812,1,166,4,4,99,101,105,111,7824,7829,7834,7846,114,59,3,55349,56503,109,105,59,1,8271,109,4,2,59,101,7841,7843,1,8765,59,1,8909,108,4,3,59,98,104,7855,7857,7860,1,92,59,1,10693,115,117,98,59,1,10184,4,2,108,109,7872,7885,108,4,2,59,101,7879,7881,1,8226,116,59,1,8226,112,4,3,59,69,101,7894,7896,7899,1,8782,59,1,10926,4,2,59,113,7905,7907,1,8783,59,1,8783,4,15,97,99,100,101,102,104,105,108,111,114,115,116,117,119,121,7942,8021,8075,8080,8121,8126,8157,8279,8295,8430,8446,8485,8491,8707,8726,4,3,99,112,114,7950,7956,8007,117,116,101,59,1,263,4,6,59,97,98,99,100,115,7970,7972,7977,7984,7998,8003,1,8745,110,100,59,1,10820,114,99,117,112,59,1,10825,4,2,97,117,7990,7994,112,59,1,10827,112,59,1,10823,111,116,59,1,10816,59,3,8745,65024,4,2,101,111,8013,8017,116,59,1,8257,110,59,1,711,4,4,97,101,105,117,8031,8046,8056,8061,4,2,112,114,8037,8041,115,59,1,10829,111,110,59,1,269,100,105,108,5,231,1,59,8054,1,231,114,99,59,1,265,112,115,4,2,59,115,8069,8071,1,10828,109,59,1,10832,111,116,59,1,267,4,3,100,109,110,8088,8097,8104,105,108,5,184,1,59,8095,1,184,112,116,121,118,59,1,10674,116,5,162,2,59,101,8112,8114,1,162,114,100,111,116,59,1,183,114,59,3,55349,56608,4,3,99,101,105,8134,8138,8154,121,59,1,1095,99,107,4,2,59,109,8146,8148,1,10003,97,114,107,59,1,10003,59,1,967,114,4,7,59,69,99,101,102,109,115,8174,8176,8179,8258,8261,8268,8273,1,9675,59,1,10691,4,3,59,101,108,8187,8189,8193,1,710,113,59,1,8791,101,4,2,97,100,8200,8223,114,114,111,119,4,2,108,114,8210,8216,101,102,116,59,1,8634,105,103,104,116,59,1,8635,4,5,82,83,97,99,100,8235,8238,8241,8246,8252,59,1,174,59,1,9416,115,116,59,1,8859,105,114,99,59,1,8858,97,115,104,59,1,8861,59,1,8791,110,105,110,116,59,1,10768,105,100,59,1,10991,99,105,114,59,1,10690,117,98,115,4,2,59,117,8288,8290,1,9827,105,116,59,1,9827,4,4,108,109,110,112,8305,8326,8376,8400,111,110,4,2,59,101,8313,8315,1,58,4,2,59,113,8321,8323,1,8788,59,1,8788,4,2,109,112,8332,8344,97,4,2,59,116,8339,8341,1,44,59,1,64,4,3,59,102,108,8352,8354,8358,1,8705,110,59,1,8728,101,4,2,109,120,8365,8371,101,110,116,59,1,8705,101,115,59,1,8450,4,2,103,105,8382,8395,4,2,59,100,8388,8390,1,8773,111,116,59,1,10861,110,116,59,1,8750,4,3,102,114,121,8408,8412,8417,59,3,55349,56660,111,100,59,1,8720,5,169,2,59,115,8424,8426,1,169,114,59,1,8471,4,2,97,111,8436,8441,114,114,59,1,8629,115,115,59,1,10007,4,2,99,117,8452,8457,114,59,3,55349,56504,4,2,98,112,8463,8474,4,2,59,101,8469,8471,1,10959,59,1,10961,4,2,59,101,8480,8482,1,10960,59,1,10962,100,111,116,59,1,8943,4,7,100,101,108,112,114,118,119,8507,8522,8536,8550,8600,8697,8702,97,114,114,4,2,108,114,8516,8519,59,1,10552,59,1,10549,4,2,112,115,8528,8532,114,59,1,8926,99,59,1,8927,97,114,114,4,2,59,112,8545,8547,1,8630,59,1,10557,4,6,59,98,99,100,111,115,8564,8566,8573,8587,8592,8596,1,8746,114,99,97,112,59,1,10824,4,2,97,117,8579,8583,112,59,1,10822,112,59,1,10826,111,116,59,1,8845,114,59,1,10821,59,3,8746,65024,4,4,97,108,114,118,8610,8623,8663,8672,114,114,4,2,59,109,8618,8620,1,8631,59,1,10556,121,4,3,101,118,119,8632,8651,8656,113,4,2,112,115,8639,8645,114,101,99,59,1,8926,117,99,99,59,1,8927,101,101,59,1,8910,101,100,103,101,59,1,8911,101,110,5,164,1,59,8670,1,164,101,97,114,114,111,119,4,2,108,114,8684,8690,101,102,116,59,1,8630,105,103,104,116,59,1,8631,101,101,59,1,8910,101,100,59,1,8911,4,2,99,105,8713,8721,111,110,105,110,116,59,1,8754,110,116,59,1,8753,108,99,116,121,59,1,9005,4,19,65,72,97,98,99,100,101,102,104,105,106,108,111,114,115,116,117,119,122,8773,8778,8783,8821,8839,8854,8887,8914,8930,8944,9036,9041,9058,9197,9227,9258,9281,9297,9305,114,114,59,1,8659,97,114,59,1,10597,4,4,103,108,114,115,8793,8799,8805,8809,103,101,114,59,1,8224,101,116,104,59,1,8504,114,59,1,8595,104,4,2,59,118,8816,8818,1,8208,59,1,8867,4,2,107,108,8827,8834,97,114,111,119,59,1,10511,97,99,59,1,733,4,2,97,121,8845,8851,114,111,110,59,1,271,59,1,1076,4,3,59,97,111,8862,8864,8880,1,8518,4,2,103,114,8870,8876,103,101,114,59,1,8225,114,59,1,8650,116,115,101,113,59,1,10871,4,3,103,108,109,8895,8902,8907,5,176,1,59,8900,1,176,116,97,59,1,948,112,116,121,118,59,1,10673,4,2,105,114,8920,8926,115,104,116,59,1,10623,59,3,55349,56609,97,114,4,2,108,114,8938,8941,59,1,8643,59,1,8642,4,5,97,101,103,115,118,8956,8986,8989,8996,9001,109,4,3,59,111,115,8965,8967,8983,1,8900,110,100,4,2,59,115,8975,8977,1,8900,117,105,116,59,1,9830,59,1,9830,59,1,168,97,109,109,97,59,1,989,105,110,59,1,8946,4,3,59,105,111,9009,9011,9031,1,247,100,101,5,247,2,59,111,9020,9022,1,247,110,116,105,109,101,115,59,1,8903,110,120,59,1,8903,99,121,59,1,1106,99,4,2,111,114,9048,9053,114,110,59,1,8990,111,112,59,1,8973,4,5,108,112,116,117,119,9070,9076,9081,9130,9144,108,97,114,59,1,36,102,59,3,55349,56661,4,5,59,101,109,112,115,9093,9095,9109,9116,9122,1,729,113,4,2,59,100,9102,9104,1,8784,111,116,59,1,8785,105,110,117,115,59,1,8760,108,117,115,59,1,8724,113,117,97,114,101,59,1,8865,98,108,101,98,97,114,119,101,100,103,101,59,1,8966,110,4,3,97,100,104,9153,9160,9172,114,114,111,119,59,1,8595,111,119,110,97,114,114,111,119,115,59,1,8650,97,114,112,111,111,110,4,2,108,114,9184,9190,101,102,116,59,1,8643,105,103,104,116,59,1,8642,4,2,98,99,9203,9211,107,97,114,111,119,59,1,10512,4,2,111,114,9217,9222,114,110,59,1,8991,111,112,59,1,8972,4,3,99,111,116,9235,9248,9252,4,2,114,121,9241,9245,59,3,55349,56505,59,1,1109,108,59,1,10742,114,111,107,59,1,273,4,2,100,114,9264,9269,111,116,59,1,8945,105,4,2,59,102,9276,9278,1,9663,59,1,9662,4,2,97,104,9287,9292,114,114,59,1,8693,97,114,59,1,10607,97,110,103,108,101,59,1,10662,4,2,99,105,9311,9315,121,59,1,1119,103,114,97,114,114,59,1,10239,4,18,68,97,99,100,101,102,103,108,109,110,111,112,113,114,115,116,117,120,9361,9376,9398,9439,9444,9447,9462,9495,9531,9585,9598,9614,9659,9755,9771,9792,9808,9826,4,2,68,111,9367,9372,111,116,59,1,10871,116,59,1,8785,4,2,99,115,9382,9392,117,116,101,5,233,1,59,9390,1,233,116,101,114,59,1,10862,4,4,97,105,111,121,9408,9414,9430,9436,114,111,110,59,1,283,114,4,2,59,99,9421,9423,1,8790,5,234,1,59,9428,1,234,108,111,110,59,1,8789,59,1,1101,111,116,59,1,279,59,1,8519,4,2,68,114,9453,9458,111,116,59,1,8786,59,3,55349,56610,4,3,59,114,115,9470,9472,9482,1,10906,97,118,101,5,232,1,59,9480,1,232,4,2,59,100,9488,9490,1,10902,111,116,59,1,10904,4,4,59,105,108,115,9505,9507,9515,9518,1,10905,110,116,101,114,115,59,1,9191,59,1,8467,4,2,59,100,9524,9526,1,10901,111,116,59,1,10903,4,3,97,112,115,9539,9544,9564,99,114,59,1,275,116,121,4,3,59,115,118,9554,9556,9561,1,8709,101,116,59,1,8709,59,1,8709,112,4,2,49,59,9571,9583,4,2,51,52,9577,9580,59,1,8196,59,1,8197,1,8195,4,2,103,115,9591,9594,59,1,331,112,59,1,8194,4,2,103,112,9604,9609,111,110,59,1,281,102,59,3,55349,56662,4,3,97,108,115,9622,9635,9640,114,4,2,59,115,9629,9631,1,8917,108,59,1,10723,117,115,59,1,10865,105,4,3,59,108,118,9649,9651,9656,1,949,111,110,59,1,949,59,1,1013,4,4,99,115,117,118,9669,9686,9716,9747,4,2,105,111,9675,9680,114,99,59,1,8790,108,111,110,59,1,8789,4,2,105,108,9692,9696,109,59,1,8770,97,110,116,4,2,103,108,9705,9710,116,114,59,1,10902,101,115,115,59,1,10901,4,3,97,101,105,9724,9729,9734,108,115,59,1,61,115,116,59,1,8799,118,4,2,59,68,9741,9743,1,8801,68,59,1,10872,112,97,114,115,108,59,1,10725,4,2,68,97,9761,9766,111,116,59,1,8787,114,114,59,1,10609,4,3,99,100,105,9779,9783,9788,114,59,1,8495,111,116,59,1,8784,109,59,1,8770,4,2,97,104,9798,9801,59,1,951,5,240,1,59,9806,1,240,4,2,109,114,9814,9822,108,5,235,1,59,9820,1,235,111,59,1,8364,4,3,99,105,112,9834,9838,9843,108,59,1,33,115,116,59,1,8707,4,2,101,111,9849,9859,99,116,97,116,105,111,110,59,1,8496,110,101,110,116,105,97,108,101,59,1,8519,4,12,97,99,101,102,105,106,108,110,111,112,114,115,9896,9910,9914,9921,9954,9960,9967,9989,9994,10027,10036,10164,108,108,105,110,103,100,111,116,115,101,113,59,1,8786,121,59,1,1092,109,97,108,101,59,1,9792,4,3,105,108,114,9929,9935,9950,108,105,103,59,1,64259,4,2,105,108,9941,9945,103,59,1,64256,105,103,59,1,64260,59,3,55349,56611,108,105,103,59,1,64257,108,105,103,59,3,102,106,4,3,97,108,116,9975,9979,9984,116,59,1,9837,105,103,59,1,64258,110,115,59,1,9649,111,102,59,1,402,4,2,112,114,10000,10005,102,59,3,55349,56663,4,2,97,107,10011,10016,108,108,59,1,8704,4,2,59,118,10022,10024,1,8916,59,1,10969,97,114,116,105,110,116,59,1,10765,4,2,97,111,10042,10159,4,2,99,115,10048,10155,4,6,49,50,51,52,53,55,10062,10102,10114,10135,10139,10151,4,6,50,51,52,53,54,56,10076,10083,10086,10093,10096,10099,5,189,1,59,10081,1,189,59,1,8531,5,188,1,59,10091,1,188,59,1,8533,59,1,8537,59,1,8539,4,2,51,53,10108,10111,59,1,8532,59,1,8534,4,3,52,53,56,10122,10129,10132,5,190,1,59,10127,1,190,59,1,8535,59,1,8540,53,59,1,8536,4,2,54,56,10145,10148,59,1,8538,59,1,8541,56,59,1,8542,108,59,1,8260,119,110,59,1,8994,99,114,59,3,55349,56507,4,17,69,97,98,99,100,101,102,103,105,106,108,110,111,114,115,116,118,10206,10217,10247,10254,10268,10273,10358,10363,10374,10380,10385,10406,10458,10464,10470,10497,10610,4,2,59,108,10212,10214,1,8807,59,1,10892,4,3,99,109,112,10225,10231,10244,117,116,101,59,1,501,109,97,4,2,59,100,10239,10241,1,947,59,1,989,59,1,10886,114,101,118,101,59,1,287,4,2,105,121,10260,10265,114,99,59,1,285,59,1,1075,111,116,59,1,289,4,4,59,108,113,115,10283,10285,10288,10308,1,8805,59,1,8923,4,3,59,113,115,10296,10298,10301,1,8805,59,1,8807,108,97,110,116,59,1,10878,4,4,59,99,100,108,10318,10320,10324,10345,1,10878,99,59,1,10921,111,116,4,2,59,111,10332,10334,1,10880,4,2,59,108,10340,10342,1,10882,59,1,10884,4,2,59,101,10351,10354,3,8923,65024,115,59,1,10900,114,59,3,55349,56612,4,2,59,103,10369,10371,1,8811,59,1,8921,109,101,108,59,1,8503,99,121,59,1,1107,4,4,59,69,97,106,10395,10397,10400,10403,1,8823,59,1,10898,59,1,10917,59,1,10916,4,4,69,97,101,115,10416,10419,10434,10453,59,1,8809,112,4,2,59,112,10426,10428,1,10890,114,111,120,59,1,10890,4,2,59,113,10440,10442,1,10888,4,2,59,113,10448,10450,1,10888,59,1,8809,105,109,59,1,8935,112,102,59,3,55349,56664,97,118,101,59,1,96,4,2,99,105,10476,10480,114,59,1,8458,109,4,3,59,101,108,10489,10491,10494,1,8819,59,1,10894,59,1,10896,5,62,6,59,99,100,108,113,114,10512,10514,10527,10532,10538,10545,1,62,4,2,99,105,10520,10523,59,1,10919,114,59,1,10874,111,116,59,1,8919,80,97,114,59,1,10645,117,101,115,116,59,1,10876,4,5,97,100,101,108,115,10557,10574,10579,10599,10605,4,2,112,114,10563,10570,112,114,111,120,59,1,10886,114,59,1,10616,111,116,59,1,8919,113,4,2,108,113,10586,10592,101,115,115,59,1,8923,108,101,115,115,59,1,10892,101,115,115,59,1,8823,105,109,59,1,8819,4,2,101,110,10616,10626,114,116,110,101,113,113,59,3,8809,65024,69,59,3,8809,65024,4,10,65,97,98,99,101,102,107,111,115,121,10653,10658,10713,10718,10724,10760,10765,10786,10850,10875,114,114,59,1,8660,4,4,105,108,109,114,10668,10674,10678,10684,114,115,112,59,1,8202,102,59,1,189,105,108,116,59,1,8459,4,2,100,114,10690,10695,99,121,59,1,1098,4,3,59,99,119,10703,10705,10710,1,8596,105,114,59,1,10568,59,1,8621,97,114,59,1,8463,105,114,99,59,1,293,4,3,97,108,114,10732,10748,10754,114,116,115,4,2,59,117,10741,10743,1,9829,105,116,59,1,9829,108,105,112,59,1,8230,99,111,110,59,1,8889,114,59,3,55349,56613,115,4,2,101,119,10772,10779,97,114,111,119,59,1,10533,97,114,111,119,59,1,10534,4,5,97,109,111,112,114,10798,10803,10809,10839,10844,114,114,59,1,8703,116,104,116,59,1,8763,107,4,2,108,114,10816,10827,101,102,116,97,114,114,111,119,59,1,8617,105,103,104,116,97,114,114,111,119,59,1,8618,102,59,3,55349,56665,98,97,114,59,1,8213,4,3,99,108,116,10858,10863,10869,114,59,3,55349,56509,97,115,104,59,1,8463,114,111,107,59,1,295,4,2,98,112,10881,10887,117,108,108,59,1,8259,104,101,110,59,1,8208,4,15,97,99,101,102,103,105,106,109,110,111,112,113,115,116,117,10925,10936,10958,10977,10990,11001,11039,11045,11101,11192,11220,11226,11237,11285,11299,99,117,116,101,5,237,1,59,10934,1,237,4,3,59,105,121,10944,10946,10955,1,8291,114,99,5,238,1,59,10953,1,238,59,1,1080,4,2,99,120,10964,10968,121,59,1,1077,99,108,5,161,1,59,10975,1,161,4,2,102,114,10983,10986,59,1,8660,59,3,55349,56614,114,97,118,101,5,236,1,59,10999,1,236,4,4,59,105,110,111,11011,11013,11028,11034,1,8520,4,2,105,110,11019,11024,110,116,59,1,10764,116,59,1,8749,102,105,110,59,1,10716,116,97,59,1,8489,108,105,103,59,1,307,4,3,97,111,112,11053,11092,11096,4,3,99,103,116,11061,11065,11088,114,59,1,299,4,3,101,108,112,11073,11076,11082,59,1,8465,105,110,101,59,1,8464,97,114,116,59,1,8465,104,59,1,305,102,59,1,8887,101,100,59,1,437,4,5,59,99,102,111,116,11113,11115,11121,11136,11142,1,8712,97,114,101,59,1,8453,105,110,4,2,59,116,11129,11131,1,8734,105,101,59,1,10717,100,111,116,59,1,305,4,5,59,99,101,108,112,11154,11156,11161,11179,11186,1,8747,97,108,59,1,8890,4,2,103,114,11167,11173,101,114,115,59,1,8484,99,97,108,59,1,8890,97,114,104,107,59,1,10775,114,111,100,59,1,10812,4,4,99,103,112,116,11202,11206,11211,11216,121,59,1,1105,111,110,59,1,303,102,59,3,55349,56666,97,59,1,953,114,111,100,59,1,10812,117,101,115,116,5,191,1,59,11235,1,191,4,2,99,105,11243,11248,114,59,3,55349,56510,110,4,5,59,69,100,115,118,11261,11263,11266,11271,11282,1,8712,59,1,8953,111,116,59,1,8949,4,2,59,118,11277,11279,1,8948,59,1,8947,59,1,8712,4,2,59,105,11291,11293,1,8290,108,100,101,59,1,297,4,2,107,109,11305,11310,99,121,59,1,1110,108,5,239,1,59,11316,1,239,4,6,99,102,109,111,115,117,11332,11346,11351,11357,11363,11380,4,2,105,121,11338,11343,114,99,59,1,309,59,1,1081,114,59,3,55349,56615,97,116,104,59,1,567,112,102,59,3,55349,56667,4,2,99,101,11369,11374,114,59,3,55349,56511,114,99,121,59,1,1112,107,99,121,59,1,1108,4,8,97,99,102,103,104,106,111,115,11404,11418,11433,11438,11445,11450,11455,11461,112,112,97,4,2,59,118,11413,11415,1,954,59,1,1008,4,2,101,121,11424,11430,100,105,108,59,1,311,59,1,1082,114,59,3,55349,56616,114,101,101,110,59,1,312,99,121,59,1,1093,99,121,59,1,1116,112,102,59,3,55349,56668,99,114,59,3,55349,56512,4,23,65,66,69,72,97,98,99,100,101,102,103,104,106,108,109,110,111,112,114,115,116,117,118,11515,11538,11544,11555,11560,11721,11780,11818,11868,12136,12160,12171,12203,12208,12246,12275,12327,12509,12523,12569,12641,12732,12752,4,3,97,114,116,11523,11528,11532,114,114,59,1,8666,114,59,1,8656,97,105,108,59,1,10523,97,114,114,59,1,10510,4,2,59,103,11550,11552,1,8806,59,1,10891,97,114,59,1,10594,4,9,99,101,103,109,110,112,113,114,116,11580,11586,11594,11600,11606,11624,11627,11636,11694,117,116,101,59,1,314,109,112,116,121,118,59,1,10676,114,97,110,59,1,8466,98,100,97,59,1,955,103,4,3,59,100,108,11615,11617,11620,1,10216,59,1,10641,101,59,1,10216,59,1,10885,117,111,5,171,1,59,11634,1,171,114,4,8,59,98,102,104,108,112,115,116,11655,11657,11669,11673,11677,11681,11685,11690,1,8592,4,2,59,102,11663,11665,1,8676,115,59,1,10527,115,59,1,10525,107,59,1,8617,112,59,1,8619,108,59,1,10553,105,109,59,1,10611,108,59,1,8610,4,3,59,97,101,11702,11704,11709,1,10923,105,108,59,1,10521,4,2,59,115,11715,11717,1,10925,59,3,10925,65024,4,3,97,98,114,11729,11734,11739,114,114,59,1,10508,114,107,59,1,10098,4,2,97,107,11745,11758,99,4,2,101,107,11752,11755,59,1,123,59,1,91,4,2,101,115,11764,11767,59,1,10635,108,4,2,100,117,11774,11777,59,1,10639,59,1,10637,4,4,97,101,117,121,11790,11796,11811,11815,114,111,110,59,1,318,4,2,100,105,11802,11807,105,108,59,1,316,108,59,1,8968,98,59,1,123,59,1,1083,4,4,99,113,114,115,11828,11832,11845,11864,97,59,1,10550,117,111,4,2,59,114,11840,11842,1,8220,59,1,8222,4,2,100,117,11851,11857,104,97,114,59,1,10599,115,104,97,114,59,1,10571,104,59,1,8626,4,5,59,102,103,113,115,11880,11882,12008,12011,12031,1,8804,116,4,5,97,104,108,114,116,11895,11913,11935,11947,11996,114,114,111,119,4,2,59,116,11905,11907,1,8592,97,105,108,59,1,8610,97,114,112,111,111,110,4,2,100,117,11925,11931,111,119,110,59,1,8637,112,59,1,8636,101,102,116,97,114,114,111,119,115,59,1,8647,105,103,104,116,4,3,97,104,115,11959,11974,11984,114,114,111,119,4,2,59,115,11969,11971,1,8596,59,1,8646,97,114,112,111,111,110,115,59,1,8651,113,117,105,103,97,114,114,111,119,59,1,8621,104,114,101,101,116,105,109,101,115,59,1,8907,59,1,8922,4,3,59,113,115,12019,12021,12024,1,8804,59,1,8806,108,97,110,116,59,1,10877,4,5,59,99,100,103,115,12043,12045,12049,12070,12083,1,10877,99,59,1,10920,111,116,4,2,59,111,12057,12059,1,10879,4,2,59,114,12065,12067,1,10881,59,1,10883,4,2,59,101,12076,12079,3,8922,65024,115,59,1,10899,4,5,97,100,101,103,115,12095,12103,12108,12126,12131,112,112,114,111,120,59,1,10885,111,116,59,1,8918,113,4,2,103,113,12115,12120,116,114,59,1,8922,103,116,114,59,1,10891,116,114,59,1,8822,105,109,59,1,8818,4,3,105,108,114,12144,12150,12156,115,104,116,59,1,10620,111,111,114,59,1,8970,59,3,55349,56617,4,2,59,69,12166,12168,1,8822,59,1,10897,4,2,97,98,12177,12198,114,4,2,100,117,12184,12187,59,1,8637,4,2,59,108,12193,12195,1,8636,59,1,10602,108,107,59,1,9604,99,121,59,1,1113,4,5,59,97,99,104,116,12220,12222,12227,12235,12241,1,8810,114,114,59,1,8647,111,114,110,101,114,59,1,8990,97,114,100,59,1,10603,114,105,59,1,9722,4,2,105,111,12252,12258,100,111,116,59,1,320,117,115,116,4,2,59,97,12267,12269,1,9136,99,104,101,59,1,9136,4,4,69,97,101,115,12285,12288,12303,12322,59,1,8808,112,4,2,59,112,12295,12297,1,10889,114,111,120,59,1,10889,4,2,59,113,12309,12311,1,10887,4,2,59,113,12317,12319,1,10887,59,1,8808,105,109,59,1,8934,4,8,97,98,110,111,112,116,119,122,12345,12359,12364,12421,12446,12467,12474,12490,4,2,110,114,12351,12355,103,59,1,10220,114,59,1,8701,114,107,59,1,10214,103,4,3,108,109,114,12373,12401,12409,101,102,116,4,2,97,114,12382,12389,114,114,111,119,59,1,10229,105,103,104,116,97,114,114,111,119,59,1,10231,97,112,115,116,111,59,1,10236,105,103,104,116,97,114,114,111,119,59,1,10230,112,97,114,114,111,119,4,2,108,114,12433,12439,101,102,116,59,1,8619,105,103,104,116,59,1,8620,4,3,97,102,108,12454,12458,12462,114,59,1,10629,59,3,55349,56669,117,115,59,1,10797,105,109,101,115,59,1,10804,4,2,97,98,12480,12485,115,116,59,1,8727,97,114,59,1,95,4,3,59,101,102,12498,12500,12506,1,9674,110,103,101,59,1,9674,59,1,10731,97,114,4,2,59,108,12517,12519,1,40,116,59,1,10643,4,5,97,99,104,109,116,12535,12540,12548,12561,12564,114,114,59,1,8646,111,114,110,101,114,59,1,8991,97,114,4,2,59,100,12556,12558,1,8651,59,1,10605,59,1,8206,114,105,59,1,8895,4,6,97,99,104,105,113,116,12583,12589,12594,12597,12614,12635,113,117,111,59,1,8249,114,59,3,55349,56513,59,1,8624,109,4,3,59,101,103,12606,12608,12611,1,8818,59,1,10893,59,1,10895,4,2,98,117,12620,12623,59,1,91,111,4,2,59,114,12630,12632,1,8216,59,1,8218,114,111,107,59,1,322,5,60,8,59,99,100,104,105,108,113,114,12660,12662,12675,12680,12686,12692,12698,12705,1,60,4,2,99,105,12668,12671,59,1,10918,114,59,1,10873,111,116,59,1,8918,114,101,101,59,1,8907,109,101,115,59,1,8905,97,114,114,59,1,10614,117,101,115,116,59,1,10875,4,2,80,105,12711,12716,97,114,59,1,10646,4,3,59,101,102,12724,12726,12729,1,9667,59,1,8884,59,1,9666,114,4,2,100,117,12739,12746,115,104,97,114,59,1,10570,104,97,114,59,1,10598,4,2,101,110,12758,12768,114,116,110,101,113,113,59,3,8808,65024,69,59,3,8808,65024,4,14,68,97,99,100,101,102,104,105,108,110,111,112,115,117,12803,12809,12893,12908,12914,12928,12933,12937,13011,13025,13032,13049,13052,13069,68,111,116,59,1,8762,4,4,99,108,112,114,12819,12827,12849,12887,114,5,175,1,59,12825,1,175,4,2,101,116,12833,12836,59,1,9794,4,2,59,101,12842,12844,1,10016,115,101,59,1,10016,4,2,59,115,12855,12857,1,8614,116,111,4,4,59,100,108,117,12869,12871,12877,12883,1,8614,111,119,110,59,1,8615,101,102,116,59,1,8612,112,59,1,8613,107,101,114,59,1,9646,4,2,111,121,12899,12905,109,109,97,59,1,10793,59,1,1084,97,115,104,59,1,8212,97,115,117,114,101,100,97,110,103,108,101,59,1,8737,114,59,3,55349,56618,111,59,1,8487,4,3,99,100,110,12945,12954,12985,114,111,5,181,1,59,12952,1,181,4,4,59,97,99,100,12964,12966,12971,12976,1,8739,115,116,59,1,42,105,114,59,1,10992,111,116,5,183,1,59,12983,1,183,117,115,4,3,59,98,100,12995,12997,13000,1,8722,59,1,8863,4,2,59,117,13006,13008,1,8760,59,1,10794,4,2,99,100,13017,13021,112,59,1,10971,114,59,1,8230,112,108,117,115,59,1,8723,4,2,100,112,13038,13044,101,108,115,59,1,8871,102,59,3,55349,56670,59,1,8723,4,2,99,116,13058,13063,114,59,3,55349,56514,112,111,115,59,1,8766,4,3,59,108,109,13077,13079,13087,1,956,116,105,109,97,112,59,1,8888,97,112,59,1,8888,4,24,71,76,82,86,97,98,99,100,101,102,103,104,105,106,108,109,111,112,114,115,116,117,118,119,13142,13165,13217,13229,13247,13330,13359,13414,13420,13508,13513,13579,13602,13626,13631,13762,13767,13855,13936,13995,14214,14285,14312,14432,4,2,103,116,13148,13152,59,3,8921,824,4,2,59,118,13158,13161,3,8811,8402,59,3,8811,824,4,3,101,108,116,13173,13200,13204,102,116,4,2,97,114,13181,13188,114,114,111,119,59,1,8653,105,103,104,116,97,114,114,111,119,59,1,8654,59,3,8920,824,4,2,59,118,13210,13213,3,8810,8402,59,3,8810,824,105,103,104,116,97,114,114,111,119,59,1,8655,4,2,68,100,13235,13241,97,115,104,59,1,8879,97,115,104,59,1,8878,4,5,98,99,110,112,116,13259,13264,13270,13275,13308,108,97,59,1,8711,117,116,101,59,1,324,103,59,3,8736,8402,4,5,59,69,105,111,112,13287,13289,13293,13298,13302,1,8777,59,3,10864,824,100,59,3,8779,824,115,59,1,329,114,111,120,59,1,8777,117,114,4,2,59,97,13316,13318,1,9838,108,4,2,59,115,13325,13327,1,9838,59,1,8469,4,2,115,117,13336,13344,112,5,160,1,59,13342,1,160,109,112,4,2,59,101,13352,13355,3,8782,824,59,3,8783,824,4,5,97,101,111,117,121,13371,13385,13391,13407,13411,4,2,112,114,13377,13380,59,1,10819,111,110,59,1,328,100,105,108,59,1,326,110,103,4,2,59,100,13399,13401,1,8775,111,116,59,3,10861,824,112,59,1,10818,59,1,1085,97,115,104,59,1,8211,4,7,59,65,97,100,113,115,120,13436,13438,13443,13466,13472,13478,13494,1,8800,114,114,59,1,8663,114,4,2,104,114,13450,13454,107,59,1,10532,4,2,59,111,13460,13462,1,8599,119,59,1,8599,111,116,59,3,8784,824,117,105,118,59,1,8802,4,2,101,105,13484,13489,97,114,59,1,10536,109,59,3,8770,824,105,115,116,4,2,59,115,13503,13505,1,8708,59,1,8708,114,59,3,55349,56619,4,4,69,101,115,116,13523,13527,13563,13568,59,3,8807,824,4,3,59,113,115,13535,13537,13559,1,8817,4,3,59,113,115,13545,13547,13551,1,8817,59,3,8807,824,108,97,110,116,59,3,10878,824,59,3,10878,824,105,109,59,1,8821,4,2,59,114,13574,13576,1,8815,59,1,8815,4,3,65,97,112,13587,13592,13597,114,114,59,1,8654,114,114,59,1,8622,97,114,59,1,10994,4,3,59,115,118,13610,13612,13623,1,8715,4,2,59,100,13618,13620,1,8956,59,1,8954,59,1,8715,99,121,59,1,1114,4,7,65,69,97,100,101,115,116,13647,13652,13656,13661,13665,13737,13742,114,114,59,1,8653,59,3,8806,824,114,114,59,1,8602,114,59,1,8229,4,4,59,102,113,115,13675,13677,13703,13725,1,8816,116,4,2,97,114,13684,13691,114,114,111,119,59,1,8602,105,103,104,116,97,114,114,111,119,59,1,8622,4,3,59,113,115,13711,13713,13717,1,8816,59,3,8806,824,108,97,110,116,59,3,10877,824,4,2,59,115,13731,13734,3,10877,824,59,1,8814,105,109,59,1,8820,4,2,59,114,13748,13750,1,8814,105,4,2,59,101,13757,13759,1,8938,59,1,8940,105,100,59,1,8740,4,2,112,116,13773,13778,102,59,3,55349,56671,5,172,3,59,105,110,13787,13789,13829,1,172,110,4,4,59,69,100,118,13800,13802,13806,13812,1,8713,59,3,8953,824,111,116,59,3,8949,824,4,3,97,98,99,13820,13823,13826,59,1,8713,59,1,8951,59,1,8950,105,4,2,59,118,13836,13838,1,8716,4,3,97,98,99,13846,13849,13852,59,1,8716,59,1,8958,59,1,8957,4,3,97,111,114,13863,13892,13899,114,4,4,59,97,115,116,13874,13876,13883,13888,1,8742,108,108,101,108,59,1,8742,108,59,3,11005,8421,59,3,8706,824,108,105,110,116,59,1,10772,4,3,59,99,101,13907,13909,13914,1,8832,117,101,59,1,8928,4,2,59,99,13920,13923,3,10927,824,4,2,59,101,13929,13931,1,8832,113,59,3,10927,824,4,4,65,97,105,116,13946,13951,13971,13982,114,114,59,1,8655,114,114,4,3,59,99,119,13961,13963,13967,1,8603,59,3,10547,824,59,3,8605,824,103,104,116,97,114,114,111,119,59,1,8603,114,105,4,2,59,101,13990,13992,1,8939,59,1,8941,4,7,99,104,105,109,112,113,117,14011,14036,14060,14080,14085,14090,14106,4,4,59,99,101,114,14021,14023,14028,14032,1,8833,117,101,59,1,8929,59,3,10928,824,59,3,55349,56515,111,114,116,4,2,109,112,14045,14050,105,100,59,1,8740,97,114,97,108,108,101,108,59,1,8742,109,4,2,59,101,14067,14069,1,8769,4,2,59,113,14075,14077,1,8772,59,1,8772,105,100,59,1,8740,97,114,59,1,8742,115,117,4,2,98,112,14098,14102,101,59,1,8930,101,59,1,8931,4,3,98,99,112,14114,14157,14171,4,4,59,69,101,115,14124,14126,14130,14133,1,8836,59,3,10949,824,59,1,8840,101,116,4,2,59,101,14141,14144,3,8834,8402,113,4,2,59,113,14151,14153,1,8840,59,3,10949,824,99,4,2,59,101,14164,14166,1,8833,113,59,3,10928,824,4,4,59,69,101,115,14181,14183,14187,14190,1,8837,59,3,10950,824,59,1,8841,101,116,4,2,59,101,14198,14201,3,8835,8402,113,4,2,59,113,14208,14210,1,8841,59,3,10950,824,4,4,103,105,108,114,14224,14228,14238,14242,108,59,1,8825,108,100,101,5,241,1,59,14236,1,241,103,59,1,8824,105,97,110,103,108,101,4,2,108,114,14254,14269,101,102,116,4,2,59,101,14263,14265,1,8938,113,59,1,8940,105,103,104,116,4,2,59,101,14279,14281,1,8939,113,59,1,8941,4,2,59,109,14291,14293,1,957,4,3,59,101,115,14301,14303,14308,1,35,114,111,59,1,8470,112,59,1,8199,4,9,68,72,97,100,103,105,108,114,115,14332,14338,14344,14349,14355,14369,14376,14408,14426,97,115,104,59,1,8877,97,114,114,59,1,10500,112,59,3,8781,8402,97,115,104,59,1,8876,4,2,101,116,14361,14365,59,3,8805,8402,59,3,62,8402,110,102,105,110,59,1,10718,4,3,65,101,116,14384,14389,14393,114,114,59,1,10498,59,3,8804,8402,4,2,59,114,14399,14402,3,60,8402,105,101,59,3,8884,8402,4,2,65,116,14414,14419,114,114,59,1,10499,114,105,101,59,3,8885,8402,105,109,59,3,8764,8402,4,3,65,97,110,14440,14445,14468,114,114,59,1,8662,114,4,2,104,114,14452,14456,107,59,1,10531,4,2,59,111,14462,14464,1,8598,119,59,1,8598,101,97,114,59,1,10535,4,18,83,97,99,100,101,102,103,104,105,108,109,111,112,114,115,116,117,118,14512,14515,14535,14560,14597,14603,14618,14643,14657,14662,14701,14741,14747,14769,14851,14877,14907,14916,59,1,9416,4,2,99,115,14521,14531,117,116,101,5,243,1,59,14529,1,243,116,59,1,8859,4,2,105,121,14541,14557,114,4,2,59,99,14548,14550,1,8858,5,244,1,59,14555,1,244,59,1,1086,4,5,97,98,105,111,115,14572,14577,14583,14587,14591,115,104,59,1,8861,108,97,99,59,1,337,118,59,1,10808,116,59,1,8857,111,108,100,59,1,10684,108,105,103,59,1,339,4,2,99,114,14609,14614,105,114,59,1,10687,59,3,55349,56620,4,3,111,114,116,14626,14630,14640,110,59,1,731,97,118,101,5,242,1,59,14638,1,242,59,1,10689,4,2,98,109,14649,14654,97,114,59,1,10677,59,1,937,110,116,59,1,8750,4,4,97,99,105,116,14672,14677,14693,14698,114,114,59,1,8634,4,2,105,114,14683,14687,114,59,1,10686,111,115,115,59,1,10683,110,101,59,1,8254,59,1,10688,4,3,97,101,105,14709,14714,14719,99,114,59,1,333,103,97,59,1,969,4,3,99,100,110,14727,14733,14736,114,111,110,59,1,959,59,1,10678,117,115,59,1,8854,112,102,59,3,55349,56672,4,3,97,101,108,14755,14759,14764,114,59,1,10679,114,112,59,1,10681,117,115,59,1,8853,4,7,59,97,100,105,111,115,118,14785,14787,14792,14831,14837,14841,14848,1,8744,114,114,59,1,8635,4,4,59,101,102,109,14802,14804,14817,14824,1,10845,114,4,2,59,111,14811,14813,1,8500,102,59,1,8500,5,170,1,59,14822,1,170,5,186,1,59,14829,1,186,103,111,102,59,1,8886,114,59,1,10838,108,111,112,101,59,1,10839,59,1,10843,4,3,99,108,111,14859,14863,14873,114,59,1,8500,97,115,104,5,248,1,59,14871,1,248,108,59,1,8856,105,4,2,108,109,14884,14893,100,101,5,245,1,59,14891,1,245,101,115,4,2,59,97,14901,14903,1,8855,115,59,1,10806,109,108,5,246,1,59,14914,1,246,98,97,114,59,1,9021,4,12,97,99,101,102,104,105,108,109,111,114,115,117,14948,14992,14996,15033,15038,15068,15090,15189,15192,15222,15427,15441,114,4,4,59,97,115,116,14959,14961,14976,14989,1,8741,5,182,2,59,108,14968,14970,1,182,108,101,108,59,1,8741,4,2,105,108,14982,14986,109,59,1,10995,59,1,11005,59,1,8706,121,59,1,1087,114,4,5,99,105,109,112,116,15009,15014,15019,15024,15027,110,116,59,1,37,111,100,59,1,46,105,108,59,1,8240,59,1,8869,101,110,107,59,1,8241,114,59,3,55349,56621,4,3,105,109,111,15046,15057,15063,4,2,59,118,15052,15054,1,966,59,1,981,109,97,116,59,1,8499,110,101,59,1,9742,4,3,59,116,118,15076,15078,15087,1,960,99,104,102,111,114,107,59,1,8916,59,1,982,4,2,97,117,15096,15119,110,4,2,99,107,15103,15115,107,4,2,59,104,15110,15112,1,8463,59,1,8462,118,59,1,8463,115,4,9,59,97,98,99,100,101,109,115,116,15140,15142,15148,15151,15156,15168,15171,15179,15184,1,43,99,105,114,59,1,10787,59,1,8862,105,114,59,1,10786,4,2,111,117,15162,15165,59,1,8724,59,1,10789,59,1,10866,110,5,177,1,59,15177,1,177,105,109,59,1,10790,119,111,59,1,10791,59,1,177,4,3,105,112,117,15200,15208,15213,110,116,105,110,116,59,1,10773,102,59,3,55349,56673,110,100,5,163,1,59,15220,1,163,4,10,59,69,97,99,101,105,110,111,115,117,15244,15246,15249,15253,15258,15334,15347,15367,15416,15421,1,8826,59,1,10931,112,59,1,10935,117,101,59,1,8828,4,2,59,99,15264,15266,1,10927,4,6,59,97,99,101,110,115,15280,15282,15290,15299,15303,15329,1,8826,112,112,114,111,120,59,1,10935,117,114,108,121,101,113,59,1,8828,113,59,1,10927,4,3,97,101,115,15311,15319,15324,112,112,114,111,120,59,1,10937,113,113,59,1,10933,105,109,59,1,8936,105,109,59,1,8830,109,101,4,2,59,115,15342,15344,1,8242,59,1,8473,4,3,69,97,115,15355,15358,15362,59,1,10933,112,59,1,10937,105,109,59,1,8936,4,3,100,102,112,15375,15378,15404,59,1,8719,4,3,97,108,115,15386,15392,15398,108,97,114,59,1,9006,105,110,101,59,1,8978,117,114,102,59,1,8979,4,2,59,116,15410,15412,1,8733,111,59,1,8733,105,109,59,1,8830,114,101,108,59,1,8880,4,2,99,105,15433,15438,114,59,3,55349,56517,59,1,968,110,99,115,112,59,1,8200,4,6,102,105,111,112,115,117,15462,15467,15472,15478,15485,15491,114,59,3,55349,56622,110,116,59,1,10764,112,102,59,3,55349,56674,114,105,109,101,59,1,8279,99,114,59,3,55349,56518,4,3,97,101,111,15499,15520,15534,116,4,2,101,105,15506,15515,114,110,105,111,110,115,59,1,8461,110,116,59,1,10774,115,116,4,2,59,101,15528,15530,1,63,113,59,1,8799,116,5,34,1,59,15540,1,34,4,21,65,66,72,97,98,99,100,101,102,104,105,108,109,110,111,112,114,115,116,117,120,15586,15609,15615,15620,15796,15855,15893,15931,15977,16001,16039,16183,16204,16222,16228,16285,16312,16318,16363,16408,16416,4,3,97,114,116,15594,15599,15603,114,114,59,1,8667,114,59,1,8658,97,105,108,59,1,10524,97,114,114,59,1,10511,97,114,59,1,10596,4,7,99,100,101,110,113,114,116,15636,15651,15656,15664,15687,15696,15770,4,2,101,117,15642,15646,59,3,8765,817,116,101,59,1,341,105,99,59,1,8730,109,112,116,121,118,59,1,10675,103,4,4,59,100,101,108,15675,15677,15680,15683,1,10217,59,1,10642,59,1,10661,101,59,1,10217,117,111,5,187,1,59,15694,1,187,114,4,11,59,97,98,99,102,104,108,112,115,116,119,15721,15723,15727,15739,15742,15746,15750,15754,15758,15763,15767,1,8594,112,59,1,10613,4,2,59,102,15733,15735,1,8677,115,59,1,10528,59,1,10547,115,59,1,10526,107,59,1,8618,112,59,1,8620,108,59,1,10565,105,109,59,1,10612,108,59,1,8611,59,1,8605,4,2,97,105,15776,15781,105,108,59,1,10522,111,4,2,59,110,15788,15790,1,8758,97,108,115,59,1,8474,4,3,97,98,114,15804,15809,15814,114,114,59,1,10509,114,107,59,1,10099,4,2,97,107,15820,15833,99,4,2,101,107,15827,15830,59,1,125,59,1,93,4,2,101,115,15839,15842,59,1,10636,108,4,2,100,117,15849,15852,59,1,10638,59,1,10640,4,4,97,101,117,121,15865,15871,15886,15890,114,111,110,59,1,345,4,2,100,105,15877,15882,105,108,59,1,343,108,59,1,8969,98,59,1,125,59,1,1088,4,4,99,108,113,115,15903,15907,15914,15927,97,59,1,10551,100,104,97,114,59,1,10601,117,111,4,2,59,114,15922,15924,1,8221,59,1,8221,104,59,1,8627,4,3,97,99,103,15939,15966,15970,108,4,4,59,105,112,115,15950,15952,15957,15963,1,8476,110,101,59,1,8475,97,114,116,59,1,8476,59,1,8477,116,59,1,9645,5,174,1,59,15975,1,174,4,3,105,108,114,15985,15991,15997,115,104,116,59,1,10621,111,111,114,59,1,8971,59,3,55349,56623,4,2,97,111,16007,16028,114,4,2,100,117,16014,16017,59,1,8641,4,2,59,108,16023,16025,1,8640,59,1,10604,4,2,59,118,16034,16036,1,961,59,1,1009,4,3,103,110,115,16047,16167,16171,104,116,4,6,97,104,108,114,115,116,16063,16081,16103,16130,16143,16155,114,114,111,119,4,2,59,116,16073,16075,1,8594,97,105,108,59,1,8611,97,114,112,111,111,110,4,2,100,117,16093,16099,111,119,110,59,1,8641,112,59,1,8640,101,102,116,4,2,97,104,16112,16120,114,114,111,119,115,59,1,8644,97,114,112,111,111,110,115,59,1,8652,105,103,104,116,97,114,114,111,119,115,59,1,8649,113,117,105,103,97,114,114,111,119,59,1,8605,104,114,101,101,116,105,109,101,115,59,1,8908,103,59,1,730,105,110,103,100,111,116,115,101,113,59,1,8787,4,3,97,104,109,16191,16196,16201,114,114,59,1,8644,97,114,59,1,8652,59,1,8207,111,117,115,116,4,2,59,97,16214,16216,1,9137,99,104,101,59,1,9137,109,105,100,59,1,10990,4,4,97,98,112,116,16238,16252,16257,16278,4,2,110,114,16244,16248,103,59,1,10221,114,59,1,8702,114,107,59,1,10215,4,3,97,102,108,16265,16269,16273,114,59,1,10630,59,3,55349,56675,117,115,59,1,10798,105,109,101,115,59,1,10805,4,2,97,112,16291,16304,114,4,2,59,103,16298,16300,1,41,116,59,1,10644,111,108,105,110,116,59,1,10770,97,114,114,59,1,8649,4,4,97,99,104,113,16328,16334,16339,16342,113,117,111,59,1,8250,114,59,3,55349,56519,59,1,8625,4,2,98,117,16348,16351,59,1,93,111,4,2,59,114,16358,16360,1,8217,59,1,8217,4,3,104,105,114,16371,16377,16383,114,101,101,59,1,8908,109,101,115,59,1,8906,105,4,4,59,101,102,108,16394,16396,16399,16402,1,9657,59,1,8885,59,1,9656,116,114,105,59,1,10702,108,117,104,97,114,59,1,10600,59,1,8478,4,19,97,98,99,100,101,102,104,105,108,109,111,112,113,114,115,116,117,119,122,16459,16466,16472,16572,16590,16672,16687,16746,16844,16850,16924,16963,16988,17115,17121,17154,17206,17614,17656,99,117,116,101,59,1,347,113,117,111,59,1,8218,4,10,59,69,97,99,101,105,110,112,115,121,16494,16496,16499,16513,16518,16531,16536,16556,16564,16569,1,8827,59,1,10932,4,2,112,114,16505,16508,59,1,10936,111,110,59,1,353,117,101,59,1,8829,4,2,59,100,16524,16526,1,10928,105,108,59,1,351,114,99,59,1,349,4,3,69,97,115,16544,16547,16551,59,1,10934,112,59,1,10938,105,109,59,1,8937,111,108,105,110,116,59,1,10771,105,109,59,1,8831,59,1,1089,111,116,4,3,59,98,101,16582,16584,16587,1,8901,59,1,8865,59,1,10854,4,7,65,97,99,109,115,116,120,16606,16611,16634,16642,16646,16652,16668,114,114,59,1,8664,114,4,2,104,114,16618,16622,107,59,1,10533,4,2,59,111,16628,16630,1,8600,119,59,1,8600,116,5,167,1,59,16640,1,167,105,59,1,59,119,97,114,59,1,10537,109,4,2,105,110,16659,16665,110,117,115,59,1,8726,59,1,8726,116,59,1,10038,114,4,2,59,111,16679,16682,3,55349,56624,119,110,59,1,8994,4,4,97,99,111,121,16697,16702,16716,16739,114,112,59,1,9839,4,2,104,121,16708,16713,99,121,59,1,1097,59,1,1096,114,116,4,2,109,112,16724,16729,105,100,59,1,8739,97,114,97,108,108,101,108,59,1,8741,5,173,1,59,16744,1,173,4,2,103,109,16752,16770,109,97,4,3,59,102,118,16762,16764,16767,1,963,59,1,962,59,1,962,4,8,59,100,101,103,108,110,112,114,16788,16790,16795,16806,16817,16828,16832,16838,1,8764,111,116,59,1,10858,4,2,59,113,16801,16803,1,8771,59,1,8771,4,2,59,69,16812,16814,1,10910,59,1,10912,4,2,59,69,16823,16825,1,10909,59,1,10911,101,59,1,8774,108,117,115,59,1,10788,97,114,114,59,1,10610,97,114,114,59,1,8592,4,4,97,101,105,116,16860,16883,16891,16904,4,2,108,115,16866,16878,108,115,101,116,109,105,110,117,115,59,1,8726,104,112,59,1,10803,112,97,114,115,108,59,1,10724,4,2,100,108,16897,16900,59,1,8739,101,59,1,8995,4,2,59,101,16910,16912,1,10922,4,2,59,115,16918,16920,1,10924,59,3,10924,65024,4,3,102,108,112,16932,16938,16958,116,99,121,59,1,1100,4,2,59,98,16944,16946,1,47,4,2,59,97,16952,16954,1,10692,114,59,1,9023,102,59,3,55349,56676,97,4,2,100,114,16970,16985,101,115,4,2,59,117,16978,16980,1,9824,105,116,59,1,9824,59,1,8741,4,3,99,115,117,16996,17028,17089,4,2,97,117,17002,17015,112,4,2,59,115,17009,17011,1,8851,59,3,8851,65024,112,4,2,59,115,17022,17024,1,8852,59,3,8852,65024,117,4,2,98,112,17035,17062,4,3,59,101,115,17043,17045,17048,1,8847,59,1,8849,101,116,4,2,59,101,17056,17058,1,8847,113,59,1,8849,4,3,59,101,115,17070,17072,17075,1,8848,59,1,8850,101,116,4,2,59,101,17083,17085,1,8848,113,59,1,8850,4,3,59,97,102,17097,17099,17112,1,9633,114,4,2,101,102,17106,17109,59,1,9633,59,1,9642,59,1,9642,97,114,114,59,1,8594,4,4,99,101,109,116,17131,17136,17142,17148,114,59,3,55349,56520,116,109,110,59,1,8726,105,108,101,59,1,8995,97,114,102,59,1,8902,4,2,97,114,17160,17172,114,4,2,59,102,17167,17169,1,9734,59,1,9733,4,2,97,110,17178,17202,105,103,104,116,4,2,101,112,17188,17197,112,115,105,108,111,110,59,1,1013,104,105,59,1,981,115,59,1,175,4,5,98,99,109,110,112,17218,17351,17420,17423,17427,4,9,59,69,100,101,109,110,112,114,115,17238,17240,17243,17248,17261,17267,17279,17285,17291,1,8834,59,1,10949,111,116,59,1,10941,4,2,59,100,17254,17256,1,8838,111,116,59,1,10947,117,108,116,59,1,10945,4,2,69,101,17273,17276,59,1,10955,59,1,8842,108,117,115,59,1,10943,97,114,114,59,1,10617,4,3,101,105,117,17299,17335,17339,116,4,3,59,101,110,17308,17310,17322,1,8834,113,4,2,59,113,17317,17319,1,8838,59,1,10949,101,113,4,2,59,113,17330,17332,1,8842,59,1,10955,109,59,1,10951,4,2,98,112,17345,17348,59,1,10965,59,1,10963,99,4,6,59,97,99,101,110,115,17366,17368,17376,17385,17389,17415,1,8827,112,112,114,111,120,59,1,10936,117,114,108,121,101,113,59,1,8829,113,59,1,10928,4,3,97,101,115,17397,17405,17410,112,112,114,111,120,59,1,10938,113,113,59,1,10934,105,109,59,1,8937,105,109,59,1,8831,59,1,8721,103,59,1,9834,4,13,49,50,51,59,69,100,101,104,108,109,110,112,115,17455,17462,17469,17476,17478,17481,17496,17509,17524,17530,17536,17548,17554,5,185,1,59,17460,1,185,5,178,1,59,17467,1,178,5,179,1,59,17474,1,179,1,8835,59,1,10950,4,2,111,115,17487,17491,116,59,1,10942,117,98,59,1,10968,4,2,59,100,17502,17504,1,8839,111,116,59,1,10948,115,4,2,111,117,17516,17520,108,59,1,10185,98,59,1,10967,97,114,114,59,1,10619,117,108,116,59,1,10946,4,2,69,101,17542,17545,59,1,10956,59,1,8843,108,117,115,59,1,10944,4,3,101,105,117,17562,17598,17602,116,4,3,59,101,110,17571,17573,17585,1,8835,113,4,2,59,113,17580,17582,1,8839,59,1,10950,101,113,4,2,59,113,17593,17595,1,8843,59,1,10956,109,59,1,10952,4,2,98,112,17608,17611,59,1,10964,59,1,10966,4,3,65,97,110,17622,17627,17650,114,114,59,1,8665,114,4,2,104,114,17634,17638,107,59,1,10534,4,2,59,111,17644,17646,1,8601,119,59,1,8601,119,97,114,59,1,10538,108,105,103,5,223,1,59,17664,1,223,4,13,97,98,99,100,101,102,104,105,111,112,114,115,119,17694,17709,17714,17737,17742,17749,17754,17860,17905,17957,17964,18090,18122,4,2,114,117,17700,17706,103,101,116,59,1,8982,59,1,964,114,107,59,1,9140,4,3,97,101,121,17722,17728,17734,114,111,110,59,1,357,100,105,108,59,1,355,59,1,1090,111,116,59,1,8411,108,114,101,99,59,1,8981,114,59,3,55349,56625,4,4,101,105,107,111,17764,17805,17836,17851,4,2,114,116,17770,17786,101,4,2,52,102,17777,17780,59,1,8756,111,114,101,59,1,8756,97,4,3,59,115,118,17795,17797,17802,1,952,121,109,59,1,977,59,1,977,4,2,99,110,17811,17831,107,4,2,97,115,17818,17826,112,112,114,111,120,59,1,8776,105,109,59,1,8764,115,112,59,1,8201,4,2,97,115,17842,17846,112,59,1,8776,105,109,59,1,8764,114,110,5,254,1,59,17858,1,254,4,3,108,109,110,17868,17873,17901,100,101,59,1,732,101,115,5,215,3,59,98,100,17884,17886,17898,1,215,4,2,59,97,17892,17894,1,8864,114,59,1,10801,59,1,10800,116,59,1,8749,4,3,101,112,115,17913,17917,17953,97,59,1,10536,4,4,59,98,99,102,17927,17929,17934,17939,1,8868,111,116,59,1,9014,105,114,59,1,10993,4,2,59,111,17945,17948,3,55349,56677,114,107,59,1,10970,97,59,1,10537,114,105,109,101,59,1,8244,4,3,97,105,112,17972,17977,18082,100,101,59,1,8482,4,7,97,100,101,109,112,115,116,17993,18051,18056,18059,18066,18072,18076,110,103,108,101,4,5,59,100,108,113,114,18009,18011,18017,18032,18035,1,9653,111,119,110,59,1,9663,101,102,116,4,2,59,101,18026,18028,1,9667,113,59,1,8884,59,1,8796,105,103,104,116,4,2,59,101,18045,18047,1,9657,113,59,1,8885,111,116,59,1,9708,59,1,8796,105,110,117,115,59,1,10810,108,117,115,59,1,10809,98,59,1,10701,105,109,101,59,1,10811,101,122,105,117,109,59,1,9186,4,3,99,104,116,18098,18111,18116,4,2,114,121,18104,18108,59,3,55349,56521,59,1,1094,99,121,59,1,1115,114,111,107,59,1,359,4,2,105,111,18128,18133,120,116,59,1,8812,104,101,97,100,4,2,108,114,18143,18154,101,102,116,97,114,114,111,119,59,1,8606,105,103,104,116,97,114,114,111,119,59,1,8608,4,18,65,72,97,98,99,100,102,103,104,108,109,111,112,114,115,116,117,119,18204,18209,18214,18234,18250,18268,18292,18308,18319,18343,18379,18397,18413,18504,18547,18553,18584,18603,114,114,59,1,8657,97,114,59,1,10595,4,2,99,114,18220,18230,117,116,101,5,250,1,59,18228,1,250,114,59,1,8593,114,4,2,99,101,18241,18245,121,59,1,1118,118,101,59,1,365,4,2,105,121,18256,18265,114,99,5,251,1,59,18263,1,251,59,1,1091,4,3,97,98,104,18276,18281,18287,114,114,59,1,8645,108,97,99,59,1,369,97,114,59,1,10606,4,2,105,114,18298,18304,115,104,116,59,1,10622,59,3,55349,56626,114,97,118,101,5,249,1,59,18317,1,249,4,2,97,98,18325,18338,114,4,2,108,114,18332,18335,59,1,8639,59,1,8638,108,107,59,1,9600,4,2,99,116,18349,18374,4,2,111,114,18355,18369,114,110,4,2,59,101,18363,18365,1,8988,114,59,1,8988,111,112,59,1,8975,114,105,59,1,9720,4,2,97,108,18385,18390,99,114,59,1,363,5,168,1,59,18395,1,168,4,2,103,112,18403,18408,111,110,59,1,371,102,59,3,55349,56678,4,6,97,100,104,108,115,117,18427,18434,18445,18470,18475,18494,114,114,111,119,59,1,8593,111,119,110,97,114,114,111,119,59,1,8597,97,114,112,111,111,110,4,2,108,114,18457,18463,101,102,116,59,1,8639,105,103,104,116,59,1,8638,117,115,59,1,8846,105,4,3,59,104,108,18484,18486,18489,1,965,59,1,978,111,110,59,1,965,112,97,114,114,111,119,115,59,1,8648,4,3,99,105,116,18512,18537,18542,4,2,111,114,18518,18532,114,110,4,2,59,101,18526,18528,1,8989,114,59,1,8989,111,112,59,1,8974,110,103,59,1,367,114,105,59,1,9721,99,114,59,3,55349,56522,4,3,100,105,114,18561,18566,18572,111,116,59,1,8944,108,100,101,59,1,361,105,4,2,59,102,18579,18581,1,9653,59,1,9652,4,2,97,109,18590,18595,114,114,59,1,8648,108,5,252,1,59,18601,1,252,97,110,103,108,101,59,1,10663,4,15,65,66,68,97,99,100,101,102,108,110,111,112,114,115,122,18643,18648,18661,18667,18847,18851,18857,18904,18909,18915,18931,18937,18943,18949,18996,114,114,59,1,8661,97,114,4,2,59,118,18656,18658,1,10984,59,1,10985,97,115,104,59,1,8872,4,2,110,114,18673,18679,103,114,116,59,1,10652,4,7,101,107,110,112,114,115,116,18695,18704,18711,18720,18742,18754,18810,112,115,105,108,111,110,59,1,1013,97,112,112,97,59,1,1008,111,116,104,105,110,103,59,1,8709,4,3,104,105,114,18728,18732,18735,105,59,1,981,59,1,982,111,112,116,111,59,1,8733,4,2,59,104,18748,18750,1,8597,111,59,1,1009,4,2,105,117,18760,18766,103,109,97,59,1,962,4,2,98,112,18772,18791,115,101,116,110,101,113,4,2,59,113,18784,18787,3,8842,65024,59,3,10955,65024,115,101,116,110,101,113,4,2,59,113,18803,18806,3,8843,65024,59,3,10956,65024,4,2,104,114,18816,18822,101,116,97,59,1,977,105,97,110,103,108,101,4,2,108,114,18834,18840,101,102,116,59,1,8882,105,103,104,116,59,1,8883,121,59,1,1074,97,115,104,59,1,8866,4,3,101,108,114,18865,18884,18890,4,3,59,98,101,18873,18875,18880,1,8744,97,114,59,1,8891,113,59,1,8794,108,105,112,59,1,8942,4,2,98,116,18896,18901,97,114,59,1,124,59,1,124,114,59,3,55349,56627,116,114,105,59,1,8882,115,117,4,2,98,112,18923,18927,59,3,8834,8402,59,3,8835,8402,112,102,59,3,55349,56679,114,111,112,59,1,8733,116,114,105,59,1,8883,4,2,99,117,18955,18960,114,59,3,55349,56523,4,2,98,112,18966,18981,110,4,2,69,101,18973,18977,59,3,10955,65024,59,3,8842,65024,110,4,2,69,101,18988,18992,59,3,10956,65024,59,3,8843,65024,105,103,122,97,103,59,1,10650,4,7,99,101,102,111,112,114,115,19020,19026,19061,19066,19072,19075,19089,105,114,99,59,1,373,4,2,100,105,19032,19055,4,2,98,103,19038,19043,97,114,59,1,10847,101,4,2,59,113,19050,19052,1,8743,59,1,8793,101,114,112,59,1,8472,114,59,3,55349,56628,112,102,59,3,55349,56680,59,1,8472,4,2,59,101,19081,19083,1,8768,97,116,104,59,1,8768,99,114,59,3,55349,56524,4,14,99,100,102,104,105,108,109,110,111,114,115,117,118,119,19125,19146,19152,19157,19173,19176,19192,19197,19202,19236,19252,19269,19286,19291,4,3,97,105,117,19133,19137,19142,112,59,1,8898,114,99,59,1,9711,112,59,1,8899,116,114,105,59,1,9661,114,59,3,55349,56629,4,2,65,97,19163,19168,114,114,59,1,10234,114,114,59,1,10231,59,1,958,4,2,65,97,19182,19187,114,114,59,1,10232,114,114,59,1,10229,97,112,59,1,10236,105,115,59,1,8955,4,3,100,112,116,19210,19215,19230,111,116,59,1,10752,4,2,102,108,19221,19225,59,3,55349,56681,117,115,59,1,10753,105,109,101,59,1,10754,4,2,65,97,19242,19247,114,114,59,1,10233,114,114,59,1,10230,4,2,99,113,19258,19263,114,59,3,55349,56525,99,117,112,59,1,10758,4,2,112,116,19275,19281,108,117,115,59,1,10756,114,105,59,1,9651,101,101,59,1,8897,101,100,103,101,59,1,8896,4,8,97,99,101,102,105,111,115,117,19316,19335,19349,19357,19362,19367,19373,19379,99,4,2,117,121,19323,19332,116,101,5,253,1,59,19330,1,253,59,1,1103,4,2,105,121,19341,19346,114,99,59,1,375,59,1,1099,110,5,165,1,59,19355,1,165,114,59,3,55349,56630,99,121,59,1,1111,112,102,59,3,55349,56682,99,114,59,3,55349,56526,4,2,99,109,19385,19389,121,59,1,1102,108,5,255,1,59,19395,1,255,4,10,97,99,100,101,102,104,105,111,115,119,19419,19426,19441,19446,19462,19467,19472,19480,19486,19492,99,117,116,101,59,1,378,4,2,97,121,19432,19438,114,111,110,59,1,382,59,1,1079,111,116,59,1,380,4,2,101,116,19452,19458,116,114,102,59,1,8488,97,59,1,950,114,59,3,55349,56631,99,121,59,1,1078,103,114,97,114,114,59,1,8669,112,102,59,3,55349,56683,99,114,59,3,55349,56527,4,2,106,110,19498,19501,59,1,8205,106,59,1,8204]);
|
|
},{}],84:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const unicode = require('../common/unicode');
|
|
const ERR = require('../common/error-codes');
|
|
|
|
//Aliases
|
|
const $ = unicode.CODE_POINTS;
|
|
|
|
//Const
|
|
const DEFAULT_BUFFER_WATERLINE = 1 << 16;
|
|
|
|
//Preprocessor
|
|
//NOTE: HTML input preprocessing
|
|
//(see: http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#preprocessing-the-input-stream)
|
|
class Preprocessor {
|
|
constructor() {
|
|
this.html = null;
|
|
|
|
this.pos = -1;
|
|
this.lastGapPos = -1;
|
|
this.lastCharPos = -1;
|
|
|
|
this.gapStack = [];
|
|
|
|
this.skipNextNewLine = false;
|
|
|
|
this.lastChunkWritten = false;
|
|
this.endOfChunkHit = false;
|
|
this.bufferWaterline = DEFAULT_BUFFER_WATERLINE;
|
|
}
|
|
|
|
_err() {
|
|
// NOTE: err reporting is noop by default. Enabled by mixin.
|
|
}
|
|
|
|
_addGap() {
|
|
this.gapStack.push(this.lastGapPos);
|
|
this.lastGapPos = this.pos;
|
|
}
|
|
|
|
_processSurrogate(cp) {
|
|
//NOTE: try to peek a surrogate pair
|
|
if (this.pos !== this.lastCharPos) {
|
|
const nextCp = this.html.charCodeAt(this.pos + 1);
|
|
|
|
if (unicode.isSurrogatePair(nextCp)) {
|
|
//NOTE: we have a surrogate pair. Peek pair character and recalculate code point.
|
|
this.pos++;
|
|
|
|
//NOTE: add gap that should be avoided during retreat
|
|
this._addGap();
|
|
|
|
return unicode.getSurrogatePairCodePoint(cp, nextCp);
|
|
}
|
|
}
|
|
|
|
//NOTE: we are at the end of a chunk, therefore we can't infer surrogate pair yet.
|
|
else if (!this.lastChunkWritten) {
|
|
this.endOfChunkHit = true;
|
|
return $.EOF;
|
|
}
|
|
|
|
//NOTE: isolated surrogate
|
|
this._err(ERR.surrogateInInputStream);
|
|
|
|
return cp;
|
|
}
|
|
|
|
dropParsedChunk() {
|
|
if (this.pos > this.bufferWaterline) {
|
|
this.lastCharPos -= this.pos;
|
|
this.html = this.html.substring(this.pos);
|
|
this.pos = 0;
|
|
this.lastGapPos = -1;
|
|
this.gapStack = [];
|
|
}
|
|
}
|
|
|
|
write(chunk, isLastChunk) {
|
|
if (this.html) {
|
|
this.html += chunk;
|
|
} else {
|
|
this.html = chunk;
|
|
}
|
|
|
|
this.lastCharPos = this.html.length - 1;
|
|
this.endOfChunkHit = false;
|
|
this.lastChunkWritten = isLastChunk;
|
|
}
|
|
|
|
insertHtmlAtCurrentPos(chunk) {
|
|
this.html = this.html.substring(0, this.pos + 1) + chunk + this.html.substring(this.pos + 1, this.html.length);
|
|
|
|
this.lastCharPos = this.html.length - 1;
|
|
this.endOfChunkHit = false;
|
|
}
|
|
|
|
advance() {
|
|
this.pos++;
|
|
|
|
if (this.pos > this.lastCharPos) {
|
|
this.endOfChunkHit = !this.lastChunkWritten;
|
|
return $.EOF;
|
|
}
|
|
|
|
let cp = this.html.charCodeAt(this.pos);
|
|
|
|
//NOTE: any U+000A LINE FEED (LF) characters that immediately follow a U+000D CARRIAGE RETURN (CR) character
|
|
//must be ignored.
|
|
if (this.skipNextNewLine && cp === $.LINE_FEED) {
|
|
this.skipNextNewLine = false;
|
|
this._addGap();
|
|
return this.advance();
|
|
}
|
|
|
|
//NOTE: all U+000D CARRIAGE RETURN (CR) characters must be converted to U+000A LINE FEED (LF) characters
|
|
if (cp === $.CARRIAGE_RETURN) {
|
|
this.skipNextNewLine = true;
|
|
return $.LINE_FEED;
|
|
}
|
|
|
|
this.skipNextNewLine = false;
|
|
|
|
if (unicode.isSurrogate(cp)) {
|
|
cp = this._processSurrogate(cp);
|
|
}
|
|
|
|
//OPTIMIZATION: first check if code point is in the common allowed
|
|
//range (ASCII alphanumeric, whitespaces, big chunk of BMP)
|
|
//before going into detailed performance cost validation.
|
|
const isCommonValidRange =
|
|
(cp > 0x1f && cp < 0x7f) || cp === $.LINE_FEED || cp === $.CARRIAGE_RETURN || (cp > 0x9f && cp < 0xfdd0);
|
|
|
|
if (!isCommonValidRange) {
|
|
this._checkForProblematicCharacters(cp);
|
|
}
|
|
|
|
return cp;
|
|
}
|
|
|
|
_checkForProblematicCharacters(cp) {
|
|
if (unicode.isControlCodePoint(cp)) {
|
|
this._err(ERR.controlCharacterInInputStream);
|
|
} else if (unicode.isUndefinedCodePoint(cp)) {
|
|
this._err(ERR.noncharacterInInputStream);
|
|
}
|
|
}
|
|
|
|
retreat() {
|
|
if (this.pos === this.lastGapPos) {
|
|
this.lastGapPos = this.gapStack.pop();
|
|
this.pos--;
|
|
}
|
|
|
|
this.pos--;
|
|
}
|
|
}
|
|
|
|
module.exports = Preprocessor;
|
|
|
|
},{"../common/error-codes":65,"../common/unicode":68}],85:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
const { DOCUMENT_MODE } = require('../common/html');
|
|
|
|
//Node construction
|
|
exports.createDocument = function() {
|
|
return {
|
|
nodeName: '#document',
|
|
mode: DOCUMENT_MODE.NO_QUIRKS,
|
|
childNodes: []
|
|
};
|
|
};
|
|
|
|
exports.createDocumentFragment = function() {
|
|
return {
|
|
nodeName: '#document-fragment',
|
|
childNodes: []
|
|
};
|
|
};
|
|
|
|
exports.createElement = function(tagName, namespaceURI, attrs) {
|
|
return {
|
|
nodeName: tagName,
|
|
tagName: tagName,
|
|
attrs: attrs,
|
|
namespaceURI: namespaceURI,
|
|
childNodes: [],
|
|
parentNode: null
|
|
};
|
|
};
|
|
|
|
exports.createCommentNode = function(data) {
|
|
return {
|
|
nodeName: '#comment',
|
|
data: data,
|
|
parentNode: null
|
|
};
|
|
};
|
|
|
|
const createTextNode = function(value) {
|
|
return {
|
|
nodeName: '#text',
|
|
value: value,
|
|
parentNode: null
|
|
};
|
|
};
|
|
|
|
//Tree mutation
|
|
const appendChild = (exports.appendChild = function(parentNode, newNode) {
|
|
parentNode.childNodes.push(newNode);
|
|
newNode.parentNode = parentNode;
|
|
});
|
|
|
|
const insertBefore = (exports.insertBefore = function(parentNode, newNode, referenceNode) {
|
|
const insertionIdx = parentNode.childNodes.indexOf(referenceNode);
|
|
|
|
parentNode.childNodes.splice(insertionIdx, 0, newNode);
|
|
newNode.parentNode = parentNode;
|
|
});
|
|
|
|
exports.setTemplateContent = function(templateElement, contentElement) {
|
|
templateElement.content = contentElement;
|
|
};
|
|
|
|
exports.getTemplateContent = function(templateElement) {
|
|
return templateElement.content;
|
|
};
|
|
|
|
exports.setDocumentType = function(document, name, publicId, systemId) {
|
|
let doctypeNode = null;
|
|
|
|
for (let i = 0; i < document.childNodes.length; i++) {
|
|
if (document.childNodes[i].nodeName === '#documentType') {
|
|
doctypeNode = document.childNodes[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (doctypeNode) {
|
|
doctypeNode.name = name;
|
|
doctypeNode.publicId = publicId;
|
|
doctypeNode.systemId = systemId;
|
|
} else {
|
|
appendChild(document, {
|
|
nodeName: '#documentType',
|
|
name: name,
|
|
publicId: publicId,
|
|
systemId: systemId
|
|
});
|
|
}
|
|
};
|
|
|
|
exports.setDocumentMode = function(document, mode) {
|
|
document.mode = mode;
|
|
};
|
|
|
|
exports.getDocumentMode = function(document) {
|
|
return document.mode;
|
|
};
|
|
|
|
exports.detachNode = function(node) {
|
|
if (node.parentNode) {
|
|
const idx = node.parentNode.childNodes.indexOf(node);
|
|
|
|
node.parentNode.childNodes.splice(idx, 1);
|
|
node.parentNode = null;
|
|
}
|
|
};
|
|
|
|
exports.insertText = function(parentNode, text) {
|
|
if (parentNode.childNodes.length) {
|
|
const prevNode = parentNode.childNodes[parentNode.childNodes.length - 1];
|
|
|
|
if (prevNode.nodeName === '#text') {
|
|
prevNode.value += text;
|
|
return;
|
|
}
|
|
}
|
|
|
|
appendChild(parentNode, createTextNode(text));
|
|
};
|
|
|
|
exports.insertTextBefore = function(parentNode, text, referenceNode) {
|
|
const prevNode = parentNode.childNodes[parentNode.childNodes.indexOf(referenceNode) - 1];
|
|
|
|
if (prevNode && prevNode.nodeName === '#text') {
|
|
prevNode.value += text;
|
|
} else {
|
|
insertBefore(parentNode, createTextNode(text), referenceNode);
|
|
}
|
|
};
|
|
|
|
exports.adoptAttributes = function(recipient, attrs) {
|
|
const recipientAttrsMap = [];
|
|
|
|
for (let i = 0; i < recipient.attrs.length; i++) {
|
|
recipientAttrsMap.push(recipient.attrs[i].name);
|
|
}
|
|
|
|
for (let j = 0; j < attrs.length; j++) {
|
|
if (recipientAttrsMap.indexOf(attrs[j].name) === -1) {
|
|
recipient.attrs.push(attrs[j]);
|
|
}
|
|
}
|
|
};
|
|
|
|
//Tree traversing
|
|
exports.getFirstChild = function(node) {
|
|
return node.childNodes[0];
|
|
};
|
|
|
|
exports.getChildNodes = function(node) {
|
|
return node.childNodes;
|
|
};
|
|
|
|
exports.getParentNode = function(node) {
|
|
return node.parentNode;
|
|
};
|
|
|
|
exports.getAttrList = function(element) {
|
|
return element.attrs;
|
|
};
|
|
|
|
//Node data
|
|
exports.getTagName = function(element) {
|
|
return element.tagName;
|
|
};
|
|
|
|
exports.getNamespaceURI = function(element) {
|
|
return element.namespaceURI;
|
|
};
|
|
|
|
exports.getTextNodeContent = function(textNode) {
|
|
return textNode.value;
|
|
};
|
|
|
|
exports.getCommentNodeContent = function(commentNode) {
|
|
return commentNode.data;
|
|
};
|
|
|
|
exports.getDocumentTypeNodeName = function(doctypeNode) {
|
|
return doctypeNode.name;
|
|
};
|
|
|
|
exports.getDocumentTypeNodePublicId = function(doctypeNode) {
|
|
return doctypeNode.publicId;
|
|
};
|
|
|
|
exports.getDocumentTypeNodeSystemId = function(doctypeNode) {
|
|
return doctypeNode.systemId;
|
|
};
|
|
|
|
//Node types
|
|
exports.isTextNode = function(node) {
|
|
return node.nodeName === '#text';
|
|
};
|
|
|
|
exports.isCommentNode = function(node) {
|
|
return node.nodeName === '#comment';
|
|
};
|
|
|
|
exports.isDocumentTypeNode = function(node) {
|
|
return node.nodeName === '#documentType';
|
|
};
|
|
|
|
exports.isElementNode = function(node) {
|
|
return !!node.tagName;
|
|
};
|
|
|
|
// Source code location
|
|
exports.setNodeSourceCodeLocation = function(node, location) {
|
|
node.sourceCodeLocation = location;
|
|
};
|
|
|
|
exports.getNodeSourceCodeLocation = function(node) {
|
|
return node.sourceCodeLocation;
|
|
};
|
|
|
|
exports.updateNodeSourceCodeLocation = function(node, endLocation) {
|
|
node.sourceCodeLocation = Object.assign(node.sourceCodeLocation, endLocation);
|
|
};
|
|
|
|
},{"../common/html":67}],86:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
module.exports = function mergeOptions(defaults, options) {
|
|
options = options || Object.create(null);
|
|
|
|
return [defaults, options].reduce((merged, optObj) => {
|
|
Object.keys(optObj).forEach(key => {
|
|
merged[key] = optObj[key];
|
|
});
|
|
|
|
return merged;
|
|
}, Object.create(null));
|
|
};
|
|
|
|
},{}],87:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
class Mixin {
|
|
constructor(host) {
|
|
const originalMethods = {};
|
|
const overriddenMethods = this._getOverriddenMethods(this, originalMethods);
|
|
|
|
for (const key of Object.keys(overriddenMethods)) {
|
|
if (typeof overriddenMethods[key] === 'function') {
|
|
originalMethods[key] = host[key];
|
|
host[key] = overriddenMethods[key];
|
|
}
|
|
}
|
|
}
|
|
|
|
_getOverriddenMethods() {
|
|
throw new Error('Not implemented');
|
|
}
|
|
}
|
|
|
|
Mixin.install = function(host, Ctor, opts) {
|
|
if (!host.__mixins) {
|
|
host.__mixins = [];
|
|
}
|
|
|
|
for (let i = 0; i < host.__mixins.length; i++) {
|
|
if (host.__mixins[i].constructor === Ctor) {
|
|
return host.__mixins[i];
|
|
}
|
|
}
|
|
|
|
const mixin = new Ctor(host, opts);
|
|
|
|
host.__mixins.push(mixin);
|
|
|
|
return mixin;
|
|
};
|
|
|
|
module.exports = Mixin;
|
|
|
|
},{}],88:[function(require,module,exports){
|
|
(function (global){(function (){
|
|
/*! *****************************************************************************
|
|
Copyright (c) Microsoft Corporation.
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
purpose with or without fee is hereby granted.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
PERFORMANCE OF THIS SOFTWARE.
|
|
***************************************************************************** */
|
|
/* global global, define, System, Reflect, Promise */
|
|
var __extends;
|
|
var __assign;
|
|
var __rest;
|
|
var __decorate;
|
|
var __param;
|
|
var __metadata;
|
|
var __awaiter;
|
|
var __generator;
|
|
var __exportStar;
|
|
var __values;
|
|
var __read;
|
|
var __spread;
|
|
var __spreadArrays;
|
|
var __spreadArray;
|
|
var __await;
|
|
var __asyncGenerator;
|
|
var __asyncDelegator;
|
|
var __asyncValues;
|
|
var __makeTemplateObject;
|
|
var __importStar;
|
|
var __importDefault;
|
|
var __classPrivateFieldGet;
|
|
var __classPrivateFieldSet;
|
|
var __createBinding;
|
|
(function (factory) {
|
|
var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {};
|
|
if (typeof define === "function" && define.amd) {
|
|
define("tslib", ["exports"], function (exports) { factory(createExporter(root, createExporter(exports))); });
|
|
}
|
|
else if (typeof module === "object" && typeof module.exports === "object") {
|
|
factory(createExporter(root, createExporter(module.exports)));
|
|
}
|
|
else {
|
|
factory(createExporter(root));
|
|
}
|
|
function createExporter(exports, previous) {
|
|
if (exports !== root) {
|
|
if (typeof Object.create === "function") {
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
}
|
|
else {
|
|
exports.__esModule = true;
|
|
}
|
|
}
|
|
return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };
|
|
}
|
|
})
|
|
(function (exporter) {
|
|
var extendStatics = Object.setPrototypeOf ||
|
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
|
|
__extends = function (d, b) {
|
|
if (typeof b !== "function" && b !== null)
|
|
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
extendStatics(d, b);
|
|
function __() { this.constructor = d; }
|
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
};
|
|
|
|
__assign = Object.assign || function (t) {
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
s = arguments[i];
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
}
|
|
return t;
|
|
};
|
|
|
|
__rest = function (s, e) {
|
|
var t = {};
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
t[p] = s[p];
|
|
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
t[p[i]] = s[p[i]];
|
|
}
|
|
return t;
|
|
};
|
|
|
|
__decorate = function (decorators, target, key, desc) {
|
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
};
|
|
|
|
__param = function (paramIndex, decorator) {
|
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
};
|
|
|
|
__metadata = function (metadataKey, metadataValue) {
|
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
|
};
|
|
|
|
__awaiter = function (thisArg, _arguments, P, generator) {
|
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
});
|
|
};
|
|
|
|
__generator = function (thisArg, body) {
|
|
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
function step(op) {
|
|
if (f) throw new TypeError("Generator is already executing.");
|
|
while (_) try {
|
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
switch (op[0]) {
|
|
case 0: case 1: t = op; break;
|
|
case 4: _.label++; return { value: op[1], done: false };
|
|
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
default:
|
|
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
if (t[2]) _.ops.pop();
|
|
_.trys.pop(); continue;
|
|
}
|
|
op = body.call(thisArg, _);
|
|
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
}
|
|
};
|
|
|
|
__exportStar = function(m, o) {
|
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);
|
|
};
|
|
|
|
__createBinding = Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
});
|
|
|
|
__values = function (o) {
|
|
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
if (m) return m.call(o);
|
|
if (o && typeof o.length === "number") return {
|
|
next: function () {
|
|
if (o && i >= o.length) o = void 0;
|
|
return { value: o && o[i++], done: !o };
|
|
}
|
|
};
|
|
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
};
|
|
|
|
__read = function (o, n) {
|
|
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
if (!m) return o;
|
|
var i = m.call(o), r, ar = [], e;
|
|
try {
|
|
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
}
|
|
catch (error) { e = { error: error }; }
|
|
finally {
|
|
try {
|
|
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
}
|
|
finally { if (e) throw e.error; }
|
|
}
|
|
return ar;
|
|
};
|
|
|
|
/** @deprecated */
|
|
__spread = function () {
|
|
for (var ar = [], i = 0; i < arguments.length; i++)
|
|
ar = ar.concat(__read(arguments[i]));
|
|
return ar;
|
|
};
|
|
|
|
/** @deprecated */
|
|
__spreadArrays = function () {
|
|
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
|
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
|
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
|
r[k] = a[j];
|
|
return r;
|
|
};
|
|
|
|
__spreadArray = function (to, from) {
|
|
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
|
to[j] = from[i];
|
|
return to;
|
|
};
|
|
|
|
__await = function (v) {
|
|
return this instanceof __await ? (this.v = v, this) : new __await(v);
|
|
};
|
|
|
|
__asyncGenerator = function (thisArg, _arguments, generator) {
|
|
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
|
|
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
function fulfill(value) { resume("next", value); }
|
|
function reject(value) { resume("throw", value); }
|
|
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
};
|
|
|
|
__asyncDelegator = function (o) {
|
|
var i, p;
|
|
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
|
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
|
|
};
|
|
|
|
__asyncValues = function (o) {
|
|
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
var m = o[Symbol.asyncIterator], i;
|
|
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
};
|
|
|
|
__makeTemplateObject = function (cooked, raw) {
|
|
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
|
return cooked;
|
|
};
|
|
|
|
var __setModuleDefault = Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
};
|
|
|
|
__importStar = function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
|
|
__importDefault = function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
|
|
__classPrivateFieldGet = function (receiver, state, kind, f) {
|
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
};
|
|
|
|
__classPrivateFieldSet = function (receiver, state, value, kind, f) {
|
|
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
};
|
|
|
|
exporter("__extends", __extends);
|
|
exporter("__assign", __assign);
|
|
exporter("__rest", __rest);
|
|
exporter("__decorate", __decorate);
|
|
exporter("__param", __param);
|
|
exporter("__metadata", __metadata);
|
|
exporter("__awaiter", __awaiter);
|
|
exporter("__generator", __generator);
|
|
exporter("__exportStar", __exportStar);
|
|
exporter("__createBinding", __createBinding);
|
|
exporter("__values", __values);
|
|
exporter("__read", __read);
|
|
exporter("__spread", __spread);
|
|
exporter("__spreadArrays", __spreadArrays);
|
|
exporter("__spreadArray", __spreadArray);
|
|
exporter("__await", __await);
|
|
exporter("__asyncGenerator", __asyncGenerator);
|
|
exporter("__asyncDelegator", __asyncDelegator);
|
|
exporter("__asyncValues", __asyncValues);
|
|
exporter("__makeTemplateObject", __makeTemplateObject);
|
|
exporter("__importStar", __importStar);
|
|
exporter("__importDefault", __importDefault);
|
|
exporter("__classPrivateFieldGet", __classPrivateFieldGet);
|
|
exporter("__classPrivateFieldSet", __classPrivateFieldSet);
|
|
});
|
|
|
|
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
},{}],"cheerio":[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.root = exports.parseHTML = exports.merge = exports.contains = void 0;
|
|
var tslib_1 = require("tslib");
|
|
var cheerio_1 = tslib_1.__importDefault(require("./cheerio"));
|
|
/**
|
|
* The default cheerio instance.
|
|
*
|
|
* @deprecated Use the function returned by `load` instead.
|
|
*/
|
|
exports.default = cheerio_1.default;
|
|
/**
|
|
* Types used in signatures of Cheerio methods.
|
|
*
|
|
* @category Cheerio
|
|
*/
|
|
tslib_1.__exportStar(require("./types"), exports);
|
|
tslib_1.__exportStar(require("./load"), exports);
|
|
var load_1 = require("./load");
|
|
// We add this here, to avoid a cyclic depenency
|
|
cheerio_1.default.load = load_1.load;
|
|
var staticMethods = tslib_1.__importStar(require("./static"));
|
|
/**
|
|
* In order to promote consistency with the jQuery library, users are encouraged
|
|
* to instead use the static method of the same name.
|
|
*
|
|
* @deprecated
|
|
* @example
|
|
*
|
|
* ```js
|
|
* const $ = cheerio.load('<div><p></p></div>');
|
|
*
|
|
* $.contains($('div').get(0), $('p').get(0));
|
|
* //=> true
|
|
*
|
|
* $.contains($('p').get(0), $('div').get(0));
|
|
* //=> false
|
|
* ```
|
|
*
|
|
* @returns {boolean}
|
|
*/
|
|
exports.contains = staticMethods.contains;
|
|
/**
|
|
* In order to promote consistency with the jQuery library, users are encouraged
|
|
* to instead use the static method of the same name.
|
|
*
|
|
* @deprecated
|
|
* @example
|
|
*
|
|
* ```js
|
|
* const $ = cheerio.load('');
|
|
*
|
|
* $.merge([1, 2], [3, 4]);
|
|
* //=> [1, 2, 3, 4]
|
|
* ```
|
|
*/
|
|
exports.merge = staticMethods.merge;
|
|
/**
|
|
* In order to promote consistency with the jQuery library, users are encouraged
|
|
* to instead use the static method of the same name as it is defined on the
|
|
* "loaded" Cheerio factory function.
|
|
*
|
|
* @deprecated See {@link static/parseHTML}.
|
|
* @example
|
|
*
|
|
* ```js
|
|
* const $ = cheerio.load('');
|
|
* $.parseHTML('<b>markup</b>');
|
|
* ```
|
|
*/
|
|
exports.parseHTML = staticMethods.parseHTML;
|
|
/**
|
|
* Users seeking to access the top-level element of a parsed document should
|
|
* instead use the `root` static method of a "loaded" Cheerio function.
|
|
*
|
|
* @deprecated
|
|
* @example
|
|
*
|
|
* ```js
|
|
* const $ = cheerio.load('');
|
|
* $.root();
|
|
* ```
|
|
*/
|
|
exports.root = staticMethods.root;
|
|
|
|
},{"./cheerio":12,"./load":13,"./static":18,"./types":19,"tslib":88}]},{},[])("cheerio")
|
|
});
|