F2F/TPAC 2014/HTML integration again

From SVG
< F2F‎ | TPAC 2014

Issue 1: Using SVG elements directly in HTML

Motivation:

  • Some elements, semantically and practically just shouldn't need to be wrapped in <foreignObject>, e.g. <template>
  • There are other elements with authors frequently want to use in SVG such as <p>, <button>, <iframe>, <video>, and <canvas> for which using <foreignObject> is sub-optimal because:
    • For <iframe> requiring <foreignObject> makes it necessary to manage two viewports since <foreignObject> doesn't shrinkwrap its contents. Hence, embedding another SVG image looks like this:
 <foreignObject x="50" y="50" width="100" height="100">
   <iframe width="100" height="100" src="svg.svg"
     xmlns="http://www.w3.org/1999/xhtml"></iframe>
 </foreignObject>

But it would be nice to just write:

 <iframe x="50" y="50" width="100" height="100" src="svg.svg"/>
    • <foreignObject> is long and ugly to type
    • For standalone SVG documents, requiring a namespace on children of <foreignObject> is a pain (this SVGWG member has to look up the namespace of SVG/XHTML every time—largely to remember if there is a slash at the end or not)
    • For use-cases where a lot of HTML content is used (e.g. map files made up of a matrix of <iframe> map tiles), the overhead introduced by <foreignObject> may be significant, although this is a lesser concern.

Some technical background:

  • For the SVG-embedded-in-HTML case the following fragment:
<!doctype html>
<svg>
<span id="s">

<div id="i">

The <span> and <div> end up as siblings of the <svg>.

See: http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=3276

This is because the HTML parser breaks out of foreign content mode when it sees certain tags. See the rules for parsing tokens in foreign content, particularly about the 6th item there.

This was done because several pages were found that erroneously include a random unclosed <svg> tag somewhere towards the start of the document. If the content were processed in foreign content mode, none of the remainder of the page would render.

Apparently the set of tags listed in the spec corresponds to actual elements found following the <svg> tag although it does seem quite large.

Discussion so far:

Possible approaches:

We have discussed a number of possible approaches to this.

Common to all approaches

  • According to Hixie, allowing <template> in SVG is a no-brainer. We both can and probably should do this. We should just file bugs on the whatwg spec and he'll work it in: https://whatwg.org/newbug. We may also need to adjust the SVG parser to allow this in the standalone SVG case.

(“may” because exactly what is required here will depend on the approach we choose from below as well as what we decide about namespaces)

  • If we're to make any of the HTML elements that currently close the <svg> element to stop doing that then we have to think about compatibility for those pages. I'm going to pick up this issue below, however, since first it makes sense to outline the possible scenarios.

<div> approach

In this approach, we only allow <div> to appear by itself in SVG (in addition, of course, to <template> as above).

The <iframe> example from before becomes:

<div style="x: 50; y: 50"><iframe width="100" height="100" src="svg.svg"></iframe></div>

(Note that this has the same number of characters as 'svg' 😊)

Hixie didn't seem thrilled with the idea of adding x/y/transform presentation attributes to HTMLElement but maybe if it's just <div> it might be ok?

Whitelist approach

In this case we could introduce a whitelist of HTML elements allowed directly in SVG, e.g.

  • video
  • audio
  • canvas
  • iframe
  • input
  • button
  • p
  • (template)

If the set is small enough, adding presentation attributes might be palatable.

I think it's somewhat confusing for authors however?

All-in approach

Basically allow all HTML elements to be used directly in SVG. Or is it all flow content? What to do with elements that are not flow content? e.g. <li>

If we do this we have to address overlap:

  • <font> - fixed by deprecating
  • <style> - can probably be aligned?
  • <style> - has different semantics but can be aligned???

This is probably the hardest for authoring tools since they have to either support all of HTML (is it possible to use a WebView or something for those parts of the tree?) or otherwise explain to users why the text that's wrapped in a <p> isn't showing. Of course, that's only an issue for tools that support arbitrary input.

