Closed Bug 587585 Opened 14 years ago Closed 14 years ago

SVG effects on anonymous XBL elements referring to an element in a different document always tries to load that document as an external resource

Categories

(Core :: XBL, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla2.0b8
Tracking Status
blocking2.0 --- beta8+

People

(Reporter: mstange, Assigned: mstange)

References

Details

Attachments

(1 file, 1 obsolete file)

Attached patch proposed patch (obsolete) — Splinter Review
In bug 547787 I'm trying to use a mask on an anonymous XBL element. The binding that defines this element is in tabbrowser.xml and the element that the binding applies to is in browser.xul. The current code in nsReferencedElement::Reset allows two places for the mask to live in: Either it needs to be in tabbrowser.xml as anonymous content inside the binding, or it needs to be in an external resource document.
Both options are bad: Having it inside the binding would mean that lots of identical SVG frames are created for every tab. Having it in an external resource document would mean that the mask will be applied very late and will cause an additional repaint, thus regressing performance (see bug 546262).

Ideally we'd be able to host the mask inside browser.xul. But that doesn't work with the current code in nsReferencedElement::Reset: "documentURL" will point to tabbrowser.xml and "url" to browser.xul, so we'll try to load browser.xul as an external resource document, and that doesn't work.

Is this by design? It seems like a bug to me.

Incidentally this also also means that -moz-element on anonymous XBL elements doesn't work at all due to the way we choose the URL in ImageRenderer::PrepareImage().

I've attached a patch that implements how I think it should work.
Roc/sicking: Could one of you review the patch or should I wait for bz to return?

I'll write tests once we agree on the correct behavior.
Attachment #466260 - Flags: feedback?(bzbarsky)
See bug 406564 and bug 406566. Is one of those a duplicate of this?
Both are different from this bug as far as I can tell. Bug 406564 asks whether the loop over anonymousChildren should exclude elements from the bound document which are inserted by <children/>, and bug 406566 wants that loop to additionally include elements inside the binding's <resources> element (and to have SVG frames created for them, I guess). So they're both about referenced elements *inside* the binding, while this bug is about elements *outside* the binding.
My (limited) understanding of XBL2 is that the bindings document is considered "the document" that the bindings belong to, and ID-references in the bindings would not normally be resolved to elements in the bound document.

It seems to me that we could make URIs where the non-fragment part of the URI is the URI of the bound document refer to the bound document (instead of an external resource document with the same URI as the bound document). That would work for you, right?
It would, and I think that's what the patch does.
(In reply to comment #0)
> Ideally we'd be able to host the mask inside browser.xul.

Not quite. It's theme-specific code, so ideally it would be a resource in the theme without notably degrading perf.
I agree, that would be even better.

We'll still need this patch to make -moz-element on anonymous elements work.
Comment on attachment 466260 [details] [diff] [review]
proposed patch

Doesn't this break the "as anonymous content inside the binding" use case?  And don't we have tests covering that?  And don't they fail with this patch?

Specifically, I don't see when EqualExceptRef(url, bindingDocumentURL) would ever test true.
Attachment #466260 - Flags: feedback?(bzbarsky) → feedback-
(In reply to comment #8)
> Specifically, I don't see when EqualExceptRef(url, bindingDocumentURL) would
> ever test true.

In the same cases as before, I'd think. With the old code the check was "EqualExceptRef(url, documentURL)", after documentURL had been set to binding->PrototypeBinding()->DocURI(). Now binding->PrototypeBinding()->DocURI() is stored in bindingDocumentURL.

Anyway, I'll create a testcase and double-check if it still works. I haven't run tests yet because I wanted your feedback on the approach first.
> after documentURL had been set to binding->PrototypeBinding()->DocURI().

Oh, hmm.  I clearly need to reread that logic again.  I don't understand why that code was doing what it's doing, though, unless the relevant URIs for elements coming from XBL are converted to absolute form _before_ adoption into the bound document....  I guess that must be happening.  And the urls you're using are not resolved relative to the XBL document, I take it?

The idea of having XBL anon content lift resources from the bound document is really odd, to me.  Would it make more sense to do sync-loading of external resources that are local or something (ugh)?
(In reply to comment #10)
> And the urls you're
> using are not resolved relative to the XBL document, I take it?

I'm not sure which URLs you mean. The mask I'm using has "mask: url(chrome://browser/content/browser.xul#tab-left-curve-mask)" set on it. The -moz-element URL is constructed here: http://mxr.mozilla.org/mozilla-central/source/layout/base/nsCSSRendering.cpp#3748

> The idea of having XBL anon content lift resources from the bound document is
> really odd, to me.

I'd agree if we were talking about a CSS stylesheet that only applies to a binding. But in this case we're talking about browser.css, which is a stylesheet for bound document (browser.xul) that just happens to also style anonymous content inside the tabs.

> Would it make more sense to do sync-loading of external
> resources that are local or something (ugh)?

"Ugh", right. Or start the loads to them at style resolution and have them block the document load event, just like images. (Or if that's not how they work, do whatever images do.)

But that still wouldn't address the -moz-element issue. The use case there is that I want to this: document.mozSetImageElement("active-personas-image", img) on the browser.xul document and then have anonymous content inside the tabs use it.
> I'm not sure which URLs you mean.

Whatever urls are going into this function.  Sounds like you're using an absolute URI, so the "resolved relative to ..." part doesn't apply at all.

> But in this case we're talking about browser.css

Right.  Fundamentally, the problem is that there's conflation of URIs and id-refs here...  Ah, well.

> Or start the loads to them at style resolution

I wonder what the impact of this would be... Might be worth doing.

> and have them block the document load event

I believe external resources already do this, if their loads start before the load event fires.

> But that still wouldn't address the -moz-element issue.

Yes.  It's not clear to me whether that should work... It seems to be seriously violating the compartmentalization that XBL is supposed to provide.
(In reply to comment #11)
> > Would it make more sense to do sync-loading of external
> > resources that are local or something (ugh)?
> 
> "Ugh", right. Or start the loads to them at style resolution and have them
> block the document load event, just like images. (Or if that's not how they
> work, do whatever images do.)

See bug 546262 comment 6.

> But that still wouldn't address the -moz-element issue.

Maybe this bug's summary should be changed. As mentioned and agreed upon earlier, we don't really want theme specific SVG masks in browser.xul.
(In reply to comment #12)
> > Or start the loads to them at style resolution
> 
> I wonder what the impact of this would be... Might be worth doing.

Would you mind writing a patch that does this (in bug 546262)? I'm afraid my time for doing these things in the near future is running out fast.

> > and have them block the document load event
> 
> I believe external resources already do this, if their loads start before the
> load event fires.

I see.

> > But that still wouldn't address the -moz-element issue.
> 
> Yes.  It's not clear to me whether that should work... It seems to be seriously
> violating the compartmentalization that XBL is supposed to provide.

I don't really have an opinion on this. All I need is some way of doing what I want appearance-wise. In this case it means I have to place a tab-shaped cut-out of the active personas image behind the active tab, and the current implementation approach I have in mind requires masks and -moz-element on anonymous content. I'm happy to change approaches as long as it works.

However, I don't understand what we would gain by disallowing the usages I'm proposing here. We don't break anything, we only make cases work that didn't work before, don't we?
> We don't break anything

We sort of do.  We make reusable widgets (XBL) suddenly depend on the place they're included.

The ideal thing would be if we kept track of where a style is coming from and based where we look for the element on that.  So a browser.css style applied to an anon node of a binding attached to an element in browser.xul would look in browser.xul.  But style coming from inside the binding would look inside the binding.  That's way outside the scope of this bug, though...  Might be good to file a followup on being able to do this.  It'd involve storing more data in the style structs (e.g. a CSSValue::URI instead of nsIURI), but should be totally doable.
(In reply to comment #15)
> That's way outside the scope of this bug, though... 

OK, what should we do in this bug, then?
Well, a good start is addressing the issues Dao had, right?
You mean fixing bug 546262? And how should we fix -moz-element?
I guess we should take the original patch in this bug for now, given the schedule situation, to fix -moz-element, and file a followup to do it right...
Okay, I'll start running and writing tests now.
blocking2.0: --- → ?
Attachment #466260 - Attachment is obsolete: true
Attachment #474794 - Flags: review?(bzbarsky)
I'm having a hard time coming up with good arguments for why this would block 2.0, marking blocking-, but if you disagree please renominate with reasoning why this has to be fixed for 2.0.
blocking2.0: ? → -
Bug 547787 is blocking, and the patch over there doesn't work without the patch in this bug.

Boris, when do you think you'll get to the review?
blocking2.0: - → ?
beta8+ per comment 23.
blocking2.0: ? → beta8+
Comment on attachment 474794 [details] [diff] [review]
same patch but with tests

r=me
Attachment #474794 - Flags: review?(bzbarsky) → review+
http://hg.mozilla.org/mozilla-central/rev/889a05b6dc87
Status: ASSIGNED → RESOLVED
Closed: 14 years ago
Flags: in-testsuite+
Resolution: --- → FIXED
Target Milestone: --- → mozilla2.0b8
"The most common grafxbot failure with 4.0b8/4.0b9pre is that in the test
== mask-html-xbl-bound-01.html mask-html-01-ref.svg
the test file is rendered as a blank page. This happens on all OS's."

See bug 622717.
Depends on: 622717
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: