- 
                Notifications
    You must be signed in to change notification settings 
- Fork 906
Description
Is your feature request related to a problem? Please describe.
The library cannot be used with a strict content security policy because it uses inline styles. When a strict csp is used, the tooltips and hover/click events do not work and the console contains csp violation errors:
Describe the solution you'd like
Preferably, replace inline styles with a stylesheet and class toggling.
Alternatively, provide an api to set a nonce that is used for inline styles.
Describe alternatives you've considered
I am currently monkey patching document.createElement and document.createTextNode to inject a nonce in the dynamically created elements. This is not a secure solution because it effectively allows inline styles when the are injected via these apis. Additionally this requires to use a nonce.
Additional context
Reproduce with the following example file (e.g. with python -m http.server). Toggle the csp at the top:
<!doctype html>
<html>
<head>
  <!-- this works -->
  <!-- <meta http-equiv="Content-Security-Policy" --> <!--   content="default-src 'self'; script-src-elem 'unsafe-inline' https://cdn.jsdelivr.net; style-src-elem 'unsafe-inline'" /> -->
  <!-- this does not works -->
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src-elem 'unsafe-inline' https://cdn.jsdelivr.net;" />
  <style>
    body {
      margin: 0;
    }
  </style>
  <script src="https://cdn.jsdelivr.net/npm/3d-force-graph"></script>
</head>
<body>
  <div id="3d-graph"></div>
  <script>
    // Random tree
    const NODES = 300;
    const GROUPS = 12;
    const gData = {
      nodes: [...Array(NODES).keys()].map((i) => ({
        id: i,
        group: Math.ceil(Math.random() * GROUPS),
        user: i.toString(),
        description: i.toString(),
      })),
      links: [...Array(NODES).keys()]
        .filter((id) => id)
        .map((id) => ({
          source: id,
          target: Math.round(Math.random() * (id - 1)),
        })),
    };
    const Graph = new ForceGraph3D(document.getElementById("3d-graph"))
      .nodeAutoColorBy("group")
      .linkAutoColorBy((d) => gData.nodes[d.source].group)
      .linkOpacity(0.5)
      .nodeLabel((node) => `${node.user}: ${node.description}`)
      .onNodeClick((node) => {
        // Aim at node from outside it
        const distance = 40;
        const distRatio = 1 + distance / Math.hypot(node.x, node.y, node.z);
        const newPos =
          node.x || node.y || node.z
            ? {
              x: node.x * distRatio,
              y: node.y * distRatio,
              z: node.z * distRatio,
            }
            : {x: 0, y: 0, z: distance}; // special case if node is in (0,0,0)
        Graph.cameraPosition(
          newPos, // new position
          node, // lookAt ({ x, y, z })
          3000, // ms transition duration
        );
      })
      .graphData(gData);
  </script>
</body>
</html>