crysalead-js / dom-layer

Virtual DOM implementation.
MIT License
30 stars 1 forks source link

issues rendering svg elements #8

Closed ghost closed 9 years ago

ghost commented 9 years ago

@jails Got trouble rendering SVG elements. Not sure if I should use attrs or attrsNS, but only the attrs sems to work. It get mounted, but not visible.

What I had expected to see is a red circle with a thin black line around it.

This is the code:


var vtree = h({ tagName: 'svg' }, [
    h({ tagName: 'circle',
       attrs: {
                    cx: 20,
                    cy: 20,
                    r: 10,
                    stroke: "black",
                    "stroke-width": 1,
                    fill: "red"
                },
        props: { "onclick": function() { alert("Hello, world"); } } // Is this working on SVG, at all?
      })
]);

Update: Got it to work when I added namespace: "http://www.w3.org/2000/svg", but easier if this was automatic, or?

Anyway, if I attach another child to it:

  h({ tagName: 'a',
        attrs: { "xlink:href": "http://link" },
    }),

The a-tag is not working even if I remove the onclick property. And I'm still confused about attr and attrsNS. Anyways, only attr sets the attribute, for attrsNS it set undefined, but the href link are set.

ghost commented 9 years ago

@jails Here is a quick list over SVG issues I get:

1. Can set, but will not work height and width attributes

In the example above. If I change the first line to this:

h({ tagName: 'svg', namespace: "http://www.w3.org/2000/svg",   attrs: {  width:300, height:3000 } } [

it will automaticly set the element to a div-tag even if you have specified a svg

2. a-tag not working. Even if you attach a "Hello, world!" on the "a" child, like this:

 h({ tagName: 'a',
       namespace: "http://www.w3.org/2000/svg",
        attrs: { "xlink:href": "http://link"},
    }, ["Hello, World!"]),

The result will only be visible in the console.log not in the browser window.

3. attrsNS don't seem to work 4. Namespaced SVG attributes are not working

ghost commented 9 years ago

@jails It also seems not to be enough to check if the tagName is either svg or math and automaticly add namespace because circle, rect etc, should got the same namespace as svg

When I now pointed out all the issues or strange things with svg you will figure out that MathML face almost the same issues.

ghost commented 9 years ago

@jails I tried to investigate a little. It seems that it will not create a element if this.namespace are empty / blank. You will get a Uknown HTML element error. This seems to occur if I add a circle as tagName etc.

So if you check if "svg" or "math", and you add a "circle", you will get this issue.

I'm aware you can set namespace manually and this error will not occur.

Anyways. There seems to be a ton of other issues here too...

jails commented 9 years ago

Indeed I thought the namespace was propagated automatically, fixed in https://github.com/crysalead-js/dom-layer/commit/8407fef6e053a712acec5c658967a9f4025ea007 Otherwise attrs is for attributes. and attrsNS are for namespaced attributes. So each time you have a colon is an attribute like "xlink:href" you must use attrsNS for them. And I don't see that many issues, all the example seems to work fine now when used correctly: https://jsfiddle.net/3htrx2zh/

ghost commented 9 years ago

@jails What I actually tried to was the 'a' tag to work when you click on a SVG element, as a child node. Not separated mounted.

In CitoJS you can do that, but not here.

Anyways. It seems like REACT got same issues: https://github.com/facebook/react/issues/3845

jails commented 9 years ago

Can you provide a valid CitoJS fiddle ?

ghost commented 9 years ago

@jails Give me 15 minutes, need to fix something first. But at the first glance it seems that you are splitting with the ":" and only using the href, while citoJS are not splitting.

I'm not so good with fiddle, so I just paste code snippet here and you can run it locale. Or?

ghost commented 9 years ago

@jails As you may know Cito is litle more advanced with events etc. But click on the button to create more circles. Each time you click on a circle, it will activate the href and you are taken to Google.

Hope that helps!


var circles = [{
        tag: "svg",
        attrs: {
            height: 40,
            width: 40
        },
        children: {
            tag: "a",
            attrs: {
                "xlink:href": "http://google.com"  // The magic happen here !!!!
            },
            children: {
                tag: "circle",
                attrs: {
                    cx: 20,
                    cy: 20,
                    r: 10,
                    stroke: "black",
                    "stroke-width": 1,
                    fill: "red"
                }
            }
        },
    }
];
function newCircles(e) {
    circles = circles.concat(circles);
    cito.vdom.update(rootNode, root);
}
function button() {
        return {
            tag: 'button',
            attrs: {
                title: 'SVG demo',
            },
            events: {
                click: newCircles
            },
            children: 'double'
        }
    }
function root() {
    return {
        tag: 'div',
        children: [
            button, {
                tag: 'ul',
                children: circles
            }
        ]
    };
}
var rootNode = cito.vdom.append(document.body, root);
ghost commented 9 years ago

@jails I'm going offline now. Will bug check a litle tomorrow if I got some time.

I know all VD projects online, but I'm really facinated about your work! Therefor I spend some hours trying to find all your bugs.

If you don't want me to continue to find your bugs, just let me know!

jails commented 9 years ago

Glad you find it interesting and if you find some bugs yeah sure open some more issues. However I didn't see the issue you were talking about https://jsfiddle.net/q9zecawz/, I can click on circles and get redirected to the defined url.

ghost commented 9 years ago

@jails I just come online to verify another bug and reply to you. I see it's working now, but it was not and still are not working in the example given in the first post in this thread.

Anyway.

Another bug come up. Try this example, and let me know why it's rendering a empty div tag?? I state it should be an svg with namespace and some attrs. But ending up as a div-tag and no svg.

var vtree = h({ tagName: 'svg', namespace: "http://www.w3.org/2000/svg",   attrs: {  width:300, height:3000 } } [
    h({ tagName: 'circle',
       attrs: {
                    cx: 20,
                    cy: 20,
                    r: 10,
                    stroke: "black",
                    "stroke-width": 1,
                    fill: "red"
                },
        props: { "onclick": function() { alert("Hello, world"); } } // Is this working on SVG, at all?
      })
]);
jails commented 9 years ago

There was a missing quote before the children definition (the array) https://jsfiddle.net/cby22m6z/1/