Feature detection of absolute url images inside foreignObject

891 views Asked by At

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>
2

There are 2 answers

2
Zaheer Ahmed On

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.

4
Robert Longson On
  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);