zerodevx / zero-md

Ridiculously simple zero-config markdown displayer
https://zerodevx.github.io/zero-md/
ISC License
423 stars 48 forks source link

BUG: `goto` (scroll to selected element) broken when `no-shadow` enabled #82

Closed alifeee closed 1 year ago

alifeee commented 1 year ago

Working example:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script
      type="module"
      src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@2/dist/zero-md.min.js"
    ></script>
  </head>

  <body>
    <zero-md
      src="https://raw.githubusercontent.com/zerodevx/zero-md/master/README.md"
    ></zero-md>
  </body>
</html>

Broken example

The difference is that no-shadow is provided to the <zero-md> element.

<!DOCTYPE html>
<html lang="en">
  <head>
    <script
      type="module"
      src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@2/dist/zero-md.min.js"
    ></script>
  </head>

  <body>
    <zero-md
      src="https://raw.githubusercontent.com/zerodevx/zero-md/master/README.md"
      no-shadow
    ></zero-md>
  </body>
</html>

Expected behaviour:

go to https://URL#basic-usage. Page should scroll to that heading.

Actual behaviour

console error:

Uncaught TypeError: this.root.getElementById is not a function
    goto index.js:153
    t index.js:66
    setTimeout handler*t/< index.js:66
    promise callback*t index.js:66
    <anonymous> index.js:330
index.js:153:27

Environment

I am using Firefox.

Code

The problem is with the goto function.

https://github.com/zerodevx/zero-md/blob/5a627f2a8f605efbc108ba7f3866eb910de9cf20/src/index.js#L151-L158

this.root does not have getElementById if no-shadow is true. this.root is set in the constructor() function:

https://github.com/zerodevx/zero-md/blob/5a627f2a8f605efbc108ba7f3866eb910de9cf20/src/index.js#L55

The issue appears to be because getElementById is only defined on the document object. See MDN web docs.

zerodevx commented 1 year ago

@alifeee Hi! I just saw your sponsorship - much appreciated, thank you! 🙏

A bit of background regarding this issue - native browser behaviour performs page scroll to an element id in 2 areas:

This however doesn't work in the context of a custom element, hence the need to shim it (with the goto() function) in this project.

Nice catch that this doesn't work when no-shadow is used. Originally, no-shadow is a bit "experimental" - most of the time <zero-md> is intended to work within its own sandbox (the shadow dom). It's a simple enough fix I think. I'll add comments to your PR and see if we can take it from there.

Thanks once again!

alifeee commented 1 year ago

You have made a good library! It aligns to my opinions regarding simplicity and web content well.

You may see by my other issue (#84) why I am using no-shadow. I would like to use the shadow DOM, but it seems libraries like Mermaid/AnchorJS just don't work with it, currently. I would prefer to use the shadow DOM, it is a nice concept and I like it.

Thanks for the quick comment. :)