web-ifc-viewer: IfcViewerAPI breaks some functionality in Bootstrap5

It seems that there is something in IfcViewerAPI that breaks some of the functionality in BS5, such as dropdowns, tabs and so on.

If I remove bundle.js, which is just the file produced by rollup when I use import { IfcViewerAPI } from "web-ifc-viewer"; then the elements work as expected.

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/css/bootstrap.min.css" rel="stylesheet">
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.bundle.min.js"></script>
  <script src="bundle.js"></script>
</head>
<body>

<div class="container mt-3">
  <h2>Dropdowns</h2>
  <p>The .dropdown-divider class is used to separate links inside the dropdown menu with a thin horizontal line:</p>

  <div class="dropdown">
    <button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown">
      Dropdown button
    </button>
    <ul class="dropdown-menu">
      <li><a class="dropdown-item" href="#">Link 1</a></li>
      <li><a class="dropdown-item" href="#">Link 2</a></li>
      <li><a class="dropdown-item" href="#">Link 3</a></li>
      <li><hr class="dropdown-divider"></li>
      <li><a class="dropdown-item" href="#">Another link</a></li>
    </ul>
  </div>
</div>

</body>
</html>

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 25 (2 by maintainers)

Most upvoted comments

Hey everyone, I found out what’s causing this conflict,

tl;dr (The solution):

Node.ELEMENT_NODE = 1; //that line will fix it

The reason this conflict happens:

Bootstrap relies on the global object property Window.Node.ELEMENT_NODE to determine whether or not it should raise the event, like this

const isDisabled = element => { if (!element || element.nodeType !== Node.ELEMENT_NODE) return true; if (element.classList.contains('disabled')) return true; if (typeof element.disabled !== 'undefined') return element.disabled; return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false'; };

It makes sure that element.nodeType is of type Node.ELEMENT_NODE,

However, one of web-ifc dependencies (earcut) overrides the global object Node, and changes it to a function constructor for this struct Node

which leads to Node.ELEMENT_NODE being undefined instead of its actual value of ‘1’, so the line element.nodeType !== Node.ELEMENT_NODE will always make isDisabled = true ,and that’s why all of the bootstrap element events will not trigger.

Conclusion

Unfortunately, since this is caused by the wasm module itself, and by a third party dependency, we’d need to either change the bootstrap js file or the hpp file to avoid this conflict.

However, we can do the second best thing, which is simply redefining the Node.ELEMENT_NODE to be equal to ‘1’,

Node.ELEMENT_NODE = 1; //that should fix your problem

You can execute this line at any time after loading the wasm files and it’ll work again.

Hope that helps!

Hey @vulevukusej I looked at this and, to be honest, have no idea about what’s happening. If that last comment solves the issue, that’s going to be the solution!

To anyone else who might’ve also encountered this - a temporary workaround is to simply initiate the bootstrap elements manually in javascript.: newCanvasElement = new bootstrap.Offcanvas(_HtmlElement_)

Just to be sure we are on the same page, you are generating the bundle.js file yourself, right? Can you please update a reproducible example?

Yes I’m bundling myself. On my way home so I’ll upload an example to my repo tomorrow. Cheers.