summaryrefslogtreecommitdiff
path: root/school/node_modules/parse5/lib/extensions/location-info/parser-mixin.js
diff options
context:
space:
mode:
authorMinteck <contact@minteck.org>2023-01-10 14:54:04 +0100
committerMinteck <contact@minteck.org>2023-01-10 14:54:04 +0100
commit99c1d9af689e5325f3cf535c4007b3aeb8325229 (patch)
treee663b3c2ebdbd67c818ac0c5147f0ce1d2463cda /school/node_modules/parse5/lib/extensions/location-info/parser-mixin.js
parent9871b03912fc28ad38b4037ebf26a78aa937baba (diff)
downloadpluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.tar.gz
pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.tar.bz2
pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.zip
Update - This is an automated commit
Diffstat (limited to 'school/node_modules/parse5/lib/extensions/location-info/parser-mixin.js')
-rw-r--r--school/node_modules/parse5/lib/extensions/location-info/parser-mixin.js223
1 files changed, 223 insertions, 0 deletions
diff --git a/school/node_modules/parse5/lib/extensions/location-info/parser-mixin.js b/school/node_modules/parse5/lib/extensions/location-info/parser-mixin.js
new file mode 100644
index 0000000..e7d3e2d
--- /dev/null
+++ b/school/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;