WebReflection / linkedom

A triple-linked lists based DOM implementation.
https://webreflection.medium.com/linkedom-a-jsdom-alternative-53dd8f699311
ISC License
1.62k stars 78 forks source link

Value of a foreign input element is an attribue #268

Open bartbutenaers opened 3 months ago

bartbutenaers commented 3 months ago

Dear,

First of all thank for sharing this nice library!

I have an issue when using an html input element as foreign object inside an svg drawing. Not sure if there is anything wrong with this library, or just me doing something not correctly...

BTW if you are wondering why such foreign objects are used, you can here see a demo animation on my wiki to see how it can be used for example for floorplans in home automation.

Case 1: input elements (ok)

I set a default value "Initial" to an input element:

let html = '<html><head></head><body><input id="my_input" value="initial"></body></html>'
let parser = new DOMParser()
let doc = parser.parseFromString(html, 'text/html')
let my_input = doc.querySelector('#my_input')
let value = my_input.value

Both in a browser and using Linkedom the element.value contains that default value:

image

Case 2: input elements as foreign object in svg (nok)

I set a default value "Initial" to an input element, which is a foreign object inside an svg drawing:

let html = '<svg xmlns="http://www.w3.org/2000/svg"><foreignObject><input id="my_input" value="initial" xmlns="http://www.w3.org/1999/xhtml"></foreignObject></svg>'
let parser = new DOMParser()
let doc = parser.parseFromString(html, 'image/svg+xml')
let my_input = doc.querySelector('#my_input')
let value = my_input.value

When running this in a browser, the element.value still contains that default value (as expected):

image

However when running this code in Linkedom, the element.value is undefined. And instead the "initial" is stored inside an attribute with name "value":

image

Hopefully somebody sees what I am doing wrong.

Thanks!! Bart

WebReflection commented 3 months ago

The XML world has no special nodes so far and it doesn't interoperate with the HTMLInputElement at all, you just have plain raw XML nodes. I need to orchestrate a similar dance to register special cases or even reuse classes from the HTML world but if you want to give it a try I'll welcome a PR (as I have very little time these days to work on this project, sorry).

bartbutenaers commented 3 months ago

Hi @WebReflection, Thanks for the fast response! Sorry to hear that you have little time, but that's part of the open source development experience ;-)

Did some debugging this evening, but not sure if I have enough knowledge about the topic to be able to create a PR...

It is required to add an xmlns to the foreign html input element, otherwise it won't be visualized inside the svg:

image

I read that the xmlns is inherited by the child elements, so I 'assume' that that attribute determines whether an element is an svg element or not?

But at this moment it looks like the mimeType parameter (of the parseFromString function) is used to determine the type, and that that parameter is being used for ALL elements. So I assume some change needs to be done in the following function:

image

I first thought that the xlmns attribute had to be taken into account as an extra condition on line 63, but for mime type "image/svg+xml" the isHTML is false, so I go directly to line 85 where the svg document creates always svg elements.

So I am a bit stuck...