From bff194f4c2da8de290f2f4c1852a9341fb6f8553 Mon Sep 17 00:00:00 2001 From: melchi0r Date: Tue, 17 Nov 2020 16:48:50 -0500 Subject: [PATCH 1/3] feature/broken-block --- content/lib/droplet.js | 17018 ++++++++++++++++----------------- content/lib/jquery-turtle.js | 6 + content/lib/pc_py_wrapper.js | 38 +- content/lib/pencilcode.py | 30 +- content/src/palette.js | 131 +- content/src/view.js | 2 +- npm-shrinkwrap.json | 6212 ++++++------ package.json | 13 +- test/lib/testutil.js | 2 +- 9 files changed, 11989 insertions(+), 11463 deletions(-) diff --git a/content/lib/droplet.js b/content/lib/droplet.js index 633c5b0c..e08297c7 100644 --- a/content/lib/droplet.js +++ b/content/lib/droplet.js @@ -52060,8532 +52060,8532 @@ function hasOwnProperty(obj, prop) { }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./support/isBuffer":78,"_process":64,"inherits":61}],80:[function(require,module,exports){ -'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 '; - - if (name) - str += name; - - if (publicId !== null) - str += ' PUBLIC ' + enquoteDoctypeId(publicId); - - else if (systemId !== null) - str += ' SYSTEM'; - - if (systemId !== null) - str += ' ' + enquoteDoctypeId(systemId); - - return str; -}; +'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 '; + + if (name) + str += name; + + if (publicId !== null) + str += ' PUBLIC ' + enquoteDoctypeId(publicId); + + else if (systemId !== null) + str += ' SYSTEM'; + + if (systemId !== null) + str += ' ' + enquoteDoctypeId(systemId); + + return str; +}; + +},{}],81:[function(require,module,exports){ +'use strict'; + +var Tokenizer = require('../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', + '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' + }, + 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; + var 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 (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 +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 (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); +} + +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":97,"./html":82}],82:[function(require,module,exports){ +'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', + + 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', + 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', + + 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' +}; + +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][$.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][$.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; + +},{}],83:[function(require,module,exports){ +'use strict'; + +module.exports = function mergeOptions(defaults, options) { + options = options || {}; + + return [defaults, options].reduce(function (merged, optObj) { + Object.keys(optObj).forEach(function (key) { + merged[key] = optObj[key]; + }); + + return merged; + }, {}); +}; + +},{}],84:[function(require,module,exports){ +'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, + 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 +}; + +},{}],85:[function(require,module,exports){ +'use strict'; + +var Parser = require('./parser'), + Serializer = require('./serializer'); + +/** @namespace parse5 */ + +/** + * Parses an HTML string. + * @function parse + * @memberof parse5 + * @instance + * @param {string} html - Input HTML string. + * @param {ParserOptions} [options] - Parsing options. + * @returns {ASTNode} document + * @example + * var parse5 = require('parse5'); + * + * var document = parse5.parse('Hi there!'); + */ +exports.parse = function parse(html, options) { + var parser = new Parser(options); + + return parser.parse(html); +}; + +/** + * Parses an HTML fragment. + * @function parseFragment + * @memberof parse5 + * @instance + * @param {ASTNode} [fragmentContext] - Parsing context element. If specified, given fragment + * will be parsed as if it was set to the context element's `innerHTML` property. + * @param {string} html - Input HTML fragment string. + * @param {ParserOptions} [options] - Parsing options. + * @returns {ASTNode} documentFragment + * @example + * var parse5 = require('parse5'); + * + * var documentFragment = parse5.parseFragment('
'); + * + * // Parses the html fragment in the context of the parsed element. + * var trFragment = parser.parseFragment(documentFragment.childNodes[0], ''); + */ +exports.parseFragment = function parseFragment(fragmentContext, html, options) { + if (typeof fragmentContext === 'string') { + options = html; + html = fragmentContext; + fragmentContext = null; + } + + var parser = new Parser(options); + + return parser.parseFragment(html, fragmentContext); +}; + +/** + * Serializes an AST node to an HTML string. + * @function serialize + * @memberof parse5 + * @instance + * @param {ASTNode} node - Node to serialize. + * @param {SerializerOptions} [options] - Serialization options. + * @returns {String} html + * @example + * var parse5 = require('parse5'); + * + * var document = parse5.parse('Hi there!'); + * + * // Serializes a document. + * var html = parse5.serialize(document); + * + * // Serializes the element content. + * var bodyInnerHtml = parse5.serialize(document.childNodes[0].childNodes[1]); + */ +exports.serialize = function (node, options) { + var serializer = new Serializer(node, options); + + return serializer.serialize(); +}; + +/** + * Provides built-in tree adapters that can be used for parsing and serialization. + * @var treeAdapters + * @memberof parse5 + * @instance + * @property {TreeAdapter} default - Default tree format for parse5. + * @property {TreeAdapter} htmlparser2 - Quite popular [htmlparser2](https://github.com/fb55/htmlparser2) tree format + * (e.g. used by [cheerio](https://github.com/MatthewMueller/cheerio) and [jsdom](https://github.com/tmpvar/jsdom)). + * @example + * var parse5 = require('parse5'); + * + * // Uses the default tree adapter for parsing. + * var document = parse5.parse('
', { treeAdapter: parse5.treeAdapters.default }); + * + * // Uses the htmlparser2 tree adapter with the SerializerStream. + * var serializer = new parse5.SerializerStream(node, { treeAdapter: parse5.treeAdapters.htmlparser2 }); + */ +exports.treeAdapters = { + default: require('./tree_adapters/default'), + htmlparser2: require('./tree_adapters/htmlparser2') +}; + + +// Streaming +exports.ParserStream = require('./parser/stream'); +exports.SerializerStream = require('./serializer/stream'); +exports.SAXParser = require('./sax'); + +},{"./parser":89,"./parser/stream":91,"./sax":93,"./serializer":95,"./serializer/stream":96,"./tree_adapters/default":100,"./tree_adapters/htmlparser2":101}],86:[function(require,module,exports){ +'use strict'; + +var OpenElementStack = require('../parser/open_element_stack'), + Tokenizer = require('../tokenizer'), + HTML = require('../common/html'); + + +//Aliases +var $ = HTML.TAG_NAMES; + + +function setEndLocation(element, closingToken, treeAdapter) { + var loc = element.__location; + + if (!loc) + return; + + /** + * @typedef {Object} ElementLocationInfo + * @extends StartTagLocationInfo + * + * @property {StartTagLocationInfo} startTag - Element's start tag location info. + * @property {LocationInfo} endTag - Element's end tag location info. + */ + if (!loc.startTag) { + loc.startTag = { + line: loc.line, + col: loc.col, + startOffset: loc.startOffset, + endOffset: loc.endOffset + }; + if (loc.attrs) + loc.startTag.attrs = loc.attrs; + } + + if (closingToken.location) { + var ctLocation = closingToken.location, + tn = treeAdapter.getTagName(element), + // NOTE: For cases like

- First 'p' closes without a closing tag and + // for cases like - 'p' closes without a closing tag + isClosingEndTag = closingToken.type === Tokenizer.END_TAG_TOKEN && + tn === closingToken.tagName; + + if (isClosingEndTag) { + loc.endTag = { + line: ctLocation.line, + col: ctLocation.col, + startOffset: ctLocation.startOffset, + endOffset: ctLocation.endOffset + }; + } + + loc.endOffset = ctLocation.endOffset; + } +} + + +exports.assign = function (parser) { + //NOTE: obtain Parser proto this way to avoid module circular references + var parserProto = Object.getPrototypeOf(parser), + treeAdapter = parser.treeAdapter, + attachableElementLocation = null, + lastFosterParentingLocation = null, + currentToken = null; + + + //NOTE: patch _bootstrap method + parser._bootstrap = function (document, fragmentContext) { + parserProto._bootstrap.call(this, document, fragmentContext); + + attachableElementLocation = null; + lastFosterParentingLocation = null; + currentToken = null; + + //OpenElementStack + parser.openElements.pop = function () { + setEndLocation(this.current, currentToken, treeAdapter); + OpenElementStack.prototype.pop.call(this); + }; + + parser.openElements.popAllUpToHtmlElement = function () { + for (var i = this.stackTop; i > 0; i--) + setEndLocation(this.items[i], currentToken, treeAdapter); + + OpenElementStack.prototype.popAllUpToHtmlElement.call(this); + }; + + parser.openElements.remove = function (element) { + setEndLocation(element, currentToken, treeAdapter); + OpenElementStack.prototype.remove.call(this, element); + }; + }; + + + //Token processing + parser._processTokenInForeignContent = function (token) { + currentToken = token; + parserProto._processTokenInForeignContent.call(this, token); + }; + + parser._processToken = function (token) { + currentToken = token; + parserProto._processToken.call(this, token); + + //NOTE: and 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 = attachableElementLocation || null; + attachableElementLocation = null; + parserProto._attachElementToTree.call(this, element); + }; + + parser._appendElement = function (token, namespaceURI) { + attachableElementLocation = token.location; + parserProto._appendElement.call(this, token, namespaceURI); + }; + + parser._insertElement = function (token, namespaceURI) { + attachableElementLocation = token.location; + parserProto._insertElement.call(this, token, namespaceURI); + }; + + parser._insertTemplate = function (token) { + attachableElementLocation = token.location; + parserProto._insertTemplate.call(this, token); + + var tmplContent = this.treeAdapter.getTemplateContent(this.openElements.current); + + 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 + lastFosterParentingLocation = parserProto._findFosterParentingLocation.call(this); + return lastFosterParentingLocation; + }; + + parser._insertCharacters = function (token) { + parserProto._insertCharacters.call(this, token); + + var hasFosterParent = this._shouldFosterParentOnInsertion(), + parent = hasFosterParent && lastFosterParentingLocation.parent || + this.openElements.currentTmplContent || + this.openElements.current, + siblings = this.treeAdapter.getChildNodes(parent), + textNodeIdx = hasFosterParent && lastFosterParentingLocation.beforeElement ? + siblings.indexOf(lastFosterParentingLocation.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.endOffset = token.location.endOffset; + + else + textNode.__location = token.location; + }; +}; + + +},{"../common/html":82,"../parser/open_element_stack":90,"../tokenizer":97}],87:[function(require,module,exports){ +'use strict'; + +var UNICODE = require('../common/unicode'); + +//Aliases +var $ = UNICODE.CODE_POINTS; + + +exports.assign = function (tokenizer) { + //NOTE: obtain Tokenizer proto this way to avoid module circular references + var tokenizerProto = Object.getPrototypeOf(tokenizer), + tokenStartOffset = -1, + tokenCol = -1, + tokenLine = 1, + isEol = false, + lineStartPosStack = [0], + lineStartPos = 0, + col = -1, + line = 1; + + function attachLocationInfo(token) { + /** + * @typedef {Object} LocationInfo + * + * @property {Number} line - One-based line index + * @property {Number} col - One-based column index + * @property {Number} startOffset - Zero-based first character index + * @property {Number} endOffset - Zero-based last character index + */ + token.location = { + line: tokenLine, + col: tokenCol, + startOffset: tokenStartOffset, + endOffset: -1 + }; + } + + //NOTE: patch consumption method to track line/col information + tokenizer._consume = function () { + var cp = tokenizerProto._consume.call(this); + + //NOTE: LF should be in the last column of the line + if (isEol) { + isEol = false; + line++; + lineStartPosStack.push(this.preprocessor.pos); + lineStartPos = this.preprocessor.pos; + } + + if (cp === $.LINE_FEED) + isEol = true; + + col = this.preprocessor.pos - lineStartPos + 1; + + return cp; + }; + + tokenizer._unconsume = function () { + tokenizerProto._unconsume.call(this); + + while (lineStartPos > this.preprocessor.pos && lineStartPosStack.length > 1) { + lineStartPos = lineStartPosStack.pop(); + line--; + } + + col = this.preprocessor.pos - lineStartPos + 1; + }; + + //NOTE: patch token creation methods and attach location objects + tokenizer._createStartTagToken = function () { + tokenizerProto._createStartTagToken.call(this); + attachLocationInfo(this.currentToken); + }; + + tokenizer._createEndTagToken = function () { + tokenizerProto._createEndTagToken.call(this); + attachLocationInfo(this.currentToken); + }; + + tokenizer._createCommentToken = function () { + tokenizerProto._createCommentToken.call(this); + attachLocationInfo(this.currentToken); + }; + + tokenizer._createDoctypeToken = function (initialName) { + tokenizerProto._createDoctypeToken.call(this, initialName); + attachLocationInfo(this.currentToken); + }; + + tokenizer._createCharacterToken = function (type, ch) { + tokenizerProto._createCharacterToken.call(this, type, ch); + attachLocationInfo(this.currentCharacterToken); + }; + + tokenizer._createAttr = function (attrNameFirstCh) { + tokenizerProto._createAttr.call(this, attrNameFirstCh); + this.currentAttrLocation = { + line: line, + col: col, + startOffset: this.preprocessor.pos, + endOffset: -1 + }; + }; + + tokenizer._leaveAttrName = function (toState) { + tokenizerProto._leaveAttrName.call(this, toState); + this._attachCurrentAttrLocationInfo(); + }; + + tokenizer._leaveAttrValue = function (toState) { + tokenizerProto._leaveAttrValue.call(this, toState); + this._attachCurrentAttrLocationInfo(); + }; + + tokenizer._attachCurrentAttrLocationInfo = function () { + this.currentAttrLocation.endOffset = this.preprocessor.pos; + + if (!this.currentToken.location.attrs) + this.currentToken.location.attrs = {}; + + /** + * @typedef {Object} StartTagLocationInfo + * @extends LocationInfo + * + * @property {Dictionary} attrs - Start tag attributes' location info. + */ + this.currentToken.location.attrs[this.currentAttr.name] = this.currentAttrLocation; + }; + + //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.endOffset = this.currentToken.location.startOffset; + + this.currentToken.location.endOffset = 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. + //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 (this.currentCharacterToken && this.currentCharacterToken.location.endOffset === -1) + this.currentCharacterToken.location.endOffset = 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) { + tokenStartOffset = this.preprocessor.pos; + tokenLine = line; + tokenCol = col; + tokenizerProto[state].call(this, cp); + }; + }); +}; + +},{"../common/unicode":84}],88:[function(require,module,exports){ +'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), + 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; +}; + +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 (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 (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; +}; + +},{}],89:[function(require,module,exports){ +'use strict'; + +var Tokenizer = require('../tokenizer'), + OpenElementStack = require('./open_element_stack'), + FormattingElementList = require('./formatting_element_list'), + locationInfoMixin = require('../location_info/parser_mixin'), + defaultTreeAdapter = require('../tree_adapters/default'), + doctype = require('../common/doctype'), + foreignContent = require('../common/foreign_content'), + mergeOptions = require('../common/merge_options'), + UNICODE = require('../common/unicode'), + HTML = require('../common/html'); + +//Aliases +var $ = HTML.TAG_NAMES, + NS = HTML.NAMESPACES, + ATTRS = HTML.ATTRS; + +/** + * @typedef {Object} ParserOptions + * + * @property {Boolean} [locationInfo=false] - Enables source code location information for the nodes. + * When enabled, each node (except root node) has the `__location` property. In case the node is not an empty element, + * `__location` will be {@link ElementLocationInfo} object, otherwise it's {@link LocationInfo}. + * If the element was implicitly created by the parser it's `__location` property will be `null`. + * + * @property {TreeAdapter} [treeAdapter=parse5.treeAdapters.default] - Specifies the resulting tree format. + */ +var DEFAULT_OPTIONS = { + locationInfo: false, + treeAdapter: defaultTreeAdapter +}; + +//Misc constants +var HIDDEN_INPUT_TYPE = 'hidden'; + +//Adoption agency loops iteration count +var AA_OUTER_LOOP_ITER = 8, + AA_INNER_LOOP_ITER = 3; + +//Insertion modes +var INITIAL_MODE = 'INITIAL_MODE', + BEFORE_HTML_MODE = 'BEFORE_HTML_MODE', + BEFORE_HEAD_MODE = 'BEFORE_HEAD_MODE', + IN_HEAD_MODE = 'IN_HEAD_MODE', + AFTER_HEAD_MODE = 'AFTER_HEAD_MODE', + IN_BODY_MODE = 'IN_BODY_MODE', + TEXT_MODE = 'TEXT_MODE', + IN_TABLE_MODE = 'IN_TABLE_MODE', + IN_TABLE_TEXT_MODE = 'IN_TABLE_TEXT_MODE', + IN_CAPTION_MODE = 'IN_CAPTION_MODE', + IN_COLUMN_GROUP_MODE = 'IN_COLUMN_GROUP_MODE', + IN_TABLE_BODY_MODE = 'IN_TABLE_BODY_MODE', + IN_ROW_MODE = 'IN_ROW_MODE', + IN_CELL_MODE = 'IN_CELL_MODE', + IN_SELECT_MODE = 'IN_SELECT_MODE', + IN_SELECT_IN_TABLE_MODE = 'IN_SELECT_IN_TABLE_MODE', + IN_TEMPLATE_MODE = 'IN_TEMPLATE_MODE', + AFTER_BODY_MODE = 'AFTER_BODY_MODE', + IN_FRAMESET_MODE = 'IN_FRAMESET_MODE', + AFTER_FRAMESET_MODE = 'AFTER_FRAMESET_MODE', + AFTER_AFTER_BODY_MODE = 'AFTER_AFTER_BODY_MODE', + AFTER_AFTER_FRAMESET_MODE = 'AFTER_AFTER_FRAMESET_MODE'; + +//Insertion mode reset map +var INSERTION_MODE_RESET_MAP = {}; + +INSERTION_MODE_RESET_MAP[$.TR] = IN_ROW_MODE; +INSERTION_MODE_RESET_MAP[$.TBODY] = +INSERTION_MODE_RESET_MAP[$.THEAD] = +INSERTION_MODE_RESET_MAP[$.TFOOT] = IN_TABLE_BODY_MODE; +INSERTION_MODE_RESET_MAP[$.CAPTION] = IN_CAPTION_MODE; +INSERTION_MODE_RESET_MAP[$.COLGROUP] = IN_COLUMN_GROUP_MODE; +INSERTION_MODE_RESET_MAP[$.TABLE] = IN_TABLE_MODE; +INSERTION_MODE_RESET_MAP[$.BODY] = IN_BODY_MODE; +INSERTION_MODE_RESET_MAP[$.FRAMESET] = IN_FRAMESET_MODE; + +//Template insertion mode switch map +var TEMPLATE_INSERTION_MODE_SWITCH_MAP = {}; + +TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.CAPTION] = +TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.COLGROUP] = +TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.TBODY] = +TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.TFOOT] = +TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.THEAD] = IN_TABLE_MODE; +TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.COL] = IN_COLUMN_GROUP_MODE; +TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.TR] = IN_TABLE_BODY_MODE; +TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.TD] = +TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.TH] = IN_ROW_MODE; + +//Token handlers map for insertion modes +var _ = {}; + +_[INITIAL_MODE] = {}; +_[INITIAL_MODE][Tokenizer.CHARACTER_TOKEN] = +_[INITIAL_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenInInitialMode; +_[INITIAL_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = ignoreToken; +_[INITIAL_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[INITIAL_MODE][Tokenizer.DOCTYPE_TOKEN] = doctypeInInitialMode; +_[INITIAL_MODE][Tokenizer.START_TAG_TOKEN] = +_[INITIAL_MODE][Tokenizer.END_TAG_TOKEN] = +_[INITIAL_MODE][Tokenizer.EOF_TOKEN] = tokenInInitialMode; + +_[BEFORE_HTML_MODE] = {}; +_[BEFORE_HTML_MODE][Tokenizer.CHARACTER_TOKEN] = +_[BEFORE_HTML_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenBeforeHtml; +_[BEFORE_HTML_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = ignoreToken; +_[BEFORE_HTML_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[BEFORE_HTML_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[BEFORE_HTML_MODE][Tokenizer.START_TAG_TOKEN] = startTagBeforeHtml; +_[BEFORE_HTML_MODE][Tokenizer.END_TAG_TOKEN] = endTagBeforeHtml; +_[BEFORE_HTML_MODE][Tokenizer.EOF_TOKEN] = tokenBeforeHtml; + +_[BEFORE_HEAD_MODE] = {}; +_[BEFORE_HEAD_MODE][Tokenizer.CHARACTER_TOKEN] = +_[BEFORE_HEAD_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenBeforeHead; +_[BEFORE_HEAD_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = ignoreToken; +_[BEFORE_HEAD_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[BEFORE_HEAD_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[BEFORE_HEAD_MODE][Tokenizer.START_TAG_TOKEN] = startTagBeforeHead; +_[BEFORE_HEAD_MODE][Tokenizer.END_TAG_TOKEN] = endTagBeforeHead; +_[BEFORE_HEAD_MODE][Tokenizer.EOF_TOKEN] = tokenBeforeHead; + +_[IN_HEAD_MODE] = {}; +_[IN_HEAD_MODE][Tokenizer.CHARACTER_TOKEN] = +_[IN_HEAD_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenInHead; +_[IN_HEAD_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters; +_[IN_HEAD_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[IN_HEAD_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[IN_HEAD_MODE][Tokenizer.START_TAG_TOKEN] = startTagInHead; +_[IN_HEAD_MODE][Tokenizer.END_TAG_TOKEN] = endTagInHead; +_[IN_HEAD_MODE][Tokenizer.EOF_TOKEN] = tokenInHead; + +_[AFTER_HEAD_MODE] = {}; +_[AFTER_HEAD_MODE][Tokenizer.CHARACTER_TOKEN] = +_[AFTER_HEAD_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenAfterHead; +_[AFTER_HEAD_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters; +_[AFTER_HEAD_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[AFTER_HEAD_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[AFTER_HEAD_MODE][Tokenizer.START_TAG_TOKEN] = startTagAfterHead; +_[AFTER_HEAD_MODE][Tokenizer.END_TAG_TOKEN] = endTagAfterHead; +_[AFTER_HEAD_MODE][Tokenizer.EOF_TOKEN] = tokenAfterHead; + +_[IN_BODY_MODE] = {}; +_[IN_BODY_MODE][Tokenizer.CHARACTER_TOKEN] = characterInBody; +_[IN_BODY_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken; +_[IN_BODY_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody; +_[IN_BODY_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[IN_BODY_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[IN_BODY_MODE][Tokenizer.START_TAG_TOKEN] = startTagInBody; +_[IN_BODY_MODE][Tokenizer.END_TAG_TOKEN] = endTagInBody; +_[IN_BODY_MODE][Tokenizer.EOF_TOKEN] = eofInBody; + +_[TEXT_MODE] = {}; +_[TEXT_MODE][Tokenizer.CHARACTER_TOKEN] = +_[TEXT_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = +_[TEXT_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters; +_[TEXT_MODE][Tokenizer.COMMENT_TOKEN] = +_[TEXT_MODE][Tokenizer.DOCTYPE_TOKEN] = +_[TEXT_MODE][Tokenizer.START_TAG_TOKEN] = ignoreToken; +_[TEXT_MODE][Tokenizer.END_TAG_TOKEN] = endTagInText; +_[TEXT_MODE][Tokenizer.EOF_TOKEN] = eofInText; + +_[IN_TABLE_MODE] = {}; +_[IN_TABLE_MODE][Tokenizer.CHARACTER_TOKEN] = +_[IN_TABLE_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = +_[IN_TABLE_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = characterInTable; +_[IN_TABLE_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[IN_TABLE_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[IN_TABLE_MODE][Tokenizer.START_TAG_TOKEN] = startTagInTable; +_[IN_TABLE_MODE][Tokenizer.END_TAG_TOKEN] = endTagInTable; +_[IN_TABLE_MODE][Tokenizer.EOF_TOKEN] = eofInBody; + +_[IN_TABLE_TEXT_MODE] = {}; +_[IN_TABLE_TEXT_MODE][Tokenizer.CHARACTER_TOKEN] = characterInTableText; +_[IN_TABLE_TEXT_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken; +_[IN_TABLE_TEXT_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInTableText; +_[IN_TABLE_TEXT_MODE][Tokenizer.COMMENT_TOKEN] = +_[IN_TABLE_TEXT_MODE][Tokenizer.DOCTYPE_TOKEN] = +_[IN_TABLE_TEXT_MODE][Tokenizer.START_TAG_TOKEN] = +_[IN_TABLE_TEXT_MODE][Tokenizer.END_TAG_TOKEN] = +_[IN_TABLE_TEXT_MODE][Tokenizer.EOF_TOKEN] = tokenInTableText; + +_[IN_CAPTION_MODE] = {}; +_[IN_CAPTION_MODE][Tokenizer.CHARACTER_TOKEN] = characterInBody; +_[IN_CAPTION_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken; +_[IN_CAPTION_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody; +_[IN_CAPTION_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[IN_CAPTION_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[IN_CAPTION_MODE][Tokenizer.START_TAG_TOKEN] = startTagInCaption; +_[IN_CAPTION_MODE][Tokenizer.END_TAG_TOKEN] = endTagInCaption; +_[IN_CAPTION_MODE][Tokenizer.EOF_TOKEN] = eofInBody; + +_[IN_COLUMN_GROUP_MODE] = {}; +_[IN_COLUMN_GROUP_MODE][Tokenizer.CHARACTER_TOKEN] = +_[IN_COLUMN_GROUP_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenInColumnGroup; +_[IN_COLUMN_GROUP_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters; +_[IN_COLUMN_GROUP_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[IN_COLUMN_GROUP_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[IN_COLUMN_GROUP_MODE][Tokenizer.START_TAG_TOKEN] = startTagInColumnGroup; +_[IN_COLUMN_GROUP_MODE][Tokenizer.END_TAG_TOKEN] = endTagInColumnGroup; +_[IN_COLUMN_GROUP_MODE][Tokenizer.EOF_TOKEN] = eofInBody; + +_[IN_TABLE_BODY_MODE] = {}; +_[IN_TABLE_BODY_MODE][Tokenizer.CHARACTER_TOKEN] = +_[IN_TABLE_BODY_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = +_[IN_TABLE_BODY_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = characterInTable; +_[IN_TABLE_BODY_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[IN_TABLE_BODY_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[IN_TABLE_BODY_MODE][Tokenizer.START_TAG_TOKEN] = startTagInTableBody; +_[IN_TABLE_BODY_MODE][Tokenizer.END_TAG_TOKEN] = endTagInTableBody; +_[IN_TABLE_BODY_MODE][Tokenizer.EOF_TOKEN] = eofInBody; + +_[IN_ROW_MODE] = {}; +_[IN_ROW_MODE][Tokenizer.CHARACTER_TOKEN] = +_[IN_ROW_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = +_[IN_ROW_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = characterInTable; +_[IN_ROW_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[IN_ROW_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[IN_ROW_MODE][Tokenizer.START_TAG_TOKEN] = startTagInRow; +_[IN_ROW_MODE][Tokenizer.END_TAG_TOKEN] = endTagInRow; +_[IN_ROW_MODE][Tokenizer.EOF_TOKEN] = eofInBody; + +_[IN_CELL_MODE] = {}; +_[IN_CELL_MODE][Tokenizer.CHARACTER_TOKEN] = characterInBody; +_[IN_CELL_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken; +_[IN_CELL_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody; +_[IN_CELL_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[IN_CELL_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[IN_CELL_MODE][Tokenizer.START_TAG_TOKEN] = startTagInCell; +_[IN_CELL_MODE][Tokenizer.END_TAG_TOKEN] = endTagInCell; +_[IN_CELL_MODE][Tokenizer.EOF_TOKEN] = eofInBody; + +_[IN_SELECT_MODE] = {}; +_[IN_SELECT_MODE][Tokenizer.CHARACTER_TOKEN] = insertCharacters; +_[IN_SELECT_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken; +_[IN_SELECT_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters; +_[IN_SELECT_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[IN_SELECT_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[IN_SELECT_MODE][Tokenizer.START_TAG_TOKEN] = startTagInSelect; +_[IN_SELECT_MODE][Tokenizer.END_TAG_TOKEN] = endTagInSelect; +_[IN_SELECT_MODE][Tokenizer.EOF_TOKEN] = eofInBody; + +_[IN_SELECT_IN_TABLE_MODE] = {}; +_[IN_SELECT_IN_TABLE_MODE][Tokenizer.CHARACTER_TOKEN] = insertCharacters; +_[IN_SELECT_IN_TABLE_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken; +_[IN_SELECT_IN_TABLE_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters; +_[IN_SELECT_IN_TABLE_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[IN_SELECT_IN_TABLE_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[IN_SELECT_IN_TABLE_MODE][Tokenizer.START_TAG_TOKEN] = startTagInSelectInTable; +_[IN_SELECT_IN_TABLE_MODE][Tokenizer.END_TAG_TOKEN] = endTagInSelectInTable; +_[IN_SELECT_IN_TABLE_MODE][Tokenizer.EOF_TOKEN] = eofInBody; + +_[IN_TEMPLATE_MODE] = {}; +_[IN_TEMPLATE_MODE][Tokenizer.CHARACTER_TOKEN] = characterInBody; +_[IN_TEMPLATE_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken; +_[IN_TEMPLATE_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody; +_[IN_TEMPLATE_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[IN_TEMPLATE_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[IN_TEMPLATE_MODE][Tokenizer.START_TAG_TOKEN] = startTagInTemplate; +_[IN_TEMPLATE_MODE][Tokenizer.END_TAG_TOKEN] = endTagInTemplate; +_[IN_TEMPLATE_MODE][Tokenizer.EOF_TOKEN] = eofInTemplate; + +_[AFTER_BODY_MODE] = {}; +_[AFTER_BODY_MODE][Tokenizer.CHARACTER_TOKEN] = +_[AFTER_BODY_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenAfterBody; +_[AFTER_BODY_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody; +_[AFTER_BODY_MODE][Tokenizer.COMMENT_TOKEN] = appendCommentToRootHtmlElement; +_[AFTER_BODY_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[AFTER_BODY_MODE][Tokenizer.START_TAG_TOKEN] = startTagAfterBody; +_[AFTER_BODY_MODE][Tokenizer.END_TAG_TOKEN] = endTagAfterBody; +_[AFTER_BODY_MODE][Tokenizer.EOF_TOKEN] = stopParsing; + +_[IN_FRAMESET_MODE] = {}; +_[IN_FRAMESET_MODE][Tokenizer.CHARACTER_TOKEN] = +_[IN_FRAMESET_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken; +_[IN_FRAMESET_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters; +_[IN_FRAMESET_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[IN_FRAMESET_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[IN_FRAMESET_MODE][Tokenizer.START_TAG_TOKEN] = startTagInFrameset; +_[IN_FRAMESET_MODE][Tokenizer.END_TAG_TOKEN] = endTagInFrameset; +_[IN_FRAMESET_MODE][Tokenizer.EOF_TOKEN] = stopParsing; + +_[AFTER_FRAMESET_MODE] = {}; +_[AFTER_FRAMESET_MODE][Tokenizer.CHARACTER_TOKEN] = +_[AFTER_FRAMESET_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken; +_[AFTER_FRAMESET_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters; +_[AFTER_FRAMESET_MODE][Tokenizer.COMMENT_TOKEN] = appendComment; +_[AFTER_FRAMESET_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[AFTER_FRAMESET_MODE][Tokenizer.START_TAG_TOKEN] = startTagAfterFrameset; +_[AFTER_FRAMESET_MODE][Tokenizer.END_TAG_TOKEN] = endTagAfterFrameset; +_[AFTER_FRAMESET_MODE][Tokenizer.EOF_TOKEN] = stopParsing; + +_[AFTER_AFTER_BODY_MODE] = {}; +_[AFTER_AFTER_BODY_MODE][Tokenizer.CHARACTER_TOKEN] = tokenAfterAfterBody; +_[AFTER_AFTER_BODY_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenAfterAfterBody; +_[AFTER_AFTER_BODY_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody; +_[AFTER_AFTER_BODY_MODE][Tokenizer.COMMENT_TOKEN] = appendCommentToDocument; +_[AFTER_AFTER_BODY_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[AFTER_AFTER_BODY_MODE][Tokenizer.START_TAG_TOKEN] = startTagAfterAfterBody; +_[AFTER_AFTER_BODY_MODE][Tokenizer.END_TAG_TOKEN] = tokenAfterAfterBody; +_[AFTER_AFTER_BODY_MODE][Tokenizer.EOF_TOKEN] = stopParsing; + +_[AFTER_AFTER_FRAMESET_MODE] = {}; +_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.CHARACTER_TOKEN] = +_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken; +_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody; +_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.COMMENT_TOKEN] = appendCommentToDocument; +_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken; +_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.START_TAG_TOKEN] = startTagAfterAfterFrameset; +_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.END_TAG_TOKEN] = ignoreToken; +_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.EOF_TOKEN] = stopParsing; + + +//Parser +var Parser = module.exports = function (options) { + this.options = mergeOptions(DEFAULT_OPTIONS, options); + + this.treeAdapter = this.options.treeAdapter; + this.pendingScript = null; + + if (this.options.locationInfo) + locationInfoMixin.assign(this); +}; + +// API +Parser.prototype.parse = function (html) { + var document = this.treeAdapter.createDocument(); + + this._bootstrap(document, null); + this.tokenizer.write(html, true); + this._runParsingLoop(null, null); + + return document; +}; + +Parser.prototype.parseFragment = function (html, fragmentContext) { + //NOTE: use
Shake it, baby