Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SVG elements not created using createElementNS #68

Open
ScraM-Team opened this issue May 6, 2022 · 3 comments
Open

SVG elements not created using createElementNS #68

ScraM-Team opened this issue May 6, 2022 · 3 comments

Comments

@ScraM-Team
Copy link
Contributor

DomBuilder.java:51 always creates elements using createElement. This works for HTML elements, but for SVG elements it causes the browser to not render the SVG. Using svg elements in a template looks OK in the browser inspect pane, but the SVG is not shown.

Instead, the SVG elements need to get created using createElementNS with the SVG namespace URI. One reference: https://stackoverflow.com/questions/3492322/javascript-createelementns-and-svg

A quick but hacky fix is to check for specific SVG tag names in DomBuilder.open(). Unfortunately there are a couple of overlaps between HTML and SVG (like 'title'), so this isn't a complete solution.

It seems a possible better fix is to change parsing to flag DOMElements as SVG. Once the 'svg' parent is seen, all children can automatically be SVG. Then an overloaded open() could call createElementNS for the SVG-flagged DOMElements.

Alternatively, instead of a flag a DOMElement subtype called SVGElement could be created.

@ScraM-Team
Copy link
Contributor Author

I tried out the hacky fix and it does work. It enables using 'attr:' annotations in SVG to make SVG drawings bound to Flavour expressions. This could be useful for making drawings react to value changes in many scenarios, from live charts to games and more.

@ScraM-Team
Copy link
Contributor Author

Demo here showing an SVG circle's radius bound to a slider: https://frequal.com/TeaVM/demo/svgflavour/

These are the diffs to DomBuilder. This is the "hacky" solution, which would require enumerating all SVG element names in a list and figuring out how to handle conflicting element names like 'title'.

public class DomBuilder {
+
+  private static final String SVG_NS_URI = "http://www.w3.org/2000/svg";
     private static final Document document = Window.current().getDocument();
     private Slot slot;
     private Deque<Item> stack = new ArrayDeque<>();
     private List<Renderable> renderables = new ArrayList<>();
+  private static final List<String> listSvgTagNames = Arrays.asList(
+          "svg",
+          "circle");
 
     public DomBuilder(Slot slot) {
         this.slot = slot;
@@ -48,7 +54,12 @@
     }
 
     private DomBuilder open(String tagName, boolean slot) {
-        Element elem = document.createElement(tagName);
+    Element elem = null;
+    if (listSvgTagNames.contains(tagName)) {
+      elem = document.createElementNS(SVG_NS_URI, tagName);
+    } else {
+      elem = document.createElement(tagName);
+    }
         Item item = new Item();

@ScraM-Team
Copy link
Contributor Author

I just checked in a less-hacky fix and created a PR: #69

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant