Skip to content

DOM elements in iframe portal are instantiated from top Window.Node instead of the iframe Window.Node #2358

@bmingles

Description

@bmingles

Describe the bug

I'm trying to render SolidJS components inside of an iframe using a Portal. The rendering works, but it seems the DOM elements get created from the parent document instead of the iframe document.

import { createSignal, Show, type Component } from 'solid-js';

import styles from './App.module.css';
import { Portal } from 'solid-js/web';

const IFrame = () => {
  // Track the iframe contentDocument
  const [iframeDocument, setIframeDocument] = createSignal<Document | null>(
    null
  );

  // Signal to track results
  const [stats, setStats] = createSignal<{
    fromTop?: boolean;
    fromiFrame?: boolean;
  }>({});

  // Track the iframe contentDocument in a signal once it has loaded
  const onLoad = (e: Event) => {
    const { contentDocument } = e.target as HTMLIFrameElement;
    setIframeDocument(contentDocument);
  };

  const divRef = (ref: HTMLDivElement) => {
    setStats({
      // I don't want this to be true
      fromTop: ref instanceof window.Node,
      // I want this to be true
      fromiFrame: ref instanceof iframeDocument()!.defaultView!.Node,
    });
  };

  return (
    <iframe srcdoc={`<!DOCTYPE html>`} onLoad={onLoad}>
      <Show when={iframeDocument()?.body}>
        <Portal mount={iframeDocument()?.body}>
          <div ref={divRef}>
            This div is inside an iframe. I want the DOM element to be
            instanticated from the iframe document, but it seems to be
            instantiated from the parent document.
          </div>
          <br />
          <div>
            Instantiated from parent: {String(stats().fromTop)}
            <br />
            Instantiated from iframe: {String(stats().fromiFrame)}
          </div>
        </Portal>
      </Show>
    </iframe>
  );
};

const App: Component = () => {
  return (
    <div class={styles.App}>
      <IFrame />
    </div>
  );
};

export default App;

Your Example Website or App

https://stackblitz.com/edit/solidjs-iframe-issue?file=src%2FApp.tsx

Steps to Reproduce the Bug or Issue

Render an iframe with children in a Portal. Inspect any children rendered in the Portal. They are instances of window.Node instead of contentDocument.defaultView.Node

Expected behavior

I would expect there to be a way to render child elements in an iframe that would use the contentDocument for creating DOM elements.

Platform

  • OS: MacOS
  • Browser: Chrome
  • Version: 1.7.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions