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

Add support for namespaced elements #104

Closed
wants to merge 1 commit into from
Closed

Add support for namespaced elements #104

wants to merge 1 commit into from

Conversation

pdf
Copy link
Contributor

@pdf pdf commented Mar 30, 2017

This allows the creation of elements like inline SVG.

Refs #54

Implementing full SVG support is a much more complex beast - that would require generating a new set of elements and properties for SVGs, and possibly some new interfaces to ensure they're only used inside an SVG element.

This change will support attempts at implementing the above, but in the mean time it allows people to construct SVGs manually using vecty.NamespacedTag and vecty.Attribute.

Copy link
Contributor

@dmitshur dmitshur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some optional thoughts from me.

dom.go Outdated
properties, attributes map[string]interface{}
eventListeners []*EventListener
children []ComponentOrHTML
tag, text, innerHTML, namespace string
Copy link
Contributor

@dmitshur dmitshur Mar 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think namespace should be there before tag. It goes before tag in the call to createElementNS. Logically, that order makes more sense to me.

dom.go Outdated
h.Node = js.Global.Get("document").Call("createElementNS", h.namespace, h.tag)
} else {
h.Node = js.Global.Get("document").Call("createElement", h.tag)
}
} else {
h.Node = js.Global.Get("document").Call("createTextNode", h.text)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it were me, I'd prefer a single-level switch with 3 cases, rather than nesting:

switch {
case h.tag != "" && h.namespace == "":
	h.Node = js.Global.Get("document").Call("createElement", h.tag)
case h.tag != "" && h.namespace != "":
	h.Node = js.Global.Get("document").Call("createElementNS", h.namespace, h.tag)
default:
	h.Node = js.Global.Get("document").Call("createTextNode", h.text)
}

I think that's more readable.

But I think you should defer to @slimsag's preferences. Also, I'm not sure about the performance characteristics of switch vs if in GopherJS. Maybe that's a factor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, not sure about this one - I haven't really got my head around testing for GopherJS to do some benching. I think I'll just make this change for readability and let @slimsag weigh in if he'd prefer alternative syntax.

dom.go Outdated
@@ -268,8 +271,16 @@ func (h *HTML) Restore(old ComponentOrHTML) {
// function is not used directly but rather the elem subpackage (which is type
// safe) is used instead.
func Tag(tag string, m ...MarkupOrComponentOrHTML) *HTML {
return NamespacedTag(``, tag, m...)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's simpler/more common to represent empty string with an interpreted – rather than raw – string literal ("").

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've no problem changing this for consistency, but as a general personal query, can you explain the assertion that interpreted strings are simpler?

I tend to use raw strings liberally, but I may examine that behaviour if there are technical deficiencies that I'm unaware of.

Copy link
Contributor

@dmitshur dmitshur Mar 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you explain the assertion that interpreted strings are simpler?

Good question, I'm happy to discuss it.

I should clarify, it's not that I think interpreted strings are simpler overall. But rather than using "" to represent empty string is simpler.

For me, when it comes to single-line strings, I generally always start with interpreted strings as a default, and "upgrade" to raw strings when doing so makes the string simpler. That's typically when the strings involve characters such as ".

So, by default, I would do "foo", not `foo`.

For a short and simple string like that, both work equally well. The differences start to come out as soon as you add special characters. With interpreted strings, the special characters can/need to be escaped. But a raw string literal cannot contain the ` character itself.

For multi-line strings, I consider both equally, and often go with raw strings, because they're more readable and look more like the string value they represent. If the raw string is very long and happens to contain a few ` characters, I can get around that by concatenating the raw string + "`" + rest of raw string.

The absolute only potential technical advantage I see in using interpreted string for empty string is the following. The " character is wider, and more vertical than `. So with the two of them together, to me at least, I think it's more visible that "" and " " are empty sting and single space. But with raw string, it's a tiny bit harder to tell whether `` is empty string or a single space.

However, in the end, I think the main deciding factor comes down to consistency. If you look at the Go source code, there are a total of 7753 hits for "":

image

But only 241 matches for ``, and many of those hits are false positives:

image

So, I prefer to go with the most popular representation because it's most what most people writing Go code tend to agree on. Given there are no strong technical reasons to prefer one over the other – they're pretty much equivalent – that's all I have to go on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the brain-dump 😉

My preference has always been to be explicit about where escape sequences or interpolation are expected, and I expect the parser to be simpler for raw strings, however consistency is absolutely a good enough reason to prefer one form from mostly equivalent options.

I must admit though that ergonomics does play a part in my preference - my pinky gets tired these days, and one keypress is less strain than two. I'll have to consider before applying this to my personal code, as I write more Go. Perhaps I'll try a keycode mod.

In any case, thanks for the discussion, change is inbound.

This allows the creation of elements like inline SVG.

Refs hexops#54
@pdf
Copy link
Contributor Author

pdf commented May 10, 2017

Closing in favour of #107 meta-pull.

@pdf pdf closed this May 10, 2017
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

Successfully merging this pull request may close these issues.

2 participants