fix: Resolve replaceChild and activeElement errors in FolkJS components
- Fix activeElement undefined error by guarding against missing shadowRoot - Fix replaceChild "parameter 2 is not of type Node" error in all 15 child components by using :scope > div selector to find container div directly instead of incorrectly searching inside slot.parentElement The bug was caused by looking for a nested div that doesn't exist - the slot's parent IS the container div that needs to be replaced. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
8eef5b58b7
commit
42b29ff9d7
|
|
@ -269,13 +269,10 @@ export class FolkCalendar extends FolkShape {
|
|||
</div>
|
||||
`;
|
||||
|
||||
const slot = root.querySelector("slot");
|
||||
if (slot?.parentElement) {
|
||||
const parent = slot.parentElement;
|
||||
const existingDiv = parent.querySelector("div");
|
||||
if (existingDiv) {
|
||||
parent.replaceChild(wrapper, existingDiv);
|
||||
}
|
||||
// Replace the container div (slot's parent) with our wrapper
|
||||
const containerDiv = root.querySelector(":scope > div");
|
||||
if (containerDiv) {
|
||||
containerDiv.replaceWith(wrapper);
|
||||
}
|
||||
|
||||
// Get element references
|
||||
|
|
|
|||
|
|
@ -238,13 +238,10 @@ export class FolkChat extends FolkShape {
|
|||
</div>
|
||||
`;
|
||||
|
||||
const slot = root.querySelector("slot");
|
||||
if (slot?.parentElement) {
|
||||
const parent = slot.parentElement;
|
||||
const existingDiv = parent.querySelector("div");
|
||||
if (existingDiv) {
|
||||
parent.replaceChild(wrapper, existingDiv);
|
||||
}
|
||||
// Replace the container div (slot's parent) with our wrapper
|
||||
const containerDiv = root.querySelector(":scope > div");
|
||||
if (containerDiv) {
|
||||
containerDiv.replaceWith(wrapper);
|
||||
}
|
||||
|
||||
// Get element references
|
||||
|
|
|
|||
|
|
@ -258,13 +258,10 @@ export class FolkEmbed extends FolkShape {
|
|||
</div>
|
||||
`;
|
||||
|
||||
const slot = root.querySelector("slot");
|
||||
if (slot?.parentElement) {
|
||||
const parent = slot.parentElement;
|
||||
const existingDiv = parent.querySelector("div");
|
||||
if (existingDiv) {
|
||||
parent.replaceChild(wrapper, existingDiv);
|
||||
}
|
||||
// Replace the container div (slot's parent) with our wrapper
|
||||
const containerDiv = root.querySelector(":scope > div");
|
||||
if (containerDiv) {
|
||||
containerDiv.replaceWith(wrapper);
|
||||
}
|
||||
|
||||
const content = wrapper.querySelector(".content") as HTMLElement;
|
||||
|
|
|
|||
|
|
@ -229,13 +229,11 @@ export class FolkGoogleItem extends FolkShape {
|
|||
</div>
|
||||
`;
|
||||
|
||||
const slot = root.querySelector("slot");
|
||||
if (slot?.parentElement) {
|
||||
const parent = slot.parentElement;
|
||||
const existingDiv = parent.querySelector("div");
|
||||
if (existingDiv) {
|
||||
parent.replaceChild(wrapper.querySelector(".card")!, existingDiv);
|
||||
}
|
||||
// Replace the container div (slot's parent) with our card
|
||||
const containerDiv = root.querySelector(":scope > div");
|
||||
const cardEl = wrapper.querySelector(".card");
|
||||
if (containerDiv && cardEl) {
|
||||
containerDiv.replaceWith(cardEl);
|
||||
}
|
||||
|
||||
// Toggle visibility on badge click
|
||||
|
|
|
|||
|
|
@ -264,13 +264,10 @@ export class FolkImageGen extends FolkShape {
|
|||
</div>
|
||||
`;
|
||||
|
||||
const slot = root.querySelector("slot");
|
||||
if (slot?.parentElement) {
|
||||
const parent = slot.parentElement;
|
||||
const existingDiv = parent.querySelector("div");
|
||||
if (existingDiv) {
|
||||
parent.replaceChild(wrapper, existingDiv);
|
||||
}
|
||||
// Replace the container div (slot's parent) with our wrapper
|
||||
const containerDiv = root.querySelector(":scope > div");
|
||||
if (containerDiv) {
|
||||
containerDiv.replaceWith(wrapper);
|
||||
}
|
||||
|
||||
this.#promptInput = wrapper.querySelector(".prompt-input");
|
||||
|
|
|
|||
|
|
@ -308,13 +308,10 @@ export class FolkMap extends FolkShape {
|
|||
</div>
|
||||
`;
|
||||
|
||||
const slot = root.querySelector("slot");
|
||||
if (slot?.parentElement) {
|
||||
const parent = slot.parentElement;
|
||||
const existingDiv = parent.querySelector("div");
|
||||
if (existingDiv) {
|
||||
parent.replaceChild(wrapper, existingDiv);
|
||||
}
|
||||
// Replace the container div (slot's parent) with our wrapper
|
||||
const containerDiv = root.querySelector(":scope > div");
|
||||
if (containerDiv) {
|
||||
containerDiv.replaceWith(wrapper);
|
||||
}
|
||||
|
||||
this.#mapEl = wrapper.querySelector(".map");
|
||||
|
|
|
|||
|
|
@ -173,10 +173,10 @@ export class FolkMarkdown extends FolkShape {
|
|||
</div>
|
||||
`;
|
||||
|
||||
// Move existing slot content into our wrapper
|
||||
const slot = root.querySelector("slot");
|
||||
if (slot) {
|
||||
slot.parentElement?.replaceChild(wrapper, slot.parentElement.querySelector("div")!);
|
||||
// Replace the container div (slot's parent) with our wrapper
|
||||
const containerDiv = root.querySelector(":scope > div");
|
||||
if (containerDiv) {
|
||||
containerDiv.replaceWith(wrapper);
|
||||
}
|
||||
|
||||
// Get references to elements
|
||||
|
|
|
|||
|
|
@ -366,13 +366,10 @@ export class FolkObsNote extends FolkShape {
|
|||
</div>
|
||||
`;
|
||||
|
||||
const slot = root.querySelector("slot");
|
||||
if (slot?.parentElement) {
|
||||
const parent = slot.parentElement;
|
||||
const existingDiv = parent.querySelector("div");
|
||||
if (existingDiv) {
|
||||
parent.replaceChild(wrapper, existingDiv);
|
||||
}
|
||||
// Replace the container div (slot's parent) with our wrapper
|
||||
const containerDiv = root.querySelector(":scope > div");
|
||||
if (containerDiv) {
|
||||
containerDiv.replaceWith(wrapper);
|
||||
}
|
||||
|
||||
this.#editor = wrapper.querySelector(".editor");
|
||||
|
|
|
|||
|
|
@ -195,13 +195,11 @@ export class FolkPiano extends FolkShape {
|
|||
</div>
|
||||
`;
|
||||
|
||||
const slot = root.querySelector("slot");
|
||||
if (slot?.parentElement) {
|
||||
const parent = slot.parentElement;
|
||||
const existingDiv = parent.querySelector("div");
|
||||
if (existingDiv) {
|
||||
parent.replaceChild(wrapper.querySelector(".piano-container")!, existingDiv);
|
||||
}
|
||||
// Replace the container div (slot's parent) with our piano container
|
||||
const containerDiv = root.querySelector(":scope > div");
|
||||
const pianoContainer = wrapper.querySelector(".piano-container");
|
||||
if (containerDiv && pianoContainer) {
|
||||
containerDiv.replaceWith(pianoContainer);
|
||||
}
|
||||
|
||||
// Get references
|
||||
|
|
|
|||
|
|
@ -293,13 +293,10 @@ export class FolkPrompt extends FolkShape {
|
|||
</div>
|
||||
`;
|
||||
|
||||
const slot = root.querySelector("slot");
|
||||
if (slot?.parentElement) {
|
||||
const parent = slot.parentElement;
|
||||
const existingDiv = parent.querySelector("div");
|
||||
if (existingDiv) {
|
||||
parent.replaceChild(wrapper, existingDiv);
|
||||
}
|
||||
// Replace the container div (slot's parent) with our wrapper
|
||||
const containerDiv = root.querySelector(":scope > div");
|
||||
if (containerDiv) {
|
||||
containerDiv.replaceWith(wrapper);
|
||||
}
|
||||
|
||||
this.#messagesEl = wrapper.querySelector(".messages");
|
||||
|
|
|
|||
|
|
@ -356,7 +356,9 @@ export class FolkShape extends FolkElement {
|
|||
return;
|
||||
}
|
||||
|
||||
const focusedElement = (this.renderRoot as ShadowRoot).activeElement as HTMLElement | null;
|
||||
const shadowRoot = this.renderRoot as ShadowRoot | undefined;
|
||||
if (!shadowRoot) return;
|
||||
const focusedElement = shadowRoot.activeElement as HTMLElement | null;
|
||||
const target = event.composedPath()[0] as HTMLElement;
|
||||
let handle: Handle | null = null;
|
||||
if (target) {
|
||||
|
|
|
|||
|
|
@ -88,12 +88,11 @@ export class FolkSlide extends FolkShape {
|
|||
</div>
|
||||
`;
|
||||
|
||||
const slot = root.querySelector("slot");
|
||||
if (slot?.parentElement) {
|
||||
slot.parentElement.replaceChild(
|
||||
wrapper.querySelector(".slide-container")!,
|
||||
slot.parentElement.querySelector("div")!
|
||||
);
|
||||
// Replace the container div (slot's parent) with our slide container
|
||||
const containerDiv = root.querySelector(":scope > div");
|
||||
const slideContainer = wrapper.querySelector(".slide-container");
|
||||
if (containerDiv && slideContainer) {
|
||||
containerDiv.replaceWith(slideContainer);
|
||||
}
|
||||
|
||||
// Update label from attribute
|
||||
|
|
|
|||
|
|
@ -349,13 +349,10 @@ export class FolkTranscription extends FolkShape {
|
|||
</div>
|
||||
`;
|
||||
|
||||
const slot = root.querySelector("slot");
|
||||
if (slot?.parentElement) {
|
||||
const parent = slot.parentElement;
|
||||
const existingDiv = parent.querySelector("div");
|
||||
if (existingDiv) {
|
||||
parent.replaceChild(wrapper, existingDiv);
|
||||
}
|
||||
// Replace the container div (slot's parent) with our wrapper
|
||||
const containerDiv = root.querySelector(":scope > div");
|
||||
if (containerDiv) {
|
||||
containerDiv.replaceWith(wrapper);
|
||||
}
|
||||
|
||||
this.#recordBtn = wrapper.querySelector(".record-btn");
|
||||
|
|
|
|||
|
|
@ -325,13 +325,10 @@ export class FolkVideoChat extends FolkShape {
|
|||
</div>
|
||||
`;
|
||||
|
||||
const slot = root.querySelector("slot");
|
||||
if (slot?.parentElement) {
|
||||
const parent = slot.parentElement;
|
||||
const existingDiv = parent.querySelector("div");
|
||||
if (existingDiv) {
|
||||
parent.replaceChild(wrapper, existingDiv);
|
||||
}
|
||||
// Replace the container div (slot's parent) with our wrapper
|
||||
const containerDiv = root.querySelector(":scope > div");
|
||||
if (containerDiv) {
|
||||
containerDiv.replaceWith(wrapper);
|
||||
}
|
||||
|
||||
const content = wrapper.querySelector(".content") as HTMLElement;
|
||||
|
|
|
|||
|
|
@ -359,13 +359,10 @@ export class FolkVideoGen extends FolkShape {
|
|||
</div>
|
||||
`;
|
||||
|
||||
const slot = root.querySelector("slot");
|
||||
if (slot?.parentElement) {
|
||||
const parent = slot.parentElement;
|
||||
const existingDiv = parent.querySelector("div");
|
||||
if (existingDiv) {
|
||||
parent.replaceChild(wrapper, existingDiv);
|
||||
}
|
||||
// Replace the container div (slot's parent) with our wrapper
|
||||
const containerDiv = root.querySelector(":scope > div");
|
||||
if (containerDiv) {
|
||||
containerDiv.replaceWith(wrapper);
|
||||
}
|
||||
|
||||
this.#promptInput = wrapper.querySelector(".prompt-input");
|
||||
|
|
|
|||
|
|
@ -340,13 +340,10 @@ export class FolkWorkflowBlock extends FolkShape {
|
|||
</div>
|
||||
`;
|
||||
|
||||
const slot = root.querySelector("slot");
|
||||
if (slot?.parentElement) {
|
||||
const parent = slot.parentElement;
|
||||
const existingDiv = parent.querySelector("div");
|
||||
if (existingDiv) {
|
||||
parent.replaceChild(wrapper, existingDiv);
|
||||
}
|
||||
// Replace the container div (slot's parent) with our wrapper
|
||||
const containerDiv = root.querySelector(":scope > div");
|
||||
if (containerDiv) {
|
||||
containerDiv.replaceWith(wrapper);
|
||||
}
|
||||
|
||||
this.#contentEl = wrapper.querySelector(".content");
|
||||
|
|
|
|||
Loading…
Reference in New Issue