first commit

This commit is contained in:
s.golasch
2023-08-01 13:49:46 +02:00
commit 1fc239fd54
20238 changed files with 3112246 additions and 0 deletions

134
build/node_modules/parse5/lib/common/doctype.js generated vendored Normal file
View File

@@ -0,0 +1,134 @@
'use strict';
//Const
var VALID_DOCTYPE_NAME = 'html',
QUIRKS_MODE_SYSTEM_ID = 'http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd',
QUIRKS_MODE_PUBLIC_ID_PREFIXES = [
"+//silmaril//dtd html pro v0r11 19970101//en",
"-//advasoft ltd//dtd html 3.0 aswedit + extensions//en",
"-//as//dtd html 3.0 aswedit + extensions//en",
"-//ietf//dtd html 2.0 level 1//en",
"-//ietf//dtd html 2.0 level 2//en",
"-//ietf//dtd html 2.0 strict level 1//en",
"-//ietf//dtd html 2.0 strict level 2//en",
"-//ietf//dtd html 2.0 strict//en",
"-//ietf//dtd html 2.0//en",
"-//ietf//dtd html 2.1e//en",
"-//ietf//dtd html 3.0//en",
"-//ietf//dtd html 3.0//en//",
"-//ietf//dtd html 3.2 final//en",
"-//ietf//dtd html 3.2//en",
"-//ietf//dtd html 3//en",
"-//ietf//dtd html level 0//en",
"-//ietf//dtd html level 0//en//2.0",
"-//ietf//dtd html level 1//en",
"-//ietf//dtd html level 1//en//2.0",
"-//ietf//dtd html level 2//en",
"-//ietf//dtd html level 2//en//2.0",
"-//ietf//dtd html level 3//en",
"-//ietf//dtd html level 3//en//3.0",
"-//ietf//dtd html strict level 0//en",
"-//ietf//dtd html strict level 0//en//2.0",
"-//ietf//dtd html strict level 1//en",
"-//ietf//dtd html strict level 1//en//2.0",
"-//ietf//dtd html strict level 2//en",
"-//ietf//dtd html strict level 2//en//2.0",
"-//ietf//dtd html strict level 3//en",
"-//ietf//dtd html strict level 3//en//3.0",
"-//ietf//dtd html strict//en",
"-//ietf//dtd html strict//en//2.0",
"-//ietf//dtd html strict//en//3.0",
"-//ietf//dtd html//en",
"-//ietf//dtd html//en//2.0",
"-//ietf//dtd html//en//3.0",
"-//metrius//dtd metrius presentational//en",
"-//microsoft//dtd internet explorer 2.0 html strict//en",
"-//microsoft//dtd internet explorer 2.0 html//en",
"-//microsoft//dtd internet explorer 2.0 tables//en",
"-//microsoft//dtd internet explorer 3.0 html strict//en",
"-//microsoft//dtd internet explorer 3.0 html//en",
"-//microsoft//dtd internet explorer 3.0 tables//en",
"-//netscape comm. corp.//dtd html//en",
"-//netscape comm. corp.//dtd strict html//en",
"-//o'reilly and associates//dtd html 2.0//en",
"-//o'reilly and associates//dtd html extended 1.0//en",
"-//spyglass//dtd html 2.0 extended//en",
"-//sq//dtd html 2.0 hotmetal + extensions//en",
"-//sun microsystems corp.//dtd hotjava html//en",
"-//sun microsystems corp.//dtd hotjava strict html//en",
"-//w3c//dtd html 3 1995-03-24//en",
"-//w3c//dtd html 3.2 draft//en",
"-//w3c//dtd html 3.2 final//en",
"-//w3c//dtd html 3.2//en",
"-//w3c//dtd html 3.2s draft//en",
"-//w3c//dtd html 4.0 frameset//en",
"-//w3c//dtd html 4.0 transitional//en",
"-//w3c//dtd html experimental 19960712//en",
"-//w3c//dtd html experimental 970421//en",
"-//w3c//dtd w3 html//en",
"-//w3o//dtd w3 html 3.0//en",
"-//w3o//dtd w3 html 3.0//en//",
"-//webtechs//dtd mozilla html 2.0//en",
"-//webtechs//dtd mozilla html//en"
],
QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES = [
'-//w3c//dtd html 4.01 frameset//',
'-//w3c//dtd html 4.01 transitional//'
],
QUIRKS_MODE_PUBLIC_IDS = [
'-//w3o//dtd w3 html strict 3.0//en//',
'-/w3c/dtd html 4.0 transitional/en',
'html'
];
//Utils
function enquoteDoctypeId(id) {
var quote = id.indexOf('"') !== -1 ? '\'' : '"';
return quote + id + quote;
}
//API
exports.isQuirks = function (name, publicId, systemId) {
if (name !== VALID_DOCTYPE_NAME)
return true;
if (systemId && systemId.toLowerCase() === QUIRKS_MODE_SYSTEM_ID)
return true;
if (publicId !== null) {
publicId = publicId.toLowerCase();
if (QUIRKS_MODE_PUBLIC_IDS.indexOf(publicId) > -1)
return true;
var prefixes = QUIRKS_MODE_PUBLIC_ID_PREFIXES;
if (systemId === null)
prefixes = prefixes.concat(QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES);
for (var i = 0; i < prefixes.length; i++) {
if (publicId.indexOf(prefixes[i]) === 0)
return true;
}
}
return false;
};
exports.serializeContent = function (name, publicId, systemId) {
var str = '!DOCTYPE ' + name;
if (publicId !== null)
str += ' PUBLIC ' + enquoteDoctypeId(publicId);
else if (systemId !== null)
str += ' SYSTEM';
if (systemId !== null)
str += ' ' + enquoteDoctypeId(systemId);
return str;
};

257
build/node_modules/parse5/lib/common/foreign_content.js generated vendored Normal file
View File

