Re: [css-masking] 'mask' with resource and image references (was: [css4-images] support for SVG Paint Servers without element())

On Wed, Nov 7, 2012 at 1:43 PM, Dirk Schulze <dschulze@adobe.com> wrote:
> On Nov 7, 2012, at 1:32 PM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
>> On Wed, Nov 7, 2012 at 1:26 PM, Dirk Schulze <dschulze@adobe.com> wrote:
>>> On Nov 7, 2012, at 1:08 PM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
>>>> On Wed, Nov 7, 2012 at 12:45 PM, Dirk Schulze <dschulze@adobe.com> wrote:
>>>>> On Nov 7, 2012, at 10:43 AM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
>>>>>> So, 'mask-image' needs to have its grammar revised to take this into
>>>>>> account, so that it can take mask references as well.
>>>>>
>>>>> This would be the consequence, but wouldn't help IMO.
>>>>>
>>>>> mask-image: url(image#frag);
>>>>>
>>>>> It would be unclear until the processing, if this is an SVG resource or an image. However, the syntax would be valid in both cases. The problem for WebKit is, that we already assume that this will be an CSS Image and already start creating an CSSImage resource. This is incompatible with an SVG resource (because of various reasons roc already mentioned). That's why this is not an option for WebKit right now.
>>>>
>>>> Let's be precise here.  It's unclear at parse time whether you're
>>>> pointing at a <mask> element or some other paint server element like
>>>> <linearGradient>.
>>>
>>> I think you mix up some things. I am not talking about paint servers at all. I am just talking about the <mask> element for reference.
>>
>> ...I know?  My point is that url(image#frag) might also point at a
>> paint server, which is an <image>.  But it won't ever be interpreted
>> as an image file, like an SVG Stack.
>
> Well, for 'mask' I would follow CSS4 Images. If you want to use paint servers, use element().

Okay, I am very confused.  I don't know if you misunderstand the rule
we've come up with, or would like an exception for this property, or
what.

I'll lay out my understanding as simply as possible, and you can tell
me what you disagree with.

If you see "mask: url(...);", there are a priori three possiblities:

1. The url might be intending to point to an SVG <mask> element in the
indicated file.
2. The url might be intending to point to an SVG paint server element
in the indicated file.
3. The url might be intending to use the indicated file as an image.

1 needs to be distinguished from 2&3, because we treat <mask> and
<image> values differently.  If we want to have different syntax for
<mask> and for <image>, we need to distinguish them at parse time.  If
we're cool with keeping the same syntax (but possibly ignoring things
that are misplaced, like how 'transition-propery' ignores unknown
properties), we can do this distinguishing late, after having parsed
the file and figured out which one it is.  (Because it relies on a url
resolving, we shouldn't distinguish the cases until used-value time.
Computed values aren't supposed to depend on url resolution.)

1&2 need to be distinguished from 3, because loading an SVG file as an
image and loading it as an external resource go down very different
code paths in major browsers, and the decision about which code path
to take should be done as early as possible, ideally at parse time.

Roc's original proposal mutated into a simplified proposal given by
Steve Zilles and fantasai, where we can tell at parse time whether to
attempt to load a file as an image or as an external resource based on
the presence/absence of a hash.  For most properties that can take
url() <image>, url() is always loaded as an image file, regardless.
For a handful of SVG properties, if the url has a hash, it'll be
loaded as an external resource; otherwise, loaded as an image.

'mask-image' is in that latter set.  So, when you encounter
"mask-image: url(image#frag);", we can tell at parse time that we
should load "image#frag" as an external resource, rather than as an
image.  This happens *regardless of the file's eventual type" - if it
ends up being a PNG (which can't provide an external resource), then
too bad, it's just an invalid reference.


>>>> You *do* know, at parse time, that it won't be
>>>> loading the SVG as an image, because 'mask' is on the list of
>>>> properties that default frag-urls to being a resource reference rather
>>>> than an image.
>>>
>>> You do not know that it actually is an SVG file at all. This is what I described in a previous mail:
>>
>> That doesn't matter.  The rule that we're switching to says that, *at
>> parse time*, a value like "url(image#frag)" will be an external
>> resource reference, *not* an image file.  You don't need to know what
>> type of file it is to make this distinction.  It just tells you which
>> code path to go down.
>
> This would be a mayor difference to current behavior. See below.

Only theoretically, so far.  *If* people are commonly writing
-webkit-mask-image with SVG Stacks, or PNGs with useless fragments,
then it's a problem, because the behavior I outlined above would be a
change (and would make the mask stop working).

However, I doubt both of those.  We apparently have decent evidence
that most usage of SVG Stacks is in HTML (<img>, <iframe>, etc.), not
CSS, so heavy use of them in -webkit-mask-image seems unlikely.  I
also doubt that useless fragments are commonly used on bitmap images,
in any property, so that shouldn't be much of a problem either.

Given this, it should be okay to make this minor behavior change.


>>> ""
>>> And even the fragment itself is not a good identifier, url(image.png#frag) will be an image as well. And the file ending itself can not be trusted. The file doesn't need to have a file ending at all. Therefore, the fragment alone can not be used to clarify if it is a resource or an image. That is what I meant in the mail before. The CSS Parser would need extra information about the file then just the URL.
>>> ""
>>>
>>> You would need to check the URL itself (e.g check mime type) and can't just rely on the parsing output. That is actually my point.
>>
>> No, not according to the rule we've come up with.  You can tell,
>> before you attempt to load the url, that it will be a resource
>> reference of some kind, not an image.
>>
>> The resource might end up being a CSS <image> type (if you're pointing
>> at a paint server), but that's a different story.
>
> This has nothing to do with the rule we come up. "image.png", "image.png#frag" and even "image#frag" can be PNG images, in which case the fragment doesn't matter at all. You can't make decisions depending on fragments on these files. These are no "resources" in the sense of SVG. These are images where CORS doesn't apply. You can not just say that they are resources now if they have fragments and stop displaying images. As roc said, if Gecko treats something as resource, it doesn't download it at all. Currently Gecko does for images.

As I have described above, that's fine.  This is only a problem if
there are large numbers of stylesheets writing things like
"-webkit-mask-image: url(foo.png#uselesshash);", which I doubt.
Assuming that it's okay to break whatever tiny fraction of people
might be doing this, then the effect of that code, once we define
everything properly, will just be an invalid reference.  The 'mask'
property will by syntactically valid, but won't do anything because it
couldn't resolve the file as an external resource, same as if you
write "background-image: url(foo.html);".

~TJ

Received on Wednesday, 7 November 2012 22:17:26 UTC