TeemuKoivisto / prosemirror-dev-toolkit

Injectable developer tools for ProseMirror rich-text editors implemented in Svelte and TypeScript.
https://teemukoivisto.github.io/prosemirror-dev-toolkit/
MIT License
115 stars 6 forks source link

Skips iframes: .ProseMirror not found #44

Closed kapouer closed 1 year ago

kapouer commented 1 year ago

I'm loading prosemirror inside an iframe (to the same domain). Like this: image

The dev-toolkit chrome extension doesn't find it. Thanks for this wonderful tool.

TeemuKoivisto commented 1 year ago

Hey, thanks! I'll look into it

TeemuKoivisto commented 1 year ago

Hey, yeah it's doable. Just kinda messy. I'll try to get the next version deployed and live soon, so you can triage

kapouer commented 1 year ago

Unfortunately #48 still fails to detect it.

document.querySelectorAll('iframe')[0].contentDocument.querySelector('.ProseMirror')

returns the body in the screenshot, though.

TeemuKoivisto commented 1 year ago

Well that's a bummer. Is the site public so I can check it myself? Otherwise, I'll test it again and try to fix it but can't ensure the results

kapouer commented 1 year ago

I'll try to setup a demo

kapouer commented 1 year ago

I don't understand how to debug the code in inject.js

TeemuKoivisto commented 1 year ago

Inject.js? Well, it's quite complicated. If there's no error shown, the bundle is loaded but still nothing shows the injection has probably flaked. Typing into the editor might help but other than that, it's pretty hard. Can you use the unpacked extension instead?

TeemuKoivisto commented 1 year ago

Or well not sure how you're making the demo. Simple github.io site with iframe would probably be the best, if possible. No need to add dev-tools by hand, I can test it with the extension

kapouer commented 1 year ago

Yes, that's what i do. I suppose I need to add a debugger; statement somewhere in inject.js ?

TeemuKoivisto commented 1 year ago

You can add a debugger inside the new Promise to see whether it's actually being called. Do note thought that using inject.js to inject the dev-tools into an iframe wont work since it uses the local document object. You have to edit the querySelector logic a bit to do that.

kapouer commented 1 year ago

i'm seeing this Capture d’écran du 2023-02-21 23-33-56

getEditorView receives the body.ProseMirror node, however I suppose the detection is somehow assuming something that isn't there. el.pmViewDesc is not null, though.

kapouer commented 1 year ago

Hmm I see the hack :) Not easy to get prosemirror view.

TeemuKoivisto commented 1 year ago

Hard to say without being able to debug it myself. If the promise is never called and thus the whole function is left pending, even with user input to ProseMirror to flush the DOM, the EditorView instance just contains something unexpected. In some cases where I've had problems with it the schema was somewhat weird or there was some quirky props, like editable: false being passed.

TeemuKoivisto commented 1 year ago

@kapouer is this still a problem with the latest version?

kapouer commented 1 year ago

The last published version is 1.0.9, and that one is still failing to find body.ProseMirror in an iframe.

kapouer commented 1 year ago

I am trying from source 1.1.5

kapouer commented 1 year ago

Failing too, though it seems there is an issue when building from source.

TeemuKoivisto commented 1 year ago

Really? It works for TipTap iframes https://tiptap.dev/editor so there definitely is something different in the way you use them. If you can pinpoint the reason I can try out a solution but without that there isn't much I can do for now

kapouer commented 1 year ago

This condition still retries even when document is complete: https://github.com/TeemuKoivisto/prosemirror-dev-toolkit/blob/cd6d0e8641835c48e67dc601b21744523bac1261/packages/extension/src/inject/utils.ts#L22

TeemuKoivisto commented 1 year ago

Can you log this error:

  } catch (err) {
    // Probably "Blocked a frame with origin from accessing a cross-origin frame." error
    return []
  }

if that's the one that keeps throwing

kapouer commented 1 year ago

Actually it works ! It detects correctly the iframe. However it fails a bit after with this rejection:

setTimeout(() => {
      rej("Unable to trigger childWithSelectNode.pmViewDesc.selectNode");
    }, 1e3);
TeemuKoivisto commented 1 year ago

Oh that one. Well, it's a tricky heuristic to adjust. In most cases increasing the timeout doesn't help. Try increasing it to say 5 or 10 seconds if it helps. It has something to do with the editor being active as I recall cases where the original 1ms kept failing and why I increased it to 1s.

kapouer commented 1 year ago

It actually works, not right away, but several seconds after interacting with the editor. Considering it to be nice enough :)

TeemuKoivisto commented 1 year ago

Hey that's good to hear! Yeah wish it worked a little smoother but glad this was resolved