@@ -0,0 +1,257 @@
'use strict';
var Tokenizer = require('../tokenization/tokenizer'),
HTML = require('./html');
//Aliases
var $ = HTML.TAG_NAMES,
NS = HTML.NAMESPACES,
ATTRS = HTML.ATTRS;
//MIME types
var MIME_TYPES = {
TEXT_HTML: 'text/html',
APPLICATION_XML: 'application/xhtml+xml'
};
//Attributes
var DEFINITION_URL_ATTR = 'definitionurl',
ADJUSTED_DEFINITION_URL_ATTR = 'definitionURL',
SVG_ATTRS_ADJUSTMENT_MAP = {
'attributename': 'attributeName',
'attributetype': 'attributeType',
'basefrequency': 'baseFrequency',
'baseprofile': 'baseProfile',
'calcmode': 'calcMode',
'clippathunits': 'clipPathUnits',
'contentscripttype': 'contentScriptType',
'contentstyletype': 'contentStyleType',
'diffuseconstant': 'diffuseConstant',
'edgemode': 'edgeMode',
'externalresourcesrequired': 'externalResourcesRequired',
'filterres': 'filterRes',
'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'
},
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
var 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
var EXITS_FOREIGN_CONTENT = {};
EXITS_FOREIGN_CONTENT[$.B] = true;
EXITS_FOREIGN_CONTENT[$.BIG] = true;
EXITS_FOREIGN_CONTENT[$.BLOCKQUOTE] = true;
EXITS_FOREIGN_CONTENT[$.BODY] = true;
EXITS_FOREIGN_CONTENT[$.BR] = true;
EXITS_FOREIGN_CONTENT[$.CENTER] = true;
EXITS_FOREIGN_CONTENT[$.CODE] = true;
EXITS_FOREIGN_CONTENT[$.DD] = true;
EXITS_FOREIGN_CONTENT[$.DIV] = true;
EXITS_FOREIGN_CONTENT[$.DL] = true;
EXITS_FOREIGN_CONTENT[$.DT] = true;
EXITS_FOREIGN_CONTENT[$.EM] = true;
EXITS_FOREIGN_CONTENT[$.EMBED] = true;
EXITS_FOREIGN_CONTENT[$.H1] = true;
EXITS_FOREIGN_CONTENT[$.H2] = true;
EXITS_FOREIGN_CONTENT[$.H3] = true;
EXITS_FOREIGN_CONTENT[$.H4] = true;
EXITS_FOREIGN_CONTENT[$.H5] = true;
EXITS_FOREIGN_CONTENT[$.H6] = true;
EXITS_FOREIGN_CONTENT[$.HEAD] = true;
EXITS_FOREIGN_CONTENT[$.HR] = true;
EXITS_FOREIGN_CONTENT[$.I] = true;
EXITS_FOREIGN_CONTENT[$.IMG] = true;
EXITS_FOREIGN_CONTENT[$.LI] = true;
EXITS_FOREIGN_CONTENT[$.LISTING] = true;
EXITS_FOREIGN_CONTENT[$.MENU] = true;
EXITS_FOREIGN_CONTENT[$.META] = true;
EXITS_FOREIGN_CONTENT[$.NOBR] = true;
EXITS_FOREIGN_CONTENT[$.OL] = true;
EXITS_FOREIGN_CONTENT[$.P] = true;
EXITS_FOREIGN_CONTENT[$.PRE] = true;
EXITS_FOREIGN_CONTENT[$.RUBY] = true;
EXITS_FOREIGN_CONTENT[$.S] = true;
EXITS_FOREIGN_CONTENT[$.SMALL] = true;
EXITS_FOREIGN_CONTENT[$.SPAN] = true;
EXITS_FOREIGN_CONTENT[$.STRONG] = true;
EXITS_FOREIGN_CONTENT[$.STRIKE] = true;
EXITS_FOREIGN_CONTENT[$.SUB] = true;
EXITS_FOREIGN_CONTENT[$.SUP] = true;
EXITS_FOREIGN_CONTENT[$.TABLE] = true;
EXITS_FOREIGN_CONTENT[$.TT] = true;
EXITS_FOREIGN_CONTENT[$.U] = true;
EXITS_FOREIGN_CONTENT[$.UL] = true;
EXITS_FOREIGN_CONTENT[$.VAR] = true;
//Check exit from foreign content
exports.causesExit = function (startTagToken) {
var tn = startTagToken.tagName;
if (tn === $.FONT && (Tokenizer.getTokenAttr(startTagToken, ATTRS.COLOR) !== null ||
Tokenizer.getTokenAttr(startTagToken, ATTRS.SIZE) !== null ||
Tokenizer.getTokenAttr(startTagToken, ATTRS.FACE) !== null)) {
return true;
}
return EXITS_FOREIGN_CONTENT[tn];
};
//Token adjustments
exports.adjustTokenMathMLAttrs = function (token) {
for (var 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 (var i = 0; i < token.attrs.length; i++) {
var adjustedAttrName = SVG_ATTRS_ADJUSTMENT_MAP[token.attrs[i].name];
if (adjustedAttrName)
token.attrs[i].name = adjustedAttrName;
}
};
exports.adjustTokenXMLAttrs = function (token) {
for (var i = 0; i < token.attrs.length; i++) {
var 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) {
var adjustedTagName = SVG_TAG_NAMES_ADJUSTMENT_MAP[token.tagName];
if (adjustedTagName)
token.tagName = adjustedTagName;
};
//Integration points
exports.isMathMLTextIntegrationPoint = function (tn, ns) {
return ns === NS.MATHML && (tn === $.MI || tn === $.MO || tn === $.MN || tn === $.MS || tn === $.MTEXT);
};
exports.isHtmlIntegrationPoint = function (tn, ns, attrs) {
if (ns === NS.MATHML && tn === $.ANNOTATION_XML) {
for (var i = 0; i < attrs.length; i++) {
if (attrs[i].name === ATTRS.ENCODING) {
var 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);
};

268
build/node_modules/parse5/lib/common/html.js generated vendored Normal file
View File

@@ -0,0 +1,268 @@
'use strict';
var 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'
};
var $ = 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',
COMMAND: 'command',
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',
ISINDEX: 'isindex',
KEYGEN: 'keygen',
LABEL: 'label',
LI: 'li',
LINK: 'link',
LISTING: 'listing',
MAIN: 'main',
MALIGNMARK: 'malignmark',
MARQUEE: 'marquee',
MATH: 'math',
MENU: 'menu',
MENUITEM: 'menuitem',
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',
RP: 'rp',
RT: 'rt',
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'
};
var SPECIAL_ELEMENTS = exports.SPECIAL_ELEMENTS = {};
SPECIAL_ELEMENTS[NS.HTML] = {};
SPECIAL_ELEMENTS[NS.HTML][$.ADDRESS] = true;
SPECIAL_ELEMENTS[NS.HTML][$.APPLET] = true;
SPECIAL_ELEMENTS[NS.HTML][$.AREA] = true;
SPECIAL_ELEMENTS[NS.HTML][$.ARTICLE] = true;
SPECIAL_ELEMENTS[NS.HTML][$.ASIDE] = true;
SPECIAL_ELEMENTS[NS.HTML][$.BASE] = true;
SPECIAL_ELEMENTS[NS.HTML][$.BASEFONT] = true;
SPECIAL_ELEMENTS[NS.HTML][$.BGSOUND] = true;
SPECIAL_ELEMENTS[NS.HTML][$.BLOCKQUOTE] = true;
SPECIAL_ELEMENTS[NS.HTML][$.BODY] = true;
SPECIAL_ELEMENTS[NS.HTML][$.BR] = true;
SPECIAL_ELEMENTS[NS.HTML][$.BUTTON] = true;
SPECIAL_ELEMENTS[NS.HTML][$.CAPTION] = true;
SPECIAL_ELEMENTS[NS.HTML][$.CENTER] = true;
SPECIAL_ELEMENTS[NS.HTML][$.COL] = true;
SPECIAL_ELEMENTS[NS.HTML][$.COLGROUP] = true;
SPECIAL_ELEMENTS[NS.HTML][$.DD] = true;
SPECIAL_ELEMENTS[NS.HTML][$.DETAILS] = true;
SPECIAL_ELEMENTS[NS.HTML][$.DIR] = true;
SPECIAL_ELEMENTS[NS.HTML][$.DIV] = true;
SPECIAL_ELEMENTS[NS.HTML][$.DL] = true;
SPECIAL_ELEMENTS[NS.HTML][$.DT] = true;
SPECIAL_ELEMENTS[NS.HTML][$.EMBED] = true;
SPECIAL_ELEMENTS[NS.HTML][$.FIELDSET] = true;
SPECIAL_ELEMENTS[NS.HTML][$.FIGCAPTION] = true;
SPECIAL_ELEMENTS[NS.HTML][$.FIGURE] = true;
SPECIAL_ELEMENTS[NS.HTML][$.FOOTER] = true;
SPECIAL_ELEMENTS[NS.HTML][$.FORM] = true;
SPECIAL_ELEMENTS[NS.HTML][$.FRAME] = true;
SPECIAL_ELEMENTS[NS.HTML][$.FRAMESET] = true;
SPECIAL_ELEMENTS[NS.HTML][$.H1] = true;
SPECIAL_ELEMENTS[NS.HTML][$.H2] = true;
SPECIAL_ELEMENTS[NS.HTML][$.H3] = true;
SPECIAL_ELEMENTS[NS.HTML][$.H4] = true;
SPECIAL_ELEMENTS[NS.HTML][$.H5] = true;
SPECIAL_ELEMENTS[NS.HTML][$.H6] = true;
SPECIAL_ELEMENTS[NS.HTML][$.HEAD] = true;
SPECIAL_ELEMENTS[NS.HTML][$.HEADER] = true;
SPECIAL_ELEMENTS[NS.HTML][$.HGROUP] = true;
SPECIAL_ELEMENTS[NS.HTML][$.HR] = true;
SPECIAL_ELEMENTS[NS.HTML][$.HTML] = true;
SPECIAL_ELEMENTS[NS.HTML][$.IFRAME] = true;
SPECIAL_ELEMENTS[NS.HTML][$.IMG] = true;
SPECIAL_ELEMENTS[NS.HTML][$.INPUT] = true;
SPECIAL_ELEMENTS[NS.HTML][$.ISINDEX] = true;
SPECIAL_ELEMENTS[NS.HTML][$.LI] = true;
SPECIAL_ELEMENTS[NS.HTML][$.LINK] = true;
SPECIAL_ELEMENTS[NS.HTML][$.LISTING] = true;
SPECIAL_ELEMENTS[NS.HTML][$.MAIN] = true;
SPECIAL_ELEMENTS[NS.HTML][$.MARQUEE] = true;
SPECIAL_ELEMENTS[NS.HTML][$.MENU] = true;
SPECIAL_ELEMENTS[NS.HTML][$.MENUITEM] = true;
SPECIAL_ELEMENTS[NS.HTML][$.META] = true;
SPECIAL_ELEMENTS[NS.HTML][$.NAV] = true;
SPECIAL_ELEMENTS[NS.HTML][$.NOEMBED] = true;
SPECIAL_ELEMENTS[NS.HTML][$.NOFRAMES] = true;
SPECIAL_ELEMENTS[NS.HTML][$.NOSCRIPT] = true;
SPECIAL_ELEMENTS[NS.HTML][$.OBJECT] = true;
SPECIAL_ELEMENTS[NS.HTML][$.OL] = true;
SPECIAL_ELEMENTS[NS.HTML][$.P] = true;
SPECIAL_ELEMENTS[NS.HTML][$.PARAM] = true;
SPECIAL_ELEMENTS[NS.HTML][$.PLAINTEXT] = true;
SPECIAL_ELEMENTS[NS.HTML][$.PRE] = true;
SPECIAL_ELEMENTS[NS.HTML][$.SCRIPT] = true;
SPECIAL_ELEMENTS[NS.HTML][$.SECTION] = true;
SPECIAL_ELEMENTS[NS.HTML][$.SELECT] = true;
SPECIAL_ELEMENTS[NS.HTML][$.SOURCE] = true;
SPECIAL_ELEMENTS[NS.HTML][$.STYLE] = true;
SPECIAL_ELEMENTS[NS.HTML][$.SUMMARY] = true;
SPECIAL_ELEMENTS[NS.HTML][$.TABLE] = true;
SPECIAL_ELEMENTS[NS.HTML][$.TBODY] = true;
SPECIAL_ELEMENTS[NS.HTML][$.TD] = true;
SPECIAL_ELEMENTS[NS.HTML][$.TEMPLATE] = true;
SPECIAL_ELEMENTS[NS.HTML][$.TEXTAREA] = true;
SPECIAL_ELEMENTS[NS.HTML][$.TFOOT] = true;
SPECIAL_ELEMENTS[NS.HTML][$.TH] = true;
SPECIAL_ELEMENTS[NS.HTML][$.THEAD] = true;
SPECIAL_ELEMENTS[NS.HTML][$.TITLE] = true;
SPECIAL_ELEMENTS[NS.HTML][$.TR] = true;
SPECIAL_ELEMENTS[NS.HTML][$.TRACK] = true;
SPECIAL_ELEMENTS[NS.HTML][$.UL] = true;
SPECIAL_ELEMENTS[NS.HTML][$.WBR] = true;
SPECIAL_ELEMENTS[NS.HTML][$.XMP] = true;
SPECIAL_ELEMENTS[NS.MATHML] = {};
SPECIAL_ELEMENTS[NS.MATHML][$.MI] = true;
SPECIAL_ELEMENTS[NS.MATHML][$.MO] = true;
SPECIAL_ELEMENTS[NS.MATHML][$.MN] = true;
SPECIAL_ELEMENTS[NS.MATHML][$.MS] = true;
SPECIAL_ELEMENTS[NS.MATHML][$.MTEXT] = true;
SPECIAL_ELEMENTS[NS.MATHML][$.ANNOTATION_XML] = true;
SPECIAL_ELEMENTS[NS.SVG] = {};
SPECIAL_ELEMENTS[NS.SVG][$.TITLE] = true;
SPECIAL_ELEMENTS[NS.SVG][$.FOREIGN_OBJECT] = true;
SPECIAL_ELEMENTS[NS.SVG][$.DESC] = true;

48
build/node_modules/parse5/lib/common/unicode.js generated vendored Normal file
View File

@@ -0,0 +1,48 @@
'use strict';
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,
GRAVE_ACCENT: 0x60,
LATIN_SMALL_A: 0x61,
LATIN_SMALL_F: 0x66,
LATIN_SMALL_X: 0x78,
LATIN_SMALL_Z: 0x7A,
BOM: 0xFEFF,
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[
CDATA_END_STRING: [0x5D, 0x5D, 0x3E], //]]>
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
};

13
build/node_modules/parse5/lib/common/utils.js generated vendored Normal file
View File

@@ -0,0 +1,13 @@
'use strict';
exports.mergeOptions = function (defaults, options) {
options = options || {};
return [defaults, options].reduce(function (merged, optObj) {
Object.keys(optObj).forEach(function (key) {
merged[key] = optObj[key];
});
return merged;
}, {});
};

39
build/node_modules/parse5/lib/jsdom/jsdom_parser.js generated vendored Normal file
View File

@@ -0,0 +1,39 @@
'use strict';
var Parser = require('../tree_construction/parser'),
ParsingUnit = require('./parsing_unit');
//API
exports.parseDocument = function (html, treeAdapter) {
//NOTE: this should be reentrant, so we create new parser here
var parser = new Parser(treeAdapter),
parsingUnit = new ParsingUnit(parser);
//NOTE: override parser loop method
parser._runParsingLoop = function () {
parsingUnit.parsingLoopLock = true;
while (!parsingUnit.suspended && !this.stopped)
this._iterateParsingLoop();
parsingUnit.parsingLoopLock = false;
if (this.stopped)
parsingUnit.callback(this.document);
};
//NOTE: wait while parserController will be adopted by calling code, then
//start parsing
process.nextTick(function () {
parser.parse(html);
});
return parsingUnit;
};
exports.parseInnerHtml = function (innerHtml, contextElement, treeAdapter) {
//NOTE: this should be reentrant, so we create new parser here
var parser = new Parser(treeAdapter);
return parser.parseFragment(innerHtml, contextElement);
};

53
build/node_modules/parse5/lib/jsdom/parsing_unit.js generated vendored Normal file
View File

@@ -0,0 +1,53 @@
'use strict';
var ParsingUnit = module.exports = function (parser) {
this.parser = parser;
this.suspended = false;
this.parsingLoopLock = false;
this.callback = null;
};
ParsingUnit.prototype._stateGuard = function (suspend) {
if (this.suspended && suspend)
throw new Error('parse5: Parser was already suspended. Please, check your control flow logic.');
else if (!this.suspended && !suspend)
throw new Error('parse5: Parser was already resumed. Please, check your control flow logic.');
return suspend;
};
ParsingUnit.prototype.suspend = function () {
this.suspended = this._stateGuard(true);
return this;
};
ParsingUnit.prototype.resume = function () {
this.suspended = this._stateGuard(false);
//NOTE: don't enter parsing loop if it is locked. Without this lock _runParsingLoop() may be called
//while parsing loop is still running. E.g. when suspend() and resume() called synchronously.
if (!this.parsingLoopLock)
this.parser._runParsingLoop();
return this;
};
ParsingUnit.prototype.documentWrite = function (html) {
this.parser.tokenizer.preprocessor.write(html);
return this;
};
ParsingUnit.prototype.handleScripts = function (scriptHandler) {
this.parser.scriptHandler = scriptHandler;
return this;
};
ParsingUnit.prototype.done = function (callback) {
this.callback = callback;
return this;
};

View File

@@ -0,0 +1,178 @@
'use strict';
var DefaultTreeAdapter = require('../tree_adapters/default'),
Doctype = require('../common/doctype'),
Utils = require('../common/utils'),
HTML = require('../common/html');
//Aliases
var $ = HTML.TAG_NAMES,
NS = HTML.NAMESPACES;
//Default serializer options
var DEFAULT_OPTIONS = {
encodeHtmlEntities: true
};
//Escaping regexes
var AMP_REGEX = /&/g,
NBSP_REGEX = /\u00a0/g,
DOUBLE_QUOTE_REGEX = /"/g,
LT_REGEX = /</g,
GT_REGEX = />/g;
//Escape string
function escapeString(str, attrMode) {
str = str
.replace(AMP_REGEX, '&amp;')
.replace(NBSP_REGEX, '&nbsp;');
if (attrMode)
str = str.replace(DOUBLE_QUOTE_REGEX, '&quot;');
else {
str = str
.replace(LT_REGEX, '&lt;')
.replace(GT_REGEX, '&gt;');
}
return str;
}
//Enquote doctype ID
//Serializer
var Serializer = module.exports = function (treeAdapter, options) {
this.treeAdapter = treeAdapter || DefaultTreeAdapter;
this.options = Utils.mergeOptions(DEFAULT_OPTIONS, options);
};
//API
Serializer.prototype.serialize = function (node) {
this.html = '';
this._serializeChildNodes(node);
return this.html;
};
//Internals
Serializer.prototype._serializeChildNodes = function (parentNode) {
var childNodes = this.treeAdapter.getChildNodes(parentNode);
if (childNodes) {
for (var i = 0, cnLength = childNodes.length; i < cnLength; i++) {
var 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);
}
}
};
Serializer.prototype._serializeElement = function (node) {
var tn = this.treeAdapter.getTagName(node),
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 !== $.BR &&
tn !== $.COL && tn !== $.EMBED && tn !== $.FRAME && tn !== $.HR && tn !== $.IMG && tn !== $.INPUT &&
tn !== $.KEYGEN && tn !== $.LINK && tn !== $.MENUITEM && tn !== $.META && tn !== $.PARAM && tn !== $.SOURCE &&
tn !== $.TRACK && tn !== $.WBR) {
if (tn === $.PRE || tn === $.TEXTAREA || tn === $.LISTING) {
var firstChild = this.treeAdapter.getFirstChild(node);
if (firstChild && this.treeAdapter.isTextNode(firstChild)) {
var content = this.treeAdapter.getTextNodeContent(firstChild);
if (content[0] === '\n')
this.html += '\n';
}
}
var childNodesHolder = tn === $.TEMPLATE && ns === NS.HTML ?
this.treeAdapter.getChildNodes(node)[0] :
node;
this._serializeChildNodes(childNodesHolder);
this.html += '</' + tn + '>';
}
};
Serializer.prototype._serializeAttributes = function (node) {
var attrs = this.treeAdapter.getAttrList(node);
for (var i = 0, attrsLength = attrs.length; i < attrsLength; i++) {
var attr = attrs[i],
value = this.options.encodeHtmlEntities ? escapeString(attr.value, true) : attr.value;
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.namespace + ':' + attr.name;
this.html += '="' + value + '"';
}
};
Serializer.prototype._serializeTextNode = function (node) {
var content = this.treeAdapter.getTextNodeContent(node),
parent = this.treeAdapter.getParentNode(node),
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 += this.options.encodeHtmlEntities ? escapeString(content, false) : content;
};
Serializer.prototype._serializeCommentNode = function (node) {
this.html += '<!--' + this.treeAdapter.getCommentNodeContent(node) + '-->';
};
Serializer.prototype._serializeDocumentTypeNode = function (node) {
var name = this.treeAdapter.getDocumentTypeNodeName(node),
publicId = this.treeAdapter.getDocumentTypeNodePublicId(node),
systemId = this.treeAdapter.getDocumentTypeNodeSystemId(node);
this.html += '<' + Doctype.serializeContent(name, publicId, systemId) + '>';
};

