Open Bug 789249 Opened 12 years ago Updated 7 months ago

When rendering a SVG to canvas background-images in a foreignObject HTML are not rendered

Categories

(Core :: SVG, defect)

14 Branch
x86
macOS
defect

Tracking

()

REOPENED

People

(Reporter: christoph.burgmer, Unassigned)

References

Details

Attachments

(3 files)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1 Steps to reproduce: I am rendering an HTML document inside an SVG as foreignObject to a canvas. The HTML document includes a CSS background-image declaration (using dataURI for web security reasons). Actual results: The background image is never rendered unless the image is loaded as a background image in the surrounding page (the one that holds the canvas) independently. See the attached test case (or https://gist.github.com/3660040). Expected results: The background image should always be rendered to the canvas.
Attachment #658975 - Attachment mime type: text/plain → text/html
You wait for the svg to load but not the background image. I suspect you'll need to preload the background image (since you can't catch an onload event on it directly) so that you know it's rendered before you convert to canvas. I don't think what you're doing can be expected to work as-is and this is likely invalid as a bug.
It took me some time to process your answer but I think I understand. :) However, what loading has to be done then in addition as the image is already available as dataURI? And is there really no way to catch that?
You could try prepopulating the image. i.e. load the image data uri into an Image then continue processing when it's loaded. function OnImageLoaded (img) { ... your code runs here once the image is loaded into an Image element. } function PreloadImage (src) { var img = new Image (); img.onload = function () {OnImageLoaded (this)}; img.src = src; } PreloadImage (data uri);
Loading of all URIs is asynchronous in gecko. That's compliant with the various specifications involved even for data URIs.
Yes, I will try that. Another thought, even using setTimeout() to defer the rendering with drawImage doesn't help. The hope here is that after some time all the elements are now loaded. I guess that's because the content of the SVG is only loaded once it is going to be shown somewhere? Although, doing the img.src = THE_SVG should trigger that, or should it?
Images are loaded whether they are being shown or not. It could be that there's some other bug happening too, but to see that you'd need to fix the issue I pointed out first.
Here's my try to preload background-images through an image. I might be missing something, but in the current state it doesn't work. Worse, even the workaround wouldn't work anymore.
Attachment #659329 - Attachment mime type: text/plain → text/html
I think we should delay the load event for an SVG image until the load event for the SVG image document itself has fired (which would be delayed by the load of the data: URIs, in this case). Robert, do you want to try that?
I'm not sure what you mean. We've got an html background image on a <div> which is inside a <foreignObject>. We draw the whole lot to canvas and the html background image has gone. If I wait for all images of any type to load before firing an onload I think that's basically implementing externalResourcesRequired - bug 277955 What the modified testcase does is load the background image into a javascript Image object and wait for that to load but even that doesn't work so perhaps it's not a timing issue at all.
I don't know whether this observation helps, but in some other context just loading the background-image in a div connected to the document isn't enough. Best results, though still indeterministic, are reached by attaching the rendered SVG to the DOM. The report here for background-image seems to hold equally true for webfonts embedded in data: URIs.
The testcase builds an SVG image as a data: URI, sets it as the source of an Image, waits for that Image to fire its "load" event, then paints it to the canvas. What I'm saying is that the Image should not fire its "load" event until all the images in the internal document for the SVG image have finished loading. In other words, an SVG image has not finished loading until the load event has fired on its internal document.
Component: Untriaged → SVG
Product: Firefox → Core
We should do that if externalResourcesRequired is set. But we don't yet support externalResourcesRequired and it's due to be replaced by something else in SVG 2. It might be worth waiting to see what that replacement looks like.
I don't think this behavior needs to depend on externalResourcesRequired, especially since the resource in question is a CSS background image. I think it's quite natural for the "load" event of an SVG image to depend on the "load" event of its document. It matches the behavior for an SVG <iframe> or <object>, whose "load" event is delayed until the "load" event of the subdocument has fired.
Does the onload event in html documents i.e. on the body element wait for image loading?
Perhaps it doesn't need to as it can't be used as an image.
(In reply to Robert Longson from comment #14) > Does the onload event in html documents i.e. on the body element wait for > image loading? Yes!
This issue doesn't exist under Firefox 17.0.1. Neither is background image rendering fragile nor is the workaround still needed. From my part this issue can be closed as "FIXED".
Excellent, we use WORKSFORME when we don't know why something works and FIXED if we do know what bug fixed it.
Status: UNCONFIRMED → RESOLVED
Closed: 12 years ago
Resolution: --- → WORKSFORME
I can reproduce it on Firefox 52.0.2, Ubuntu 16.04. (https://gist.github.com/flapenguin/5503b96e235c2a8fc1197ff634eba7bc) First render does nothing, but all following renders (simply refresh the page) will render correctly. "reproduce" button will "generate" completely new image by adding 3 dummy zero bytes to end of data uri, which will make render do nothing again. Adding immediate timeout doesn't fix the problem, looks like onload firing way too early.
Status: RESOLVED → REOPENED
Ever confirmed: true
Resolution: WORKSFORME → ---

I know this bugreport is quite old, but I seem to have run into the issue when painting larger images. I was wondering if this was ever confirmed as being fixed - tying the onload of the document inside the SVG to the onload of the image.

I also know this is an old bug, but it just happened to me in Nightly 99.0a1, so i think its not fixed yet?

Severity: normal → S3
Duplicate of this bug: 1844414

:longsonr, is there any chance to see this bug fixed soon ?

Flags: needinfo?(longsonr)

I have no plans to work on it and given it's 11 years old I guess neither does Mozilla. Perhaps you can raise its internal priority in Mozilla and get someone like Henri Sivonen to look at it given that its about when the load event is fired by the parser.

Flags: needinfo?(longsonr)

:hsivonen, could you have a look on this bug please ?

Flags: needinfo?(hsivonen)

Noted as a parser item that needs a look, but clearing needinfo for now due to other priorities.

Flags: needinfo?(hsivonen)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: