web-ifc-viewer icon indicating copy to clipboard operation
web-ifc-viewer copied to clipboard

IfcViewerAPI breaks some functionality in Bootstrap5

Open vulevukusej opened this issue 3 years ago • 2 comments

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/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/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>

vulevukusej avatar Oct 12 '22 14:10 vulevukusej

Hi! I'm guessing that this happens because the div that contains the viewer is supposed to be empty. If you want to create menus, you should do it in a completely separate HTML element.

agviegas avatar Oct 17 '22 10:10 agviegas

It doesn't matter where I place the menu, it seems as if something in the code removes the event listener from the bootstrap elements. I'll experiment some more and report back if I find a workaround.

vulevukusej avatar Oct 17 '22 10:10 vulevukusej

Any updates on this? No matter what I try, it seems something within ifcjs conflicts with the javascript-dependent elements in bootstrap.

vulevukusej avatar Nov 30 '22 15:11 vulevukusej

Hey @vulevukusej are you sure that the div that you pass to web-ifc-viewer is empty (0 HTML elements inside)?

agviegas avatar Nov 30 '22 15:11 agviegas

@agviegas In the example above there isn't even a div defined for the viewer, and I never even try to load a model. Just importing the IfcViewerAPI is enough to break some javascript functionality in bootstrap. For reference, the exact same code works flawlessly if I just use three.js or xeokit.

vulevukusej avatar Nov 30 '22 15:11 vulevukusej

@vulevukusej in the example above, what is the HTML element that you are using to render the scene?

agviegas avatar Nov 30 '22 15:11 agviegas

@agviegas sorry if i'm not explaining it clearly. I intentionally skip rendering the scene or loading any model. I wanted to figure out myself what is causing the conflict. My javascript file includes the following 2 lines only:

import { Color } from 'three';
import { IfcViewerAPI } from 'web-ifc-viewer';

and the html file has nothing else other than basic dropdowns with bootstrap classes.

vulevukusej avatar Nov 30 '22 16:11 vulevukusej

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?

agviegas avatar Nov 30 '22 16:11 agviegas

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.

vulevukusej avatar Nov 30 '22 16:11 vulevukusej

@agviegas Good Morning! - Here's the repo with small example demonstrating the issue: https://github.com/vulevukusej/Bootstrap-IFCjs

With this line of code commented out, the bootstrap functionality works as expected; clicking on the button opens the offcanvas sidebar.

vulevukusej avatar Dec 01 '22 06:12 vulevukusej

::take

aka-blackboots avatar Dec 01 '22 23:12 aka-blackboots

🟢🟢🟢

::take

Hi, @aka-blackboots! Thanks for taking this bounty! The due date is December 22, 2022 UTC.

If you need to submit some pull requests (PR) to complete the tasks, make sure that the last and only the last PR has a title that either starts with the bounty ID or is exactly the same as the bounty name. After the PR is merged, this bounty’s status will automatically changed to done.

If you do not need to make a PR, tell the manager @agviegas to run ::done command after your tasks is confirmed to be done.

Good luck!

agviegas avatar Dec 01 '22 23:12 agviegas

::drop

aka-blackboots avatar Dec 01 '22 23:12 aka-blackboots

🟢🟢🟢

::drop

Hi, @aka-blackboots! Thanks for giving it a try! It’s now once again available for anyone to take.

agviegas avatar Dec 01 '22 23:12 agviegas

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_)

vulevukusej avatar Dec 02 '22 08:12 vulevukusej

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!

agviegas avatar Dec 12 '22 11:12 agviegas

::take

aozien avatar Dec 18 '22 01:12 aozien

🟢🟢🟢

::take

Hi, @aozien! Thanks for taking this bounty! The due date is January 8, 2023 UTC.

If you need to submit some pull requests (PR) to complete the tasks, make sure that the last and only the last PR has a title that either starts with the bounty ID or is exactly the same as the bounty name. After the PR is merged, this bounty’s status will automatically changed to done.

If you do not need to make a PR, tell the manager @agviegas to run ::done command after your tasks is confirmed to be done.

Good luck!

agviegas avatar Dec 18 '22 01:12 agviegas

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!

aozien avatar Dec 18 '22 20:12 aozien

::done

agviegas avatar Dec 19 '22 10:12 agviegas

🟢🟢🟢

::done

Hi, @aozien! Thanks for your contributions! Please submit an expense to IFC.js Open Collective. Then, tell us the invoice number via the ::expense::_____ command (replace the _____ with the invoice number).

agviegas avatar Dec 19 '22 10:12 agviegas

@aozien thanks, you're awesome ☺️

vulevukusej avatar Dec 19 '22 10:12 vulevukusej

@aozien thanks, you're awesome ☺️

No problem, you did a great job too 😄

aozien avatar Dec 19 '22 13:12 aozien

::expense::114333

aozien avatar Dec 19 '22 13:12 aozien

🟢🟢🟢

::expense::114333

Hi, @aozien! Thanks for the confirmation! We’ll proceed to review the expense. Once it’s approved, the payment will be scheduled.

agviegas avatar Dec 19 '22 13:12 agviegas