View File

@@ -0,0 +1,107 @@
'use strict';
var Tokenizer = require('../tokenization/tokenizer'),
TokenizerProxy = require('./tokenizer_proxy'),
Utils = require('../common/utils');
//Default options
var DEFAULT_OPTIONS = {
decodeHtmlEntities: true,
locationInfo: false
};
//Skipping handler
function skip() {
//NOTE: do nothing =)
}
//SimpleApiParser
var SimpleApiParser = module.exports = function (handlers, options) {
this.options = Utils.mergeOptions(DEFAULT_OPTIONS, options);
this.handlers = {
doctype: this._wrapHandler(handlers.doctype),
startTag: this._wrapHandler(handlers.startTag),
endTag: this._wrapHandler(handlers.endTag),
text: this._wrapHandler(handlers.text),
comment: this._wrapHandler(handlers.comment)
};
};
SimpleApiParser.prototype._wrapHandler = function (handler) {
var parser = this;
handler = handler || skip;
if (this.options.locationInfo) {
return function () {
var args = Array.prototype.slice.call(arguments);
args.push(parser.currentTokenLocation);
handler.apply(handler, args);
};
}
return handler;
};
//API
SimpleApiParser.prototype.parse = function (html) {
var token = null;
this._reset(html);
do {
token = this.tokenizerProxy.getNextToken();
if (token.type === Tokenizer.CHARACTER_TOKEN ||
token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN ||
token.type === Tokenizer.NULL_CHARACTER_TOKEN) {
if (this.options.locationInfo) {
if (this.pendingText === null)
this.currentTokenLocation = token.location;
else
this.currentTokenLocation.end = token.location.end;
}
this.pendingText = (this.pendingText || '') + token.chars;
}
else {
this._emitPendingText();
this._handleToken(token);
}
} while (token.type !== Tokenizer.EOF_TOKEN);
};
//Internals
SimpleApiParser.prototype._handleToken = function (token) {
if (this.options.locationInfo)
this.currentTokenLocation = token.location;
if (token.type === Tokenizer.START_TAG_TOKEN)
this.handlers.startTag(token.tagName, token.attrs, token.selfClosing);
else if (token.type === Tokenizer.END_TAG_TOKEN)
this.handlers.endTag(token.tagName);
else if (token.type === Tokenizer.COMMENT_TOKEN)
this.handlers.comment(token.data);
else if (token.type === Tokenizer.DOCTYPE_TOKEN)
this.handlers.doctype(token.name, token.publicId, token.systemId);
};
SimpleApiParser.prototype._reset = function (html) {
this.tokenizerProxy = new TokenizerProxy(html, this.options);
this.pendingText = null;
this.currentTokenLocation = null;
};
SimpleApiParser.prototype._emitPendingText = function () {
if (this.pendingText !== null) {
this.handlers.text(this.pendingText);
this.pendingText = null;
}
};

