diff --git a/lib/jsdom/browser/parser/html.js b/lib/jsdom/browser/parser/html.js
index 8caf0bb4e1..10521ef42f 100644
--- a/lib/jsdom/browser/parser/html.js
+++ b/lib/jsdom/browser/parser/html.js
@@ -16,6 +16,34 @@ const OpenElementStack = require("parse5/lib/parser/open-element-stack");
const OpenElementStackOriginalPop = OpenElementStack.prototype.pop;
const OpenElementStackOriginalPush = OpenElementStack.prototype.push;
+// Horrible monkey-patch to implement https://github.com/inikulin/parse5/issues/237
+function wrapOpenElementStack(adapter) {
+ OpenElementStack.prototype.push = function (...args) {
+ OpenElementStackOriginalPush.apply(this, args);
+ adapter._currentElement = this.current;
+
+ const after = this.items[this.stackTop];
+ if (after._pushedOnStackOfOpenElements) {
+ after._pushedOnStackOfOpenElements();
+ }
+ };
+ OpenElementStack.prototype.pop = function (...args) {
+ const before = this.items[this.stackTop];
+
+ OpenElementStackOriginalPop.apply(this, args);
+ adapter._currentElement = this.current;
+
+ if (before._poppedOffStackOfOpenElements) {
+ before._poppedOffStackOfOpenElements();
+ }
+ };
+}
+
+function unwrapOpenElementStack() {
+ OpenElementStack.prototype.pop = OpenElementStackOriginalPop;
+ OpenElementStack.prototype.push = OpenElementStackOriginalPush;
+}
+
class JSDOMParse5Adapter {
constructor(documentImpl) {
this._documentImpl = documentImpl;
@@ -24,28 +52,6 @@ class JSDOMParse5Adapter {
// Since the createElement hook doesn't provide the parent element, we keep track of this using _currentElement:
// https://github.com/inikulin/parse5/issues/285
this._currentElement = undefined;
-
- // Horrible monkey-patch to implement https://github.com/inikulin/parse5/issues/237
- const adapter = this;
- OpenElementStack.prototype.push = function (...args) {
- OpenElementStackOriginalPush.apply(this, args);
- adapter._currentElement = this.current;
-
- const after = this.items[this.stackTop];
- if (after._pushedOnStackOfOpenElements) {
- after._pushedOnStackOfOpenElements();
- }
- };
- OpenElementStack.prototype.pop = function (...args) {
- const before = this.items[this.stackTop];
-
- OpenElementStackOriginalPop.apply(this, args);
- adapter._currentElement = this.current;
-
- if (before._poppedOffStackOfOpenElements) {
- before._poppedOffStackOfOpenElements();
- }
- };
}
_ownerDocument() {
@@ -165,7 +171,12 @@ function parseFragment(markup, contextElement) {
treeAdapter: new JSDOMParse5Adapter(ownerDocument)
});
- return parse5.parseFragment(contextElement, markup, config);
+ wrapOpenElementStack(config.treeAdapter);
+ try {
+ return parse5.parseFragment(contextElement, markup, config);
+ } finally {
+ unwrapOpenElementStack();
+ }
}
function parseIntoDocument(markup, ownerDocument) {
@@ -173,7 +184,12 @@ function parseIntoDocument(markup, ownerDocument) {
treeAdapter: new JSDOMParse5Adapter(ownerDocument)
});
- return parse5.parse(markup, config);
+ wrapOpenElementStack(config.treeAdapter);
+ try {
+ return parse5.parse(markup, config);
+ } finally {
+ unwrapOpenElementStack();
+ }
}
module.exports = {