I thought it made more sense to let *any* element, not just a canvas, be
usable as a CSS background (which also enables reflections, thumbnails
of slides, etc), and implemented that:
http://weblogs.mozillazine.org/roc/archives/2008/07/the_latest_feat.html
I ended up not porting it to trunk, because using url(#foo) syntax to
refer to an element in the Web page from a stylesheet was just wrong.
Also I wanted a more flexible setup; sometimes instead of referring to
the content by ID you would prefer to access a particular DOM node from
script. E.g. you might have a hidden IFRAME and want to render a
particular node in that IFRAME. People have been asking for this
functionality.
So here's a new proposal:
1) A new CSS image type, -moz-element(foo). Normally 'foo' is the ID of
an element in the document to which the stylesheet applies.
2) A new DOM API, window.mozSetImageElement("foo", node). The node is
used instead of the element with ID foo when -moz-element(foo) is used.
Elements which expose a natural image --- <img>, <video> and <canvas>
--- could be used with mozSetImageElement even when they're outside a
document. That gives you the ability to emulate Webkit's canvas feature
perfectly.
For an element in a document, the instrinsic size of the generated image
is the size of the bounding box (getBoundingClientRect) in CSS pixels.
For an element not in a document, the intrinsic size of the generated
image is the intrinsic size of the element, if it's an <img>, <video> or
<canvas> (otherwise nothing is rendered).
This would let us do things like a tab preview window with live tab
previews, by filling it with elements using
background-image:-moz-element(fooNNN); background-size:..., plus some
calls to window.mozSetImageElement("fooNNN", browserElementNNN).
Comments appreciated. The code from my bling-branch is already very
close to this, so if this sounds good and useful it should be fairly
easy for me or someone else to dig out the code, bring it forward to the
trunk, change the syntax and add the DOM API.
Rob
Sounds pretty useful for things we have coming up around tab preview
and other content munging -- maybe a good student/intern project?
Would it also work for stuff like border-image and list-image?
Mike
> This would let us do things like a tab preview window with live tab
> previews, by filling it with elements using
> background-image:-moz-element(fooNNN); background-size:..., plus some
> calls to window.mozSetImageElement("fooNNN", browserElementNNN).
This sounds crazy useful to me.
Eric Shepherd
Developer Documentation Lead
Mozilla Corporation
http://www.bitstampede.com/
> _______________________________________________
> dev-platform mailing list
> dev-pl...@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-platform
>
> So here's a new proposal:
> 1) A new CSS image type, -moz-element(foo). Normally 'foo' is the ID of an
> element in the document to which the stylesheet applies.
> 2) A new DOM API, window.mozSetImageElement("foo", node). The node is used
> instead of the element with ID foo when -moz-element(foo) is used.
I think having a new DOM API for this purpose can be useful, but it's not
ideal. We should preferably allow designers who only know CSS or only have
access to the stylesheets on a web page to use this feature without forcing
them to do half of their work in JS. In addition, some users may prefer to
browse the web without JS enabled (for example with NoScript). Further
more, there are use cases where we shouldn't allow script execution at all
(example: rendering email messages), so the proposed API would be useless in
those situations. This API in the current form might not be that useful for
theme developers for XUL applications as well, because they would be limited
to the identifiers registered by the chrome code which is out of their
control.
I have two proposals, which may at least serve as a ground point for a full
CSS-based feature:
a) Accept a full CSS3 selector as -moz-element's argument. This way,
authors could write:
div#main {
background-image: -moz-element(div#sidebar p.foo > img:first-of-type);
}
b) Invent a new CSS rule in order to "mark" elements for use with
-moz-element, such as:
div#main {
background-image: -moz-element(foo);
}
div#sidebar p.foo > img:first-of-type {
-moz-element-id: foo;
}
I think -moz-element-id should not be cascaded, and we should specify what
happens when the selectors in each case match more than one element (for
example, selecting the first element in DOM order).
I personally prefer the former approach because by reading a single rule you
will know everything that there is to know about the rule, but I'm not sure
if implementing it is possible without insane changes to the CSS parser.
Incidentally, this syntax is an extension of the url(#foo) syntax, because
#foo is a valid CSS3 selector.
The obvious downside of this proposal is that CSS3 selectors can only
reference elements inside the same document, so elements not bound to a
document or for example elements inside IFRAMEs can't be targetted in this
way. In that case, we can direct users to the mozSetImageElement API that
you proposed. This way, we would have an API which is designed to deal with
these special cases, but users are still free to only use this API if they
want.
Comments/suggestions/criticisms appreciated.
--
Ehsan
<http://ehsanakhgari.org/>
It is usable without JS as proposed. E.g.
<body style="background: repeat -moz-element(v)">
<div style="height:0; overflow:hidden">
<video id="v" autoplay src="rickroll.ogv"></video>
</div>
</body>
In practice, ensuring useful elements have IDs shouldn't be a big issue,
I would have thought. It's certainly far, far easier to implement an ID
match than selectors here.
Rob
#thumbnails > div { background-size:cover; }
<div id="slide1">...</div>
<div id="slide2">...</div>
<div id="slide3">...</div>
...
<div id="thumbnails">
<div style="background-image: -moz-element(slide1);"></div>
<div style="background-image: -moz-element(slide2);"></div>
<div style="background-image: -moz-element(slide3);"></div>
</div>
Rob
> On 14/7/09 9:20 PM, Ehsan Akhgari wrote:
>
>> On Tue, Jul 14, 2009 at 6:54 AM, Robert O'Callahan<rob...@ocallahan.org
>> >wrote:
>>
>>> So here's a new proposal:
>>> 1) A new CSS image type, -moz-element(foo). Normally 'foo' is the ID of
>>> an
>>> element in the document to which the stylesheet applies.
>>> 2) A new DOM API, window.mozSetImageElement("foo", node). The node is
>>> used
>>> instead of the element with ID foo when -moz-element(foo) is used.
>>>
>>
>> I think having a new DOM API for this purpose can be useful, but it's not
>> ideal. We should preferably allow designers who only know CSS or only
>> have
>> access to the stylesheets on a web page to use this feature without
>> forcing
>> them to do half of their work in JS.
>>
>
> It is usable without JS as proposed. E.g.
>
> <body style="background: repeat -moz-element(v)">
> <div style="height:0; overflow:hidden">
> <video id="v" autoplay src="rickroll.ogv"></video>
> </div>
> </body>
Yes, of course. But the DOM API you proposed was supposed to cover the
cases where ensuring that an has an ID is not feasible, right? My proposal
was based on trying to extend that idea without resorting to a JS API as
much as possible.
> In practice, ensuring useful elements have IDs shouldn't be a big issue, I
> would have thought.
I think we can't limit the CSS-only syntax to IDs by this reasoning. Of
course implementation feasibility is an obvious concern here as well.
> It's certainly far, far easier to implement an ID match than selectors
> here.
How hard would parsing the full selector and matching it would be? I'm not
really sure because I don't know the code, but I can only assume that we
should already have a selector parsing and matching API internally which we
probably used in implementing the query selectors API. Is that a correct
assumption?
--
Ehsan
<http://ehsanakhgari.org/>
It's not so much for working with elements where the author just forgot
to give them an ID, as for working with elements in specific
subdocuments, working with elements that aren't in a document, and
writing script library APIs that work with a passed-in element reference
where you may not want to change the ID of that element. None of those
scenarios would be helped by support for general selectors.
Maybe there are some use cases with missing IDs that my proposal leaves
uncovered, but I am not convinced they are more than a tiny fraction of
the space, and I don't think they are worth worrying about now.
> How hard would parsing the full selector and matching it would be? I'm not
> really sure because I don't know the code, but I can only assume that we
> should already have a selector parsing and matching API internally which we
> probably used in implementing the query selectors API. Is that a correct
> assumption?
That's correct. However, handling dynamic changes would be very
difficult with your model. The rule setting the background-image for an
element would depend on two selector chains: the selectors for the rule,
and the selectors in the special property value.
Rob
I understood this to be mostly for JS that just creates image tags or
the like, and never adds them to the document in question.
>> In practice, ensuring useful elements have IDs shouldn't be a big issue, I
>> would have thought.
>
>
> I think we can't limit the CSS-only syntax to IDs by this reasoning. Of
> course implementation feasibility is an obvious concern here as well.
>
>
>> It's certainly far, far easier to implement an ID match than selectors
>> here.
>
>
> How hard would parsing the full selector and matching it would be? I'm not
> really sure because I don't know the code, but I can only assume that we
> should already have a selector parsing and matching API internally which we
> probably used in implementing the query selectors API. Is that a correct
> assumption?
I think that ID is actually a pretty good choice, as it only selects a
single element. Otherwise we're up for some interesting questions:
Say you a background selector matching 3 elements inside a CSS rule that
applies to 3 elements. Which background would you apply to which element?
You could make some more or less arbitrary rule on how to select a
single element to apply for all, but the markup-way to denote that is to
restrict the selector to IDs, IMHO.
Axel
Would that work with elements from different documents? For instance,
could a video from the content area be rendered in a full-screen window?
> On 14/7/09 10:12 PM, Ehsan Akhgari wrote:
> > Yes, of course. But the DOM API you proposed was supposed to cover
> > the cases where ensuring that an has an ID is not feasible,
> > right? My proposal was based on trying to extend that idea without
> > resorting to a JS API as much as possible.
>
> It's not so much for working with elements where the author just
> forgot to give them an ID, as for working with elements in specific
> subdocuments, working with elements that aren't in a document, and
> writing script library APIs that work with a passed-in element
> reference where you may not want to change the ID of that element.
> None of those scenarios would be helped by support for general
> selectors.
>
> Maybe there are some use cases with missing IDs that my proposal
> leaves uncovered, but I am not convinced they are more than a tiny
> fraction of the space, and I don't think they are worth worrying
> about now.
If we define the syntax to be -moz-element(#id) instead of
-moz-element(id), then if in the future we ever want to allow more
complex selectors there is no backward compatibility problem.
zw
> Robert O'Callahan <rob...@ocallahan.org> wrote:
>
> > On 14/7/09 10:12 PM, Ehsan Akhgari wrote:
> > > Yes, of course. But the DOM API you proposed was supposed to cover
> > > the cases where ensuring that an has an ID is not feasible,
> > > right? My proposal was based on trying to extend that idea without
> > > resorting to a JS API as much as possible.
> >
> > It's not so much for working with elements where the author just
> > forgot to give them an ID, as for working with elements in specific
> > subdocuments, working with elements that aren't in a document, and
> > writing script library APIs that work with a passed-in element
> > reference where you may not want to change the ID of that element.
> > None of those scenarios would be helped by support for general
> > selectors.
> >
> > Maybe there are some use cases with missing IDs that my proposal
> > leaves uncovered, but I am not convinced they are more than a tiny
> > fraction of the space, and I don't think they are worth worrying
> > about now.
>
> If we define the syntax to be -moz-element(#id) instead of
> -moz-element(id), then if in the future we ever want to allow more
> complex selectors there is no backward compatibility problem.
>
This sounds like a great idea. We can even special case the #foo syntax to
not hit the selector engine if it proves to be a bottleneck in performance
later on when we have full selector support.
--
Ehsan
<http://ehsanakhgari.org/>
Would you intend to still handle dynamic updating even with just a plain
ID. So if I changed the ID of an element in JavaScript would te
background change accordingly?
Yes. We already have infrastructure for this (e.g. this is how all of
the SVG paint server stuff works).
-Borsi
Yes.
Rob
That sounds reasonable. Apart from anything else it makes it clear that
it's an ID reference. It might mislead people into thinking they can put
a full URI there, but if they try it, it won't work, so I don't think
that's a problem.
Rob
<body id="main">
...
<div style="background-image: -moz-element(main);">...<div>
...
John Daggett
My branch takes the approach that you can only traverse an element
reference once in a given stack of paints. So in your example, we start
painting <body>, inside there we're painting <div>, we follow the
reference to #main, we enter <body> again, but when we get to the <div>
again we refuse to following the reference to #main again, since we're
already using that one. The -moz-element draws nothing in that case.
Each occurrence of an ID reference can appear once on a painting stack,
so if you have
<body id="main" style="border:...">
<div style="background-image: -moz-element(main);">...<div>
<div style="background-image: -moz-element(main);">...<div>
</body>
the body border will actually be rendered 5 times, with stacks
root
root <div1's reference>
root <div1's reference> <div2's reference>
root <div2's reference>
root <div2's reference> <div1's reference>
I suppose it would be simpler to say that each referenced element can
only appear once in the painting stack, so the above example would only
draw the body border 3 times.
Rob
Full URI there would be useful, no? You could grab snippets of SVG,
for example.
~fantasai
I could see url() being useful there. But I think -moz-element() is
different since it reflects all dynamic changes to the *current*
document.
-David
--
L. David Baron http://dbaron.org/
Mozilla Corporation http://www.mozilla.com/
Actually, that's probably wrong; url() could reflect dynamic changes
too. Although I'm not sure what our story in general is for dynamic
changes to resource documents (e.g., separate documents containing
SVG filters, etc.) or for when the resource is in the same document.
There generally aren't any, since such documents can't be reached from
script and can't run script themselves. The only dynamic change that
can happen is "resource document finished loading, so the thing we're
pointing to might actually exist now".
> or for when the resource is in the same document.
That works with dynamic changes.
-Boris
Actually if you enable SMIL I think animations will run in external
resource documents. This is probably what we want.
Rob
The problem with using a full URI here is that you can't then use this
from a stylesheet to refer to an element in the main document. #id would
refer to an element in the stylesheet, which makes no sense and would
have to be ignored.
The code in my branch uses url() syntax and special-cases #id to refer
to an element in the main document, but that feels dirty. Having
mozSetImageElement interfere with the interpretation of url()s feels
even dirtier.
Another problem is that if you write url(foo.svg#a) then browsers that
support SVG images today will display foo.svg. Changing that to display
just part of foo.svg is an interop issue. Also, the SVG WG had their own
ideas about using the fragment identifer to display a subregion of the
image in a different way, although I'm not sure if those ideas are still
on the table.
Rob
Hmm. That doesn't affect most of what I was thinking (which was "which
node is the paint server"), right? You can't animate @id.
We'll have to figure out a way to invalidate the resource document
consumers on animation in the resource document, though.
-Boris
That should already work using the existing notification mechanisms.
Rob
Sorry to pick up an old thread.
Is window.mozSetImageElement("foo", node) equivalent to
node.style.backgroundImage = "-moz-element(#foo);"?
Also, why do we use a string to specify the source element as opposed to
the destination element?
-Ryo
No. Calling mozSetImageElement("foo", xyz) means that from now on
-moz-element(#foo) will render element xyz instead of whatever element
has ID "foo".
> Also, why do we use a string to specify the source element as opposed to
> the destination element?
I'm not sure what you mean.
Rob