View File

@@ -0,0 +1,122 @@
'use strict';
var Tokenizer = require('../tokenization/tokenizer'),
ForeignContent = require('../common/foreign_content'),
UNICODE = require('../common/unicode'),
HTML = require('../common/html');
//Aliases
var $ = HTML.TAG_NAMES,
NS = HTML.NAMESPACES;
//Tokenizer proxy
//NOTE: this proxy simulates adjustment of the Tokenizer which performed by standard parser during tree construction.
var TokenizerProxy = module.exports = function (html, options) {
this.tokenizer = new Tokenizer(html, options);
this.namespaceStack = [];
this.namespaceStackTop = -1;
this.currentNamespace = null;
this.inForeignContent = false;
};
//API
TokenizerProxy.prototype.getNextToken = function () {
var token = this.tokenizer.getNextToken();
if (token.type === Tokenizer.START_TAG_TOKEN)
this._handleStartTagToken(token);
else if (token.type === Tokenizer.END_TAG_TOKEN)
this._handleEndTagToken(token);
else if (token.type === Tokenizer.NULL_CHARACTER_TOKEN && this.inForeignContent) {
token.type = Tokenizer.CHARACTER_TOKEN;
token.chars = UNICODE.REPLACEMENT_CHARACTER;
}
return token;
};
//Namespace stack mutations
TokenizerProxy.prototype._enterNamespace = function (namespace) {
this.namespaceStackTop++;
this.namespaceStack.push(namespace);
this.inForeignContent = namespace !== NS.HTML;
this.currentNamespace = namespace;
this.tokenizer.allowCDATA = this.inForeignContent;
};
TokenizerProxy.prototype._leaveCurrentNamespace = function () {
this.namespaceStackTop--;
this.namespaceStack.pop();
this.currentNamespace = this.namespaceStack[this.namespaceStackTop];
this.inForeignContent = this.currentNamespace !== NS.HTML;
this.tokenizer.allowCDATA = this.inForeignContent;
};
//Token handlers
TokenizerProxy.prototype._ensureTokenizerMode = function (tn) {
if (tn === $.TEXTAREA || tn === $.TITLE)
this.tokenizer.state = Tokenizer.MODE.RCDATA;
else if (tn === $.PLAINTEXT)
this.tokenizer.state = Tokenizer.MODE.PLAINTEXT;
else if (tn === $.SCRIPT)
this.tokenizer.state = Tokenizer.MODE.SCRIPT_DATA;
else if (tn === $.STYLE || tn === $.IFRAME || tn === $.XMP ||
tn === $.NOEMBED || tn === $.NOFRAMES || tn === $.NOSCRIPT) {
this.tokenizer.state = Tokenizer.MODE.RAWTEXT;
}
};
TokenizerProxy.prototype._handleStartTagToken = function (token) {
var tn = token.tagName;
if (tn === $.SVG)
this._enterNamespace(NS.SVG);
else if (tn === $.MATH)
this._enterNamespace(NS.MATHML);
else {
if (this.inForeignContent) {
if (ForeignContent.causesExit(token))
this._leaveCurrentNamespace();
else if (ForeignContent.isMathMLTextIntegrationPoint(tn, this.currentNamespace) ||
ForeignContent.isHtmlIntegrationPoint(tn, this.currentNamespace, token.attrs)) {
this._enterNamespace(NS.HTML);
}
}
else
this._ensureTokenizerMode(tn);
}
};
TokenizerProxy.prototype._handleEndTagToken = function (token) {
var tn = token.tagName;
if (!this.inForeignContent) {
var previousNs = this.namespaceStack[this.namespaceStackTop - 1];
//NOTE: check for exit from integration point
if (ForeignContent.isMathMLTextIntegrationPoint(tn, previousNs) ||
ForeignContent.isHtmlIntegrationPoint(tn, previousNs, token.attrs)) {
this._leaveCurrentNamespace();
}
else if (tn === $.SCRIPT)
this.tokenizer.state = Tokenizer.MODE.DATA;
}
else if ((tn === $.SVG && this.currentNamespace === NS.SVG) ||
(tn === $.MATH && this.currentNamespace === NS.MATHML))
this._leaveCurrentNamespace();
};

