diff options
author | Minteck <contact@minteck.org> | 2022-10-18 08:59:09 +0200 |
---|---|---|
committer | Minteck <contact@minteck.org> | 2022-10-18 08:59:09 +0200 |
commit | 2c4ae43e688a9873e86211ea0e7aeb9ba770dd77 (patch) | |
tree | 17848d95522dab25d3cdeb9c4a6450e2a234861f /alarm/node_modules/parse5/lib/extensions | |
parent | 108525534c28013cfe1897c30e4565f9893f3766 (diff) | |
download | pluralconnect-2c4ae43e688a9873e86211ea0e7aeb9ba770dd77.tar.gz pluralconnect-2c4ae43e688a9873e86211ea0e7aeb9ba770dd77.tar.bz2 pluralconnect-2c4ae43e688a9873e86211ea0e7aeb9ba770dd77.zip |
Update
Diffstat (limited to 'alarm/node_modules/parse5/lib/extensions')
8 files changed, 604 insertions, 0 deletions
diff --git a/alarm/node_modules/parse5/lib/extensions/error-reporting/mixin-base.js b/alarm/node_modules/parse5/lib/extensions/error-reporting/mixin-base.js new file mode 100644 index 0000000..1e30cfc --- /dev/null +++ b/alarm/node_modules/parse5/lib/extensions/error-reporting/mixin-base.js @@ -0,0 +1,43 @@ +'use strict'; + +const Mixin = require('../../utils/mixin'); + +class ErrorReportingMixinBase extends Mixin { + constructor(host, opts) { + super(host); + + this.posTracker = null; + this.onParseError = opts.onParseError; + } + + _setErrorLocation(err) { + err.startLine = err.endLine = this.posTracker.line; + err.startCol = err.endCol = this.posTracker.col; + err.startOffset = err.endOffset = this.posTracker.offset; + } + + _reportError(code) { + const err = { + code: code, + startLine: -1, + startCol: -1, + startOffset: -1, + endLine: -1, + endCol: -1, + endOffset: -1 + }; + + this._setErrorLocation(err); + this.onParseError(err); + } + + _getOverriddenMethods(mxn) { + return { + _err(code) { + mxn._reportError(code); + } + }; + } +} + +module.exports = ErrorReportingMixinBase; diff --git a/alarm/node_modules/parse5/lib/extensions/error-reporting/parser-mixin.js b/alarm/node_modules/parse5/lib/extensions/error-reporting/parser-mixin.js new file mode 100644 index 0000000..107ec5a --- /dev/null +++ b/alarm/node_modules/parse5/lib/extensions/error-reporting/parser-mixin.js @@ -0,0 +1,52 @@ +'use strict'; + +const ErrorReportingMixinBase = require('./mixin-base'); +const ErrorReportingTokenizerMixin = require('./tokenizer-mixin'); +const LocationInfoTokenizerMixin = require('../location-info/tokenizer-mixin'); +const Mixin = require('../../utils/mixin'); + +class ErrorReportingParserMixin extends ErrorReportingMixinBase { + constructor(parser, opts) { + super(parser, opts); + + this.opts = opts; + this.ctLoc = null; + this.locBeforeToken = false; + } + + _setErrorLocation(err) { + if (this.ctLoc) { + err.startLine = this.ctLoc.startLine; + err.startCol = this.ctLoc.startCol; + err.startOffset = this.ctLoc.startOffset; + + err.endLine = this.locBeforeToken ? this.ctLoc.startLine : this.ctLoc.endLine; + err.endCol = this.locBeforeToken ? this.ctLoc.startCol : this.ctLoc.endCol; + err.endOffset = this.locBeforeToken ? this.ctLoc.startOffset : this.ctLoc.endOffset; + } + } + + _getOverriddenMethods(mxn, orig) { + return { + _bootstrap(document, fragmentContext) { + orig._bootstrap.call(this, document, fragmentContext); + + Mixin.install(this.tokenizer, ErrorReportingTokenizerMixin, mxn.opts); + Mixin.install(this.tokenizer, LocationInfoTokenizerMixin); + }, + + _processInputToken(token) { + mxn.ctLoc = token.location; + + orig._processInputToken.call(this, token); + }, + + _err(code, options) { + mxn.locBeforeToken = options && options.beforeToken; + mxn._reportError(code); + } + }; + } +} + +module.exports = ErrorReportingParserMixin; diff --git a/alarm/node_modules/parse5/lib/extensions/error-reporting/preprocessor-mixin.js b/alarm/node_modules/parse5/lib/extensions/error-reporting/preprocessor-mixin.js new file mode 100644 index 0000000..398c966 --- /dev/null +++ b/alarm/node_modules/parse5/lib/extensions/error-reporting/preprocessor-mixin.js @@ -0,0 +1,24 @@ +'use strict'; + +const ErrorReportingMixinBase = require('./mixin-base'); +const PositionTrackingPreprocessorMixin = require('../position-tracking/preprocessor-mixin'); +const Mixin = require('../../utils/mixin'); + +class ErrorReportingPreprocessorMixin extends ErrorReportingMixinBase { + constructor(preprocessor, opts) { + super(preprocessor, opts); + + this.posTracker = Mixin.install(preprocessor, PositionTrackingPreprocessorMixin); + this.lastErrOffset = -1; + } + + _reportError(code) { + //NOTE: avoid reporting error twice on advance/retreat + if (this.lastErrOffset !== this.posTracker.offset) { + this.lastErrOffset = this.posTracker.offset; + super._reportError(code); + } + } +} + +module.exports = ErrorReportingPreprocessorMixin; diff --git a/alarm/node_modules/parse5/lib/extensions/error-reporting/tokenizer-mixin.js b/alarm/node_modules/parse5/lib/extensions/error-reporting/tokenizer-mixin.js new file mode 100644 index 0000000..219fcab --- /dev/null +++ b/alarm/node_modules/parse5/lib/extensions/error-reporting/tokenizer-mixin.js @@ -0,0 +1,17 @@ +'use strict'; + +const ErrorReportingMixinBase = require('./mixin-base'); +const ErrorReportingPreprocessorMixin = require('./preprocessor-mixin'); +const Mixin = require('../../utils/mixin'); + +class ErrorReportingTokenizerMixin extends ErrorReportingMixinBase { + constructor(tokenizer, opts) { + super(tokenizer, opts); + + const preprocessorMixin = Mixin.install(tokenizer.preprocessor, ErrorReportingPreprocessorMixin, opts); + + this.posTracker = preprocessorMixin.posTracker; + } +} + +module.exports = ErrorReportingTokenizerMixin; diff --git a/alarm/node_modules/parse5/lib/extensions/location-info/open-element-stack-mixin.js b/alarm/node_modules/parse5/lib/extensions/location-info/open-element-stack-mixin.js new file mode 100644 index 0000000..765fe77 --- /dev/null +++ b/alarm/node_modules/parse5/lib/extensions/location-info/open-element-stack-mixin.js @@ -0,0 +1,35 @@ +'use strict'; + +const Mixin = require('../../utils/mixin'); + +class LocationInfoOpenElementStackMixin extends Mixin { + constructor(stack, opts) { + super(stack); + + this.onItemPop = opts.onItemPop; + } + + _getOverriddenMethods(mxn, orig) { + return { + pop() { + mxn.onItemPop(this.current); + orig.pop.call(this); + }, + + popAllUpToHtmlElement() { + for (let i = this.stackTop; i > 0; i--) { + mxn.onItemPop(this.items[i]); + } + + orig.popAllUpToHtmlElement.call(this); + }, + + remove(element) { + mxn.onItemPop(this.current); + orig.remove.call(this, element); + } + }; + } +} + +module.exports = LocationInfoOpenElementStackMixin; diff --git a/alarm/node_modules/parse5/lib/extensions/location-info/parser-mixin.js b/alarm/node_modules/parse5/lib/extensions/location-info/parser-mixin.js new file mode 100644 index 0000000..e7d3e2d --- /dev/null +++ b/alarm/node_modules/parse5/lib/extensions/location-info/parser-mixin.js @@ -0,0 +1,223 @@ +'use strict'; + +const Mixin = require('../../utils/mixin'); +const Tokenizer = require('../../tokenizer'); +const LocationInfoTokenizerMixin = require('./tokenizer-mixin'); +const LocationInfoOpenElementStackMixin = require('./open-element-stack-mixin'); +const HTML = require('../../common/html'); + +//Aliases +const $ = HTML.TAG_NAMES; + +class LocationInfoParserMixin extends Mixin { + constructor(parser) { + super(parser); + + this.parser = parser; + this.treeAdapter = this.parser.treeAdapter; + this.posTracker = null; + this.lastStartTagToken = null; + this.lastFosterParentingLocation = null; + this.currentToken = null; + } + + _setStartLocation(element) { + let loc = null; + + if (this.lastStartTagToken) { + loc = Object.assign({}, this.lastStartTagToken.location); + loc.startTag = this.lastStartTagToken.location; + } + + this.treeAdapter.setNodeSourceCodeLocation(element, loc); + } + + _setEndLocation(element, closingToken) { + const loc = this.treeAdapter.getNodeSourceCodeLocation(element); + + if (loc) { + if (closingToken.location) { + const ctLoc = closingToken.location; + const tn = this.treeAdapter.getTagName(element); + + // NOTE: For cases like <p> <p> </p> - First 'p' closes without a closing + // tag and for cases like <td> <p> </td> - 'p' closes without a closing tag. + const isClosingEndTag = closingToken.type === Tokenizer.END_TAG_TOKEN && tn === closingToken.tagName; + const endLoc = {}; + if (isClosingEndTag) { + endLoc.endTag = Object.assign({}, ctLoc); + endLoc.endLine = ctLoc.endLine; + endLoc.endCol = ctLoc.endCol; + endLoc.endOffset = ctLoc.endOffset; + } else { + endLoc.endLine = ctLoc.startLine; + endLoc.endCol = ctLoc.startCol; + endLoc.endOffset = ctLoc.startOffset; + } + + this.treeAdapter.updateNodeSourceCodeLocation(element, endLoc); + } + } + } + + _getOverriddenMethods(mxn, orig) { + return { + _bootstrap(document, fragmentContext) { + orig._bootstrap.call(this, document, fragmentContext); + + mxn.lastStartTagToken = null; + mxn.lastFosterParentingLocation = null; + mxn.currentToken = null; + + const tokenizerMixin = Mixin.install(this.tokenizer, LocationInfoTokenizerMixin); + + mxn.posTracker = tokenizerMixin.posTracker; + + Mixin.install(this.openElements, LocationInfoOpenElementStackMixin, { + onItemPop: function(element) { + mxn._setEndLocation(element, mxn.currentToken); + } + }); + }, + + _runParsingLoop(scriptHandler) { + orig._runParsingLoop.call(this, scriptHandler); + + // NOTE: generate location info for elements + // that remains on open element stack + for (let i = this.openElements.stackTop; i >= 0; i--) { + mxn._setEndLocation(this.openElements.items[i], mxn.currentToken); + } + }, + + //Token processing + _processTokenInForeignContent(token) { + mxn.currentToken = token; + orig._processTokenInForeignContent.call(this, token); + }, + + _processToken(token) { + mxn.currentToken = token; + orig._processToken.call(this, token); + + //NOTE: <body> and <html> are never popped from the stack, so we need to updated + //their end location explicitly. + const requireExplicitUpdate = + token.type === Tokenizer.END_TAG_TOKEN && + (token.tagName === $.HTML || (token.tagName === $.BODY && this.openElements.hasInScope($.BODY))); + + if (requireExplicitUpdate) { + for (let i = this.openElements.stackTop; i >= 0; i--) { + const element = this.openElements.items[i]; + + if (this.treeAdapter.getTagName(element) === token.tagName) { + mxn._setEndLocation(element, token); + break; + } + } + } + }, + + //Doctype + _setDocumentType(token) { + orig._setDocumentType.call(this, token); + + const documentChildren = this.treeAdapter.getChildNodes(this.document); + const cnLength = documentChildren.length; + + for (let i = 0; i < cnLength; i++) { + const node = documentChildren[i]; + + if (this.treeAdapter.isDocumentTypeNode(node)) { + this.treeAdapter.setNodeSourceCodeLocation(node, token.location); + break; + } + } + }, + + //Elements + _attachElementToTree(element) { + //NOTE: _attachElementToTree is called from _appendElement, _insertElement and _insertTemplate methods. + //So we will use token location stored in this methods for the element. + mxn._setStartLocation(element); + mxn.lastStartTagToken = null; + orig._attachElementToTree.call(this, element); + }, + + _appendElement(token, namespaceURI) { + mxn.lastStartTagToken = token; + orig._appendElement.call(this, token, namespaceURI); + }, + + _insertElement(token, namespaceURI) { + mxn.lastStartTagToken = token; + orig._insertElement.call(this, token, namespaceURI); + }, + + _insertTemplate(token) { + mxn.lastStartTagToken = token; + orig._insertTemplate.call(this, token); + + const tmplContent = this.treeAdapter.getTemplateContent(this.openElements.current); + + this.treeAdapter.setNodeSourceCodeLocation(tmplContent, null); + }, + + _insertFakeRootElement() { + orig._insertFakeRootElement.call(this); + this.treeAdapter.setNodeSourceCodeLocation(this.openElements.current, null); + }, + + //Comments + _appendCommentNode(token, parent) { + orig._appendCommentNode.call(this, token, parent); + + const children = this.treeAdapter.getChildNodes(parent); + const commentNode = children[children.length - 1]; + + this.treeAdapter.setNodeSourceCodeLocation(commentNode, token.location); + }, + + //Text + _findFosterParentingLocation() { + //NOTE: store last foster parenting location, so we will be able to find inserted text + //in case of foster parenting + mxn.lastFosterParentingLocation = orig._findFosterParentingLocation.call(this); + + return mxn.lastFosterParentingLocation; + }, + + _insertCharacters(token) { + orig._insertCharacters.call(this, token); + + const hasFosterParent = this._shouldFosterParentOnInsertion(); + + const parent = + (hasFosterParent && mxn.lastFosterParentingLocation.parent) || + this.openElements.currentTmplContent || + this.openElements.current; + + const siblings = this.treeAdapter.getChildNodes(parent); + + const textNodeIdx = + hasFosterParent && mxn.lastFosterParentingLocation.beforeElement + ? siblings.indexOf(mxn.lastFosterParentingLocation.beforeElement) - 1 + : siblings.length - 1; + + const textNode = siblings[textNodeIdx]; + + //NOTE: if we have location assigned by another token, then just update end position + const tnLoc = this.treeAdapter.getNodeSourceCodeLocation(textNode); + + if (tnLoc) { + const { endLine, endCol, endOffset } = token.location; + this.treeAdapter.updateNodeSourceCodeLocation(textNode, { endLine, endCol, endOffset }); + } else { + this.treeAdapter.setNodeSourceCodeLocation(textNode, token.location); + } + } + }; + } +} + +module.exports = LocationInfoParserMixin; diff --git a/alarm/node_modules/parse5/lib/extensions/location-info/tokenizer-mixin.js b/alarm/node_modules/parse5/lib/extensions/location-info/tokenizer-mixin.js new file mode 100644 index 0000000..3c1ef5f --- /dev/null +++ b/alarm/node_modules/parse5/lib/extensions/location-info/tokenizer-mixin.js @@ -0,0 +1,146 @@ +'use strict'; + +const Mixin = require('../../utils/mixin'); +const Tokenizer = require('../../tokenizer'); +const PositionTrackingPreprocessorMixin = require('../position-tracking/preprocessor-mixin'); + +class LocationInfoTokenizerMixin extends Mixin { + constructor(tokenizer) { + super(tokenizer); + + this.tokenizer = tokenizer; + this.posTracker = Mixin.install(tokenizer.preprocessor, PositionTrackingPreprocessorMixin); + this.currentAttrLocation = null; + this.ctLoc = null; + } + + _getCurrentLocation() { + return { + startLine: this.posTracker.line, + startCol: this.posTracker.col, + startOffset: this.posTracker.offset, + endLine: -1, + endCol: -1, + endOffset: -1 + }; + } + + _attachCurrentAttrLocationInfo() { + this.currentAttrLocation.endLine = this.posTracker.line; + this.currentAttrLocation.endCol = this.posTracker.col; + this.currentAttrLocation.endOffset = this.posTracker.offset; + + const currentToken = this.tokenizer.currentToken; + const currentAttr = this.tokenizer.currentAttr; + + if (!currentToken.location.attrs) { + currentToken.location.attrs = Object.create(null); + } + + currentToken.location.attrs[currentAttr.name] = this.currentAttrLocation; + } + + _getOverriddenMethods(mxn, orig) { + const methods = { + _createStartTagToken() { + orig._createStartTagToken.call(this); + this.currentToken.location = mxn.ctLoc; + }, + + _createEndTagToken() { + orig._createEndTagToken.call(this); + this.currentToken.location = mxn.ctLoc; + }, + + _createCommentToken() { + orig._createCommentToken.call(this); + this.currentToken.location = mxn.ctLoc; + }, + + _createDoctypeToken(initialName) { + orig._createDoctypeToken.call(this, initialName); + this.currentToken.location = mxn.ctLoc; + }, + + _createCharacterToken(type, ch) { + orig._createCharacterToken.call(this, type, ch); + this.currentCharacterToken.location = mxn.ctLoc; + }, + + _createEOFToken() { + orig._createEOFToken.call(this); + this.currentToken.location = mxn._getCurrentLocation(); + }, + + _createAttr(attrNameFirstCh) { + orig._createAttr.call(this, attrNameFirstCh); + mxn.currentAttrLocation = mxn._getCurrentLocation(); + }, + + _leaveAttrName(toState) { + orig._leaveAttrName.call(this, toState); + mxn._attachCurrentAttrLocationInfo(); + }, + + _leaveAttrValue(toState) { + orig._leaveAttrValue.call(this, toState); + mxn._attachCurrentAttrLocationInfo(); + }, + + _emitCurrentToken() { + const ctLoc = this.currentToken.location; + + //NOTE: if we have pending character token make it's end location equal to the + //current token's start location. + if (this.currentCharacterToken) { + this.currentCharacterToken.location.endLine = ctLoc.startLine; + this.currentCharacterToken.location.endCol = ctLoc.startCol; + this.currentCharacterToken.location.endOffset = ctLoc.startOffset; + } + + if (this.currentToken.type === Tokenizer.EOF_TOKEN) { + ctLoc.endLine = ctLoc.startLine; + ctLoc.endCol = ctLoc.startCol; + ctLoc.endOffset = ctLoc.startOffset; + } else { + ctLoc.endLine = mxn.posTracker.line; + ctLoc.endCol = mxn.posTracker.col + 1; + ctLoc.endOffset = mxn.posTracker.offset + 1; + } + + orig._emitCurrentToken.call(this); + }, + + _emitCurrentCharacterToken() { + const ctLoc = this.currentCharacterToken && this.currentCharacterToken.location; + + //NOTE: if we have character token and it's location wasn't set in the _emitCurrentToken(), + //then set it's location at the current preprocessor position. + //We don't need to increment preprocessor position, since character token + //emission is always forced by the start of the next character token here. + //So, we already have advanced position. + if (ctLoc && ctLoc.endOffset === -1) { + ctLoc.endLine = mxn.posTracker.line; + ctLoc.endCol = mxn.posTracker.col; + ctLoc.endOffset = mxn.posTracker.offset; + } + + orig._emitCurrentCharacterToken.call(this); + } + }; + + //NOTE: patch initial states for each mode to obtain token start position + Object.keys(Tokenizer.MODE).forEach(modeName => { + const state = Tokenizer.MODE[modeName]; + + methods[state] = function(cp) { + mxn.ctLoc = mxn._getCurrentLocation(); + orig[state].call(this, cp); + }; + }); + + return methods; + } +} + +module.exports = LocationInfoTokenizerMixin; diff --git a/alarm/node_modules/parse5/lib/extensions/position-tracking/preprocessor-mixin.js b/alarm/node_modules/parse5/lib/extensions/position-tracking/preprocessor-mixin.js new file mode 100644 index 0000000..3a07d78 --- /dev/null +++ b/alarm/node_modules/parse5/lib/extensions/position-tracking/preprocessor-mixin.js @@ -0,0 +1,64 @@ +'use strict'; + +const Mixin = require('../../utils/mixin'); + +class PositionTrackingPreprocessorMixin extends Mixin { + constructor(preprocessor) { + super(preprocessor); + + this.preprocessor = preprocessor; + this.isEol = false; + this.lineStartPos = 0; + this.droppedBufferSize = 0; + + this.offset = 0; + this.col = 0; + this.line = 1; + } + + _getOverriddenMethods(mxn, orig) { + return { + advance() { + const pos = this.pos + 1; + const ch = this.html[pos]; + + //NOTE: LF should be in the last column of the line + if (mxn.isEol) { + mxn.isEol = false; + mxn.line++; + mxn.lineStartPos = pos; + } + + if (ch === '\n' || (ch === '\r' && this.html[pos + 1] !== '\n')) { + mxn.isEol = true; + } + + mxn.col = pos - mxn.lineStartPos + 1; + mxn.offset = mxn.droppedBufferSize + pos; + + return orig.advance.call(this); + }, + + retreat() { + orig.retreat.call(this); + + mxn.isEol = false; + mxn.col = this.pos - mxn.lineStartPos + 1; + }, + + dropParsedChunk() { + const prevPos = this.pos; + + orig.dropParsedChunk.call(this); + + const reduction = prevPos - this.pos; + + mxn.lineStartPos -= reduction; + mxn.droppedBufferSize += reduction; + mxn.offset = mxn.droppedBufferSize + this.pos; + } + }; + } +} + +module.exports = PositionTrackingPreprocessorMixin; |