capricorn86 / happy-dom

A JavaScript implementation of a web browser without its graphical user interface
MIT License
3.24k stars 194 forks source link

Implement getComputedTextLength support #790

Open lloydjatkinson opened 1 year ago

lloydjatkinson commented 1 year ago

Is your feature request related to a problem? Please describe. The getComputedTextLength function is not implemented causing some libraries to fail server side.

Describe the solution you'd like Implement it.

Describe alternatives you've considered Don't know of any

Additional context When using a D3 or a library that depends on it like Venn the following error is encountered:

/workspace/repo name/node_modules/@upsetjs/venn.js/build/venn.js:2069
        if (joined.length > minChars && tspan.getComputedTextLength() > width) {
                                              ^

TypeError: tspan.getComputedTextLength is not a function
    at HTMLUnknownElement.<anonymous> (/workspace/lloydatkinson.net/node_modules/@upsetjs/venn.js/build/venn.js:2069:47)
    at Selection.default [as each] (file:///workspace/lloydatkinson.net/node_modules/d3-selection/src/selection/each.js:5:37)
    at chart (/workspace/lloydatkinson.net/node_modules/@upsetjs/venn.js/build/venn.js:1885:22)
    at Selection.default [as call] (file:///workspace/lloydatkinson.net/node_modules/d3-selection/src/selection/call.js:4:12)
    at eval (/src/design/VennDiagram.astro:26:55)
    at VennDiagram (/node_modules/astro/dist/runtime/server/astro-component.js:22:12)
    at Module.renderToString (/node_modules/astro/dist/runtime/server/render/astro/factory.js:16:31)
    at renderJSXVNode (/node_modules/astro/dist/runtime/server/jsx.js:80:81)
    at renderJSX (/node_modules/astro/dist/runtime/server/jsx.js:58:10)
    at eval (/node_modules/astro/dist/runtime/server/jsx.js:45:45)
    at Array.map (<anonymous>)
    at renderJSX (/node_modules/astro/dist/runtime/server/jsx.js:45:34)
    at renderElement (/node_modules/astro/dist/runtime/server/jsx.js:194:139)
    at renderJSXVNode (/node_modules/astro/dist/runtime/server/jsx.js:85:59)
    at renderJSX (/node_modules/astro/dist/runtime/server/jsx.js:58:10)
    at slots.<computed> (/node_modules/astro/dist/runtime/server/jsx.js:74:65)
    at Module.renderChild (/node_modules/astro/dist/runtime/server/render/any.js:23:24)
    at async Module.renderSlot (/node_modules/astro/dist/runtime/server/render/slot.js:28:22)

This can be reproduced in a Node project with the following code:

import { Window } from 'happy-dom';
import venn from '@upsetjs/venn.js';

const svgWindow = new Window();
const svgDocument = svgWindow.document;

svgDocument.body.innerHTML = '<div class="zxcvbn"></div>';
const container = svgDocument.querySelector('.zxcvbn');

const sets = [
    { sets: ['Apple and Banana'], size: 12 },
    { sets: ['Cherry and Kiwi'], size: 12 },
    { sets: ['Apple and Banana', 'Cherry and Kiwi'], size: 2 },
];

var chart = venn.VennDiagram();
// @ts-expect-error Incorrect typings
select(container).datum(sets).call(chart);
const svg = svgDocument.body.toString();

// console.log(svg)

If single words are used for the labels the code path that needs to measure text does not happen.

lloydjatkinson commented 2 months ago

Anything?