View File

@@ -0,0 +1,80 @@
'use strict';
exports.assign = function (tokenizer) {
//NOTE: obtain Tokenizer proto this way to avoid module circular references
var tokenizerProto = Object.getPrototypeOf(tokenizer);
tokenizer.tokenStartLoc = -1;
//NOTE: add location info builder method
tokenizer._attachLocationInfo = function (token) {
token.location = {
start: this.tokenStartLoc,
end: -1
};
};
//NOTE: patch token creation methods and attach location objects
tokenizer._createStartTagToken = function (tagNameFirstCh) {
tokenizerProto._createStartTagToken.call(this, tagNameFirstCh);
this._attachLocationInfo(this.currentToken);
};
tokenizer._createEndTagToken = function (tagNameFirstCh) {
tokenizerProto._createEndTagToken.call(this, tagNameFirstCh);
this._attachLocationInfo(this.currentToken);
};
tokenizer._createCommentToken = function () {
tokenizerProto._createCommentToken.call(this);
this._attachLocationInfo(this.currentToken);
};
tokenizer._createDoctypeToken = function (doctypeNameFirstCh) {
tokenizerProto._createDoctypeToken.call(this, doctypeNameFirstCh);
this._attachLocationInfo(this.currentToken);
};
tokenizer._createCharacterToken = function (type, ch) {
tokenizerProto._createCharacterToken.call(this, type, ch);
this._attachLocationInfo(this.currentCharacterToken);
};
//NOTE: patch token emission methods to determine end location
tokenizer._emitCurrentToken = function () {
//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.end = this.currentToken.location.start;
this.currentToken.location.end = this.preprocessor.pos + 1;
tokenizerProto._emitCurrentToken.call(this);
};
tokenizer._emitCurrentCharacterToken = function () {
//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
if (this.currentCharacterToken && this.currentCharacterToken.location.end === -1) {
//NOTE: 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.
this.currentCharacterToken.location.end = this.preprocessor.pos;
}
tokenizerProto._emitCurrentCharacterToken.call(this);
};
//NOTE: patch initial states for each mode to obtain token start position
Object.keys(tokenizerProto.MODE)
.map(function (modeName) {
return tokenizerProto.MODE[modeName];
})
.forEach(function (state) {
tokenizer[state] = function (cp) {
this.tokenStartLoc = this.preprocessor.pos;
tokenizerProto[state].call(this, cp);
};
});
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,115 @@
'use strict';
var UNICODE = require('../common/unicode');
//Aliases
var $ = UNICODE.CODE_POINTS;
//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 isReservedCodePoint(cp) {
return cp >= 0xD800 && cp <= 0xDFFF || cp > 0x10FFFF;
}
function isSurrogatePair(cp1, cp2) {
return cp1 >= 0xD800 && cp1 <= 0xDBFF && cp2 >= 0xDC00 && cp2 <= 0xDFFF;
}
function getSurrogatePairCodePoint(cp1, cp2) {
return (cp1 - 0xD800) * 0x400 + 0x2400 + cp2;
}
//Preprocessor
//NOTE: HTML input preprocessing
//(see: http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#preprocessing-the-input-stream)
var Preprocessor = module.exports = function (html) {
this.write(html);
//NOTE: one leading U+FEFF BYTE ORDER MARK character must be ignored if any are present in the input stream.
this.pos = this.html.charCodeAt(0) === $.BOM ? 0 : -1;
this.gapStack = [];
this.lastGapPos = -1;
this.skipNextNewLine = false;
};
Preprocessor.prototype.write = function (html) {
if (this.html) {
this.html = this.html.substring(0, this.pos + 1) +
html +
this.html.substring(this.pos + 1, this.html.length);
}
else
this.html = html;
this.lastCharPos = this.html.length - 1;
};
Preprocessor.prototype.advanceAndPeekCodePoint = function () {
this.pos++;
if (this.pos > this.lastCharPos)
return $.EOF;
var 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.advanceAndPeekCodePoint();
}
//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;
//OPTIMIZATION: first perform check if the code point in the allowed range that covers most common
//HTML input (e.g. ASCII codes) to avoid performance-cost operations for high-range code points.
return cp >= 0xD800 ? this._processHighRangeCodePoint(cp) : cp;
};
Preprocessor.prototype._processHighRangeCodePoint = function (cp) {
//NOTE: try to peek a surrogate pair
if (this.pos !== this.lastCharPos) {
var nextCp = this.html.charCodeAt(this.pos + 1);
if (isSurrogatePair(cp, nextCp)) {
//NOTE: we have a surrogate pair. Peek pair character and recalculate code point.
this.pos++;
cp = getSurrogatePairCodePoint(cp, nextCp);
//NOTE: add gap that should be avoided during retreat
this._addGap();
}
}
if (isReservedCodePoint(cp))
cp = $.REPLACEMENT_CHARACTER;
return cp;
};
Preprocessor.prototype._addGap = function () {
this.gapStack.push(this.lastGapPos);
this.lastGapPos = this.pos;
};
Preprocessor.prototype.retreat = function () {
if (this.pos === this.lastGapPos) {
this.lastGapPos = this.gapStack.pop();
this.pos--;
}
this.pos--;
};

