Skip to content

.before is not working #1637

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
aralroca opened this issue Dec 14, 2024 · 3 comments · Fixed by #1652
Closed

.before is not working #1637

aralroca opened this issue Dec 14, 2024 · 3 comments · Fixed by #1652
Assignees
Labels
bug Something isn't working

Comments

@aralroca
Copy link
Contributor

When running the following test:

  it('should work', () => {
      GlobalRegistrator.register();
      document.body.innerHTML = '<section><form>Foo</form></section>';
      const el = document.querySelector('form')
      el.before(document.createElement('div'))
    })

I encounter this error:

11 |      *
12 |      * @param message Message.
13 |      * @param name Name.
14 |      */
15 |     constructor(message, name = null) {
16 |         super(message);
             ^
DOMException: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.

However, when running this code in a real browser environment, it works as expected. It seems that happy-DOM does not fully support Node.prototype.before() or handles the DOM differently.

@aralroca aralroca added the bug Something isn't working label Dec 14, 2024
@OlaviSau
Copy link
Contributor

It does appear to be a bug indeed caused by having the wrong parent being used. The parent should be from the element that this is being called on rather than from the child node. It seems like an easy fix. I am not really sure why the child node parent is used as that seems like it would be wrong every time.

/**
	public static before(childNode: IChildNode, ...nodes: (string | Node)[]): void {
		const parent = <IParentNode>childNode[PropertySymbol.parentNode];
		if (!parent) {
			return;
		}

		for (const node of nodes) {
			if (node instanceof Node) {
				parent.insertBefore(node, childNode);
			} else {
				parent.insertBefore(
					parent[PropertySymbol.ownerDocument].createTextNode(String(node)),
					childNode
				);
			}
		}
	}

@capricorn86 lmk if you want a pr fix for this.

@capricorn86
Copy link
Owner

Thank you for reporting @aralroca and thank you for the analysis @OlaviSau! 🙂

I have made a fix now in v16.2.5.

The reason for why it didn't work is because of the change in v15 to use a proxy for HTMLFormElement and HTMLSelectElement. In this and a couple of other methods, the reference to the parent was to the target and not the proxy, and the element could not be found.

@capricorn86
Copy link
Owner

@OlaviSau It is always nice with a contribution 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
3 participants