svgdotjs / svg.js

The lightweight library for manipulating and animating SVG
https://svgjs.dev
Other
11.15k stars 1.08k forks source link

ForeignObject - not showing form element #1058

Closed mrjeanjean closed 4 years ago

mrjeanjean commented 4 years ago

I don't know if it's a bug, really. But the ForeignObject element does not seem to work as expected for me.

I tried this pretty simple code :

var draw = SVG().addTo('body').size(400, 400);

var forObj = draw.foreignObject(200, 200);
var text = SVG('<textarea>Foo example</textarea>');

forObj.add(text);

Here is the code running in Fiddle : https://jsfiddle.net/MrJeanJean/hxdptc75/

On my browsers (Chrome & Firefox), the textarea element is not showing at all.

The weird thing here, is that the textarea exists in the DOM (I can inspect it and see it in the DOM tree), but it's not considered as html element by the browser (no CSS default styles applied, not editable, content is not displayed...).

Maybe I did something wrong. Thanks.

Fuzzyma commented 4 years ago

Hm thats strange. When you edit the html, it suddenly shows up. So that has to be a problem with namespaces i guess. So I think this is a bug. But I need to dig deeper for this. Try creating the element yourself (with document.createElement) and add it with add and see if that works

// EDIT: tried it myself - that works

mrjeanjean commented 4 years ago

Thanks for the very fast reply! :) Yes if I create the textarea with document.createElement method, it works well.

var draw = SVG().addTo('body').size(400, 400);

var forObj = draw.foreignObject(200, 200);
//var text = SVG('<textarea>Foo example</textarea>'); // removed
var text = document.createElement("textarea"); // replaced by

forObj.add(text);

It will do the job for me, thanks you! Good luck for debugging! Sounds a very strange bug...

Fuzzyma commented 4 years ago

I guess I already know what the issue is. In svg.js all elements are create with document.createElementNs because svg elements are from the svg namespace. Unfortuately the implementation of namespaces is completely diffuse in the specs as well as in the browsers. What once was a good idea became a huge mess. Enough of the rant. What happens is, that textarea gets added to the svg namespace and thats wrong. So that could be the issue :)

mrjeanjean commented 4 years ago

Ok, thanks for the explanation. :) That's mean foreignObject content shoud be treated as HTML objects and created with document.createElement like other HTML element. Even if it belongs to a svg context...

Oh I see... And SVG(element) create an html element with the create() method .... which use document.createElementNs!

Fuzzyma commented 4 years ago

Exactly! Albeit in your case you use an html fragment (SVG('<b>sad</b>') which is created differently but still in the svg context (I think)

mrjeanjean commented 4 years ago

Yes you're right. I forgot to mention that html fragment works well (ie: SVG('<div>foo</div>')). That's why I named my topic "not showing form element". I don't know if the problem appears with other html element types...

Fuzzyma commented 4 years ago

Oh really? But textarea does not work? Strange...

mrjeanjean commented 4 years ago

Yes, strange, indeed... I updated my fiddle demo : https://jsfiddle.net/MrJeanJean/hxdptc75/ As you can see, the div element is well displayed.

Fuzzyma commented 4 years ago

Actually this work. As I said above it is required to create the element using document.createElement('textarea') and add this to the foreignObject

Working fiddle: https://jsfiddle.net/Fuzzy/v1Lbhnjw/

slozano54 commented 4 years ago

HI! Doesn't work for me as you can see. image

slozano54 commented 4 years ago

Albeit all elements are in the DOM

Fuzzyma commented 4 years ago

Your picture clearly shows the textarea. Please elaborate

slozano54 commented 4 years ago

Thanks for your answer. Yes it does but not the text "Foo example", even if i comment the line 18. I'm actually trying to render a math text with the katex library in a SVG using SVG.js library but i can't succeed anyway. Here is a fiddle with the issue : https://jsfiddle.net/slozano54/ajvcewop/

Fuzzyma commented 4 years ago

yes thats because I only focused on the form element and not the text. But the same problem applies here. You have to create it manually. See upated fiddle: https://jsfiddle.net/Fuzzy/v1Lbhnjw/

I plan on resolving this issue by allowing a second parameter in SVG() so that you can specify that you want to create html content

slozano54 commented 4 years ago

Thanks. Your SVG.js library is very helpful. Now the text appear as i have create it manually even once i need math text as you can see here https://jsfiddle.net/slozano54/ajvcewop/