2317
build/node_modules/parse5/lib/tokenization/tokenizer.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

200
build/node_modules/parse5/lib/tree_adapters/default.js generated vendored Normal file
View File

@@ -0,0 +1,200 @@
'use strict';
//Node construction
exports.createDocument = function () {
return {
nodeName: '#document',
quirksMode: false,
childNodes: []
};
};
exports.createDocumentFragment = function () {
return {
nodeName: '#document-fragment',
quirksMode: false,
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
};
};
var createTextNode = function (value) {
return {
nodeName: '#text',
value: value,
parentNode: null
}
};
//Tree mutation
exports.setDocumentType = function (document, name, publicId, systemId) {
var doctypeNode = null;
for (var 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.setQuirksMode = function (document) {
document.quirksMode = true;
};
exports.isQuirksMode = function (document) {
return document.quirksMode;
};
var appendChild = exports.appendChild = function (parentNode, newNode) {
parentNode.childNodes.push(newNode);
newNode.parentNode = parentNode;
};
var insertBefore = exports.insertBefore = function (parentNode, newNode, referenceNode) {
var insertionIdx = parentNode.childNodes.indexOf(referenceNode);
parentNode.childNodes.splice(insertionIdx, 0, newNode);
newNode.parentNode = parentNode;
};
exports.detachNode = function (node) {
if (node.parentNode) {
var idx = node.parentNode.childNodes.indexOf(node);
node.parentNode.childNodes.splice(idx, 1);
node.parentNode = null;
}
};
exports.insertText = function (parentNode, text) {
if (parentNode.childNodes.length) {
var 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) {
var 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 (recipientNode, attrs) {
var recipientAttrsMap = [];
for (var i = 0; i < recipientNode.attrs.length; i++)
recipientAttrsMap.push(recipientNode.attrs[i].name);
for (var j = 0; j < attrs.length; j++) {
if (recipientAttrsMap.indexOf(attrs[j].name) === -1)
recipientNode.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 (node) {
return node.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;
};

View File

@@ -0,0 +1,317 @@
'use strict';
var Doctype = require('../common/doctype');
//Conversion tables for DOM Level1 structure emulation
var nodeTypes = {
element: 1,
text: 3,
cdata: 4,
comment: 8
};
var nodePropertyShorthands = {
tagName: 'name',
childNodes: 'children',
parentNode: 'parent',
previousSibling: 'prev',
nextSibling: 'next',
nodeValue: 'data'
};
//Node
var Node = function (props) {
for (var key in props) {
if (props.hasOwnProperty(key))
this[key] = props[key];
}
};
Node.prototype = {
get firstChild() {
var children = this.children;
return children && children[0] || null;
},
get lastChild() {
var children = this.children;
return children && children[children.length - 1] || null;
},
get nodeType() {
return nodeTypes[this.type] || nodeTypes.element;
}
};
Object.keys(nodePropertyShorthands).forEach(function (key) {
var 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 =
exports.createDocumentFragment = function () {
return new Node({
type: 'root',
name: 'root',
parent: null,
prev: null,
next: null,
children: []
});
};
exports.createElement = function (tagName, namespaceURI, attrs) {
var attribs = {},
attribsNamespace = {},
attribsPrefix = {};
for (var i = 0; i < attrs.length; i++) {
var 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
});
};
var createTextNode = function (value) {
return new Node({
type: 'text',
data: value,
parent: null,
prev: null,
next: null
});
};
//Tree mutation
exports.setDocumentType = function (document, name, publicId, systemId) {
var data = Doctype.serializeContent(name, publicId, systemId),
doctypeNode = null;
for (var 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.setQuirksMode = function (document) {
document.quirksMode = true;
};
exports.isQuirksMode = function (document) {
return document.quirksMode;
};
var appendChild = exports.appendChild = function (parentNode, newNode) {
var prev = parentNode.children[parentNode.children.length - 1];
if (prev) {
prev.next = newNode;
newNode.prev = prev;
}
parentNode.children.push(newNode);
newNode.parent = parentNode;
};
var insertBefore = exports.insertBefore = function (parentNode, newNode, referenceNode) {
var insertionIdx = parentNode.children.indexOf(referenceNode),
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.detachNode = function (node) {
if (node.parent) {
var idx = node.parent.children.indexOf(node),
prev = node.prev,
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) {
var 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) {
var 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 (recipientNode, attrs) {
for (var i = 0; i < attrs.length; i++) {
var attrName = attrs[i].name;
if (typeof recipientNode.attribs[attrName] === 'undefined') {
recipientNode.attribs[attrName] = attrs[i].value;
recipientNode['x-attribsNamespace'][attrName] = attrs[i].namespace;
recipientNode['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 (node) {
var attrList = [];
for (var name in node.attribs) {
if (node.attribs.hasOwnProperty(name)) {
attrList.push({
name: name,
value: node.attribs[name],
namespace: node['x-attribsNamespace'][name],
prefix: node['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;
};

View File

@@ -0,0 +1,167 @@
'use strict';
//Const
var NOAH_ARK_CAPACITY = 3;
//List of formatting elements
var FormattingElementList = module.exports = function (treeAdapter) {
this.length = 0;
this.entries = [];
this.treeAdapter = treeAdapter;
this.bookmark = null;
};
//Entry types
FormattingElementList.MARKER_ENTRY = 'MARKER_ENTRY';
FormattingElementList.ELEMENT_ENTRY = 'ELEMENT_ENTRY';
//Noah Ark's condition
//OPTIMIZATION: at first we try to find possible candidates for exclusion using
//lightweight heuristics without thorough attributes check.
FormattingElementList.prototype._getNoahArkConditionCandidates = function (newElement) {
var candidates = [];
if (this.length >= NOAH_ARK_CAPACITY) {
var neAttrsLength = this.treeAdapter.getAttrList(newElement).length,
neTagName = this.treeAdapter.getTagName(newElement),
neNamespaceURI = this.treeAdapter.getNamespaceURI(newElement);
for (var i = this.length - 1; i >= 0; i--) {
var entry = this.entries[i];
if (entry.type === FormattingElementList.MARKER_ENTRY)
break;
var element = entry.element,
elementAttrs = this.treeAdapter.getAttrList(element);
if (this.treeAdapter.getTagName(element) === neTagName &&
this.treeAdapter.getNamespaceURI(element) === neNamespaceURI &&
elementAttrs.length === neAttrsLength) {
candidates.push({idx: i, attrs: elementAttrs});
}
}
}
return candidates.length < NOAH_ARK_CAPACITY ? [] : candidates;
};
FormattingElementList.prototype._ensureNoahArkCondition = function (newElement) {
var candidates = this._getNoahArkConditionCandidates(newElement),
cLength = candidates.length;
if (cLength) {
var neAttrs = this.treeAdapter.getAttrList(newElement),
neAttrsLength = neAttrs.length,
neAttrsMap = {};
//NOTE: build attrs map for the new element so we can perform fast lookups
for (var i = 0; i < neAttrsLength; i++) {
var neAttr = neAttrs[i];
neAttrsMap[neAttr.name] = neAttr.value;
}
for (var i = 0; i < neAttrsLength; i++) {
for (var j = 0; j < cLength; j++) {
var 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 (var i = cLength - 1; i >= NOAH_ARK_CAPACITY - 1; i--) {
this.entries.splice(candidates[i].idx, 1);
this.length--;
}
}
};
//Mutations
FormattingElementList.prototype.insertMarker = function () {
this.entries.push({type: FormattingElementList.MARKER_ENTRY});
this.length++;
};
FormattingElementList.prototype.pushElement = function (element, token) {
this._ensureNoahArkCondition(element);
this.entries.push({
type: FormattingElementList.ELEMENT_ENTRY,
element: element,
token: token
});
this.length++;
};
FormattingElementList.prototype.insertElementAfterBookmark = function (element, token) {
var 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++;
};
FormattingElementList.prototype.removeEntry = function (entry) {
for (var i = this.length - 1; i >= 0; i--) {
if (this.entries[i] === entry) {
this.entries.splice(i, 1);
this.length--;
break;
}
}
};
FormattingElementList.prototype.clearToLastMarker = function () {
while (this.length) {
var entry = this.entries.pop();
this.length--;
if (entry.type === FormattingElementList.MARKER_ENTRY)
break;
}
};
//Search
FormattingElementList.prototype.getElementEntryInScopeWithTagName = function (tagName) {
for (var i = this.length - 1; i >= 0; i--) {
var entry = this.entries[i];
if (entry.type === FormattingElementList.MARKER_ENTRY)
return null;
if (this.treeAdapter.getTagName(entry.element) === tagName)
return entry;
}
return null;
};
FormattingElementList.prototype.getElementEntry = function (element) {
for (var i = this.length - 1; i >= 0; i--) {
var entry = this.entries[i];
if (entry.type === FormattingElementList.ELEMENT_ENTRY && entry.element == element)
return entry;
}
return null;
};

View File

@@ -0,0 +1,197 @@
'use strict';
var OpenElementStack = require('./open_element_stack'),
Tokenizer = require('../tokenization/tokenizer'),
HTML = require('../common/html');
//Aliases
var $ = HTML.TAG_NAMES;
function setEndLocation(element, closingToken, treeAdapter) {
var loc = element.__location;
if (!loc)
return;
if (!loc.startTag) {
loc.startTag = {
start: loc.start,
end: loc.end
};
}
if (closingToken.location) {
var tn = 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
isClosingEndTag = closingToken.type === Tokenizer.END_TAG_TOKEN &&
tn === closingToken.tagName;
if (isClosingEndTag) {
loc.endTag = {
start: closingToken.location.start,
end: closingToken.location.end
};
}
loc.end = closingToken.location.end;
}
}
//NOTE: patch open elements stack, so we can assign end location for the elements
function patchOpenElementsStack(stack, parser) {
var treeAdapter = parser.treeAdapter;
stack.pop = function () {
setEndLocation(this.current, parser.currentToken, treeAdapter);
OpenElementStack.prototype.pop.call(this);
};
stack.popAllUpToHtmlElement = function () {
for (var i = this.stackTop; i > 0; i--)
setEndLocation(this.items[i], parser.currentToken, treeAdapter);
OpenElementStack.prototype.popAllUpToHtmlElement.call(this);
};
stack.remove = function (element) {
setEndLocation(element, parser.currentToken, treeAdapter);
OpenElementStack.prototype.remove.call(this, element);
};
}
exports.assign = function (parser) {
//NOTE: obtain Parser proto this way to avoid module circular references
var parserProto = Object.getPrototypeOf(parser),
treeAdapter = parser.treeAdapter;
//NOTE: patch _reset method
parser._reset = function (html, document, fragmentContext) {
parserProto._reset.call(this, html, document, fragmentContext);
this.attachableElementLocation = null;
this.lastFosterParentingLocation = null;
this.currentToken = null;
patchOpenElementsStack(this.openElements, parser);
};
parser._processTokenInForeignContent = function (token) {
this.currentToken = token;
parserProto._processTokenInForeignContent.call(this, token);
};
parser._processToken = function (token) {
this.currentToken = token;
parserProto._processToken.call(this, token);
//NOTE: <body> and <html> are never popped from the stack, so we need to updated
//their end location explicitly.
if (token.type === Tokenizer.END_TAG_TOKEN &&
(token.tagName === $.HTML ||
(token.tagName === $.BODY && this.openElements.hasInScope($.BODY)))) {
for (var i = this.openElements.stackTop; i >= 0; i--) {
var element = this.openElements.items[i];
if (this.treeAdapter.getTagName(element) === token.tagName) {
setEndLocation(element, token, treeAdapter);
break;
}
}
}
};
//Doctype
parser._setDocumentType = function (token) {
parserProto._setDocumentType.call(this, token);
var documentChildren = this.treeAdapter.getChildNodes(this.document),
cnLength = documentChildren.length;
for (var i = 0; i < cnLength; i++) {
var node = documentChildren[i];
if (this.treeAdapter.isDocumentTypeNode(node)) {
node.__location = token.location;
break;
}
}
};
//Elements
parser._attachElementToTree = function (element) {
//NOTE: _attachElementToTree is called from _appendElement, _insertElement and _insertTemplate methods.
//So we will use token location stored in this methods for the element.
element.__location = this.attachableElementLocation || null;
this.attachableElementLocation = null;
parserProto._attachElementToTree.call(this, element);
};
parser._appendElement = function (token, namespaceURI) {
this.attachableElementLocation = token.location;
parserProto._appendElement.call(this, token, namespaceURI);
};
parser._insertElement = function (token, namespaceURI) {
this.attachableElementLocation = token.location;
parserProto._insertElement.call(this, token, namespaceURI);
};
parser._insertTemplate = function (token) {
this.attachableElementLocation = token.location;
parserProto._insertTemplate.call(this, token);
var tmplContent = this.treeAdapter.getChildNodes(this.openElements.current)[0];
tmplContent.__location = null;
};
parser._insertFakeRootElement = function () {
parserProto._insertFakeRootElement.call(this);
this.openElements.current.__location = null;
};
//Comments
parser._appendCommentNode = function (token, parent) {
parserProto._appendCommentNode.call(this, token, parent);
var children = this.treeAdapter.getChildNodes(parent),
commentNode = children[children.length - 1];
commentNode.__location = token.location;
};
//Text
parser._findFosterParentingLocation = function () {
//NOTE: store last foster parenting location, so we will be able to find inserted text
//in case of foster parenting
this.lastFosterParentingLocation = parserProto._findFosterParentingLocation.call(this);
return this.lastFosterParentingLocation;
};
parser._insertCharacters = function (token) {
parserProto._insertCharacters.call(this, token);
var hasFosterParent = this._shouldFosterParentOnInsertion(),
parentingLocation = this.lastFosterParentingLocation,
parent = (hasFosterParent && parentingLocation.parent) ||
this.openElements.currentTmplContent ||
this.openElements.current,
siblings = this.treeAdapter.getChildNodes(parent),
textNodeIdx = hasFosterParent && parentingLocation.beforeElement ?
siblings.indexOf(parentingLocation.beforeElement) - 1 :
siblings.length - 1,
textNode = siblings[textNodeIdx];
//NOTE: if we have location assigned by another token, then just update end position
if (textNode.__location)
textNode.__location.end = token.location.end;
else
textNode.__location = token.location;
};
};

View File

@@ -0,0 +1,379 @@
'use strict';
var HTML = require('../common/html');
//Aliases
var $ = HTML.TAG_NAMES,
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 === $.RP || tn === $.RT || tn === $.DD || tn === $.DT || tn === $.LI;
case 6:
return tn === $.OPTION;
case 8:
return tn === $.OPTGROUP;
}
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
var OpenElementStack = module.exports = function (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
OpenElementStack.prototype._indexOf = function (element) {
var idx = -1;
for (var i = this.stackTop; i >= 0; i--) {
if (this.items[i] === element) {
idx = i;
break;
}
}
return idx;
};
//Update current element
OpenElementStack.prototype._isInTemplate = function () {
if (this.currentTagName !== $.TEMPLATE)
return false;
return this.treeAdapter.getNamespaceURI(this.current) === NS.HTML;
};
OpenElementStack.prototype._updateCurrentElement = function () {
this.current = this.items[this.stackTop];
this.currentTagName = this.current && this.treeAdapter.getTagName(this.current);
this.currentTmplContent = this._isInTemplate() ? this.treeAdapter.getChildNodes(this.current)[0] : null;
};
//Mutations
OpenElementStack.prototype.push = function (element) {
this.items[++this.stackTop] = element;
this._updateCurrentElement();
if (this._isInTemplate())
this.tmplCount++;
};
OpenElementStack.prototype.pop = function () {
this.stackTop--;
if (this.tmplCount > 0 && this._isInTemplate())
this.tmplCount--;
this._updateCurrentElement();
};
OpenElementStack.prototype.replace = function (oldElement, newElement) {
var idx = this._indexOf(oldElement);
this.items[idx] = newElement;
if (idx === this.stackTop)
this._updateCurrentElement();
};
OpenElementStack.prototype.insertAfter = function (referenceElement, newElement) {
var insertionIdx = this._indexOf(referenceElement) + 1;
this.items.splice(insertionIdx, 0, newElement);
if (insertionIdx == ++this.stackTop)
this._updateCurrentElement();
};
OpenElementStack.prototype.popUntilTagNamePopped = function (tagName) {
while (this.stackTop > -1) {
var tn = this.currentTagName;
this.pop();
if (tn === tagName)
break;
}
};
OpenElementStack.prototype.popUntilTemplatePopped = function () {
while (this.stackTop > -1) {
var tn = this.currentTagName,
ns = this.treeAdapter.getNamespaceURI(this.current);
this.pop();
if (tn === $.TEMPLATE && ns === NS.HTML)
break;
}
};
OpenElementStack.prototype.popUntilElementPopped = function (element) {
while (this.stackTop > -1) {
var poppedElement = this.current;
this.pop();
if (poppedElement === element)
break;
}
};
OpenElementStack.prototype.popUntilNumberedHeaderPopped = function () {
while (this.stackTop > -1) {
var tn = this.currentTagName;
this.pop();
if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6)
break;
}
};
OpenElementStack.prototype.popAllUpToHtmlElement = function () {
//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();
};
OpenElementStack.prototype.clearBackToTableContext = function () {
while (this.currentTagName !== $.TABLE && this.currentTagName !== $.TEMPLATE && this.currentTagName !== $.HTML)
this.pop();
};
OpenElementStack.prototype.clearBackToTableBodyContext = function () {
while (this.currentTagName !== $.TBODY && this.currentTagName !== $.TFOOT &&
this.currentTagName !== $.THEAD && this.currentTagName !== $.TEMPLATE &&
this.currentTagName !== $.HTML) {
this.pop();
}
};
OpenElementStack.prototype.clearBackToTableRowContext = function () {
while (this.currentTagName !== $.TR && this.currentTagName !== $.TEMPLATE && this.currentTagName !== $.HTML)
this.pop();
};
OpenElementStack.prototype.remove = function (element) {
for (var i = this.stackTop; i >= 0; i--) {
if (this.items[i] === element) {
this.items.splice(i, 1);
this.stackTop--;
this._updateCurrentElement();
break;
}
}
};
//Search
OpenElementStack.prototype.tryPeekProperlyNestedBodyElement = function () {
//Properly nested <body> element (should be second element in stack).
var element = this.items[1];
return element && this.treeAdapter.getTagName(element) === $.BODY ? element : null;
};
OpenElementStack.prototype.contains = function (element) {
return this._indexOf(element) > -1;
};
OpenElementStack.prototype.getCommonAncestor = function (element) {
var elementIdx = this._indexOf(element);
return --elementIdx >= 0 ? this.items[elementIdx] : null;
};
OpenElementStack.prototype.isRootHtmlElementCurrent = function () {
return this.stackTop === 0 && this.currentTagName === $.HTML;
};
//Element in scope
OpenElementStack.prototype.hasInScope = function (tagName) {
for (var i = this.stackTop; i >= 0; i--) {
var tn = this.treeAdapter.getTagName(this.items[i]);
if (tn === tagName)
return true;
var ns = this.treeAdapter.getNamespaceURI(this.items[i]);
if (isScopingElement(tn, ns))
return false;
}
return true;
};
OpenElementStack.prototype.hasNumberedHeaderInScope = function () {
for (var i = this.stackTop; i >= 0; i--) {
var tn = this.treeAdapter.getTagName(this.items[i]);
if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6)
return true;
if (isScopingElement(tn, this.treeAdapter.getNamespaceURI(this.items[i])))
return false;
}
return true;
};
OpenElementStack.prototype.hasInListItemScope = function (tagName) {
for (var i = this.stackTop; i >= 0; i--) {
var tn = this.treeAdapter.getTagName(this.items[i]);
if (tn === tagName)
return true;
var ns = this.treeAdapter.getNamespaceURI(this.items[i]);
if (((tn === $.UL || tn === $.OL) && ns === NS.HTML) || isScopingElement(tn, ns))
return false;
}
return true;
};
OpenElementStack.prototype.hasInButtonScope = function (tagName) {
for (var i = this.stackTop; i >= 0; i--) {
var tn = this.treeAdapter.getTagName(this.items[i]);
if (tn === tagName)
return true;
var ns = this.treeAdapter.getNamespaceURI(this.items[i]);
if ((tn === $.BUTTON && ns === NS.HTML) || isScopingElement(tn, ns))
return false;
}
return true;
};
OpenElementStack.prototype.hasInTableScope = function (tagName) {
for (var i = this.stackTop; i >= 0; i--) {
var tn = this.treeAdapter.getTagName(this.items[i]);
if (tn === tagName)
return true;
var ns = this.treeAdapter.getNamespaceURI(this.items[i]);
if ((tn === $.TABLE || tn === $.TEMPLATE || tn === $.HTML) && ns === NS.HTML)
return false;
}
return true;
};
OpenElementStack.prototype.hasTableBodyContextInTableScope = function () {
for (var i = this.stackTop; i >= 0; i--) {
var tn = this.treeAdapter.getTagName(this.items[i]);
if (tn === $.TBODY || tn === $.THEAD || tn === $.TFOOT)
return true;
var ns = this.treeAdapter.getNamespaceURI(this.items[i]);
if ((tn === $.TABLE || tn === $.HTML) && ns === NS.HTML)
return false;
}
return true;
};
OpenElementStack.prototype.hasInSelectScope = function (tagName) {
for (var i = this.stackTop; i >= 0; i--) {
var tn = this.treeAdapter.getTagName(this.items[i]);
if (tn === tagName)
return true;
var ns = this.treeAdapter.getNamespaceURI(this.items[i]);
if (tn !== $.OPTION && tn !== $.OPTGROUP && ns === NS.HTML)
return false;
}
return true;
};
//Implied end tags
OpenElementStack.prototype.generateImpliedEndTags = function () {
while (isImpliedEndTagRequired(this.currentTagName))
this.pop();
};
OpenElementStack.prototype.generateImpliedEndTagsWithExclusion = function (exclusionTagName) {
while (isImpliedEndTagRequired(this.currentTagName) && this.currentTagName !== exclusionTagName)
this.pop();
};

2827
build/node_modules/parse5/lib/tree_construction/parser.js generated vendored Normal file

File diff suppressed because it is too large Load Diff