Feature detection of absolute url images inside foreignObject
Asked Answered
S

2

9

After a little research i discovered that Chrome and Opera render images inside a foreignObject if they have an absolute path, Firefox renders images only if they are in data-uri format because it does not load any external resource.

I've tried several methods but i cannot find a way to feature-detect this behaviour, for example i've tried to check the dimensions of the image in the foreignObject but they are always right, Firefox simply draws a transparent rectangle with the same image size.

Do you know how to do this?

CODE This situation is hard to reproduce, but you can test it in this way:

  • Go to google homepage
  • Open firebug console or javascript console on Chrome
  • execute this code:

:

var img = new Image();

img.src="data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPSc1MzgnIGhlaWdodD0nMTkwJz48Zm9yZWlnbk9iamVjdCB3aWR0aD0nMTAwJScgaGVpZ2h0PScxMDAlJz48aW1nIHNyYz0iaHR0cHM6Ly93d3cuZ29vZ2xlLml0L2ltYWdlcy9zcnByL2xvZ28xMXcucG5nIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgc3R5bGU9Im1hcmdpbjogMHB4OyIvPjwvZm9yZWlnbk9iamVjdD48L3N2Zz4=";

document.body.appendChild(img);

on Chrome the logo image is visible, on Firefox it isn't. The svg code is base64 encoded, this is the original code:

<svg xmlns="http://www.w3.org/2000/svg" width="538" height="190">
<foreignObject width="100%" height="100%">
<img src="https://www.google.it/images/srpr/logo11w.png" xmlns="http://www.w3.org/1999/xhtml" style="margin: 0px;">
</foreignObject>
</svg>
Squire answered 25/12, 2013 at 11:39 Comment(1)
Could you please provide some sample code?Fenton
D
1

If user agent(browser) support is not available for this feature you may use fall back technique, So if a browser does not support this feature will render 'No foreign Object supported':

<switch>
  <g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" requiredExtensions="http://www.w3.org/1999/xhtml">
    <foreignObject >
    </foreignObject>
  </g>
  <text font-size="10" font-family="Verdana">
     No foreign Object supported
  </text>
</switch>

Or if you want to detect it in JavaScript, simplest you can try:

if(typeof SVGForeignObjectElement !== 'undefined')
   alert('It support feature');

or you can use hasFeature

var flag= document.implementation.hasFeature("feature","version");

Parameters

feature Is a DOMString representing the feature name.

version Is a DOMString representing the version of the specification defining the feature.

Dempstor answered 30/12, 2013 at 9:37 Comment(2)
hasFeature returns true for foreignObject elements in Firefox, Opera and Webkit. typeOf will return true too as foreignObject is a supported element in all those UAs.Carpetbagger
The problem is not to check the support for the foreignObject, i know how to do that and both Chrome and Firefox support it. I want to know how to check if the foreignObject loads absolute-url images or not. I thought about using hasFeature but what feature i have to check? I haven't found anything that solves my problemSquire
C
0
  1. Construct an SVG file with a <foreignObject> tag in it which links to an external png or gif image. Probably easier if the image has a single colour.
  2. Load the image using a HTML <img> tag e.g. <img id="imgRect" style="display:none" width="100" height="50" src="test.svg">
  3. Copy the image into canvas
  4. When the image has loaded, read off the colour from the canvas at the location you expect to see the external png displayed

This will work on Firefox as it doesn't taint the canvas and make it write-only when an SVG image is loaded into it. I'm not sure whether Chrome still taints the canvas, if it does then step 4 will fail.

Here's some code for step 3.

var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext("2d");
var img = document.getElementById("imgRect");
ctx.drawImage(img, 0, 0);
Carpetbagger answered 1/1, 2014 at 15:54 Comment(4)
As you already said Chrome can't access image data on a canvas that contains an SVG image because it will be tainted so the test will work only on Firefox that is the only browser that doesn't load external images and the test will fail anyway, so the result is almost equal to user-agent sniffing for Firefox not a feature-detection.Squire
I expect Chrome to change to work like Firefox at some point, there are open chromium bugs on that. Firefox won't change, it will always work like this.Carpetbagger
That's a lot of overhead, just to detect a feature.Brann
Indeed it is, but that's what the OP asked for. Obviously you'd do it once per session and cache the result in a cookie or something.Carpetbagger

© 2022 - 2024 — McMap. All rights reserved.