The backwards compatibility issue

Suppose we have content with stray unclosed <svg> elements, e.g.

 <!doctype html>
 <svg>

<div> <div>

If we stop automatically closing the <svg> tag when we see the <div> what will happen?

  1. Firstly, in all of the above proposals we will at least render the div now.
  2. But where?
    • We already have a proposal to define SVG layout as something like position:absolute with percentages resolved against the outermost SVG viewport. Or something along those lines. Tab can explain this better.
    • However, if we do that all the <div>s will end up stacked on top of each other, right?
  3. And what about the bounds of the <svg>? If no size is specified it will get clipped to 300px wide.
    • We can fix that by making <svg> overflow:visible by default. IE already does this.
    • However, will percentage units will still be sized according to a 300px viewport? Will that matter?

Yet another approach: <box>

If all this proves too hard, we could just allow <template> and other new elements without backwards compatibility issues, and wrap other elements in <box>.

That would give us:

<box x="50" y="50"><iframe width="100" height="100" src="svg.svg"></iframe></box>

That, at least, avoids the compatibility issues and allows adding x/y/transform presentation attributes. Hixie didn't seem keen on using <html> for this.

Issue 2: Putting SVG elements in the HTML namespace

Hixie was not enthusiastic about this. While agreeing that if we designed things again from the start we wouldn't use namespaces he remarked that we'd crossed that bridge and trying to go back would be very difficult and we'd be addressing issues from this for years.

So I suppose that with the above approaches we'd end up with a <div> or an <iframe> with a different namespace.

Supposing that we can't add x/y/transform presentation attributes then authors would already have to make a mental distinction between SVG and HTML elements since they'd have to learn, "Why can't I just write x="10" here? Oh, because it's an HTML element".

If we don't put SVG elements in the HTML namespace then we should still look at solving some of the useability issues introduced by namespaces, e.g.

  • Not requiring namespaces in standalone SVG docs
  • Making createElementNS easier.
    • Hixie didn't like the idea of document.createElement("circle") setting the SVG namespace behind the scenes
    • Perhaps we could do something like document.createElement("svg:circle")?

Background: What's wrong with namespaces?

See responses to: https://twitter.com/wycats/status/527247467486519296

Quoting some of those responses (mostly from Henri Sivonen):

  • The name collisions between HTML and SVG rule out simple element creation API. Without collisions, the wouldn't be a need for xmlns.
  • The notion that DOM has a Level 1 view without namespaces and a Level 2 view with namespaces makes use of L1 APIs a potential bug.
  • Every API needs to pass two things instead of simply one even though people often think in terms of one string naming an element.
  • You can't type the URLs from memory and if you think you can, you'll make a hard-to-debug mistake some time.
  • Since syntax requires the shorthand, serializers involve complexity for generating roughly minimal shorthand syntax.
  • Thanks to Level 1 APIs, you can introduce unserializable nodes in the data model.
  • The notion of many vocabularies was a wrong tomorrow. We got 4: HTML, SVG, MathML and ARIA. Only SVG overlaps HTML...

Issue 3: Adding a new top-level graphics element to switch to a new DOM

Hixie remarked that even <graphics> is basically a mode switch and he said that in his experience mode switches have not worked well. If we are to take that advice we are basically left with:

  • Hope that Dirk's experiment with removing the SVG DOM from Blink succeeds and we can just rewrite things.
  • A combination of deprecating unused parts and augmenting the clumsy in-use interfaces with nicer ones but slightly less-useful names.

Note that for the second option, we've done something slightly similar with cases like classList augmenting className. So we could, for example, add SVGRectElement.widthVal or perhaps extend SVGAnimatedLength to give it, e.g. a px member so you could at least write SVGRectElement.width.px = 5. Then we could deprecate the animVal/baseVal members, add console warnings and a use counter, and eventually drop them.