data-uri test does not take into account IE8 32KB limit #321

Closed
alastaircoote opened this Issue Jul 13, 2011 · 7 comments

Projects

None yet

4 participants

@alastaircoote

IE8 will only load images provided in base 64 URIs if they are 32KB or less in length. I wrote a replacement function that test for this:

(function(){
  var datauri = new Image();

  datauri.onerror = function() {
      Modernizr.addTest('datauri', function () { return false; });
  };  
  datauri.onload = function() {
      Modernizr.addTest('datauri', function () { return (datauri.width == 1 && datauri.height == 1); });
  };

  var base64str = "R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="
  while (base64str.length < 33000) {
    base64str = "\r\n" + base64str;
  }
  datauri.src= "data:image/gif;base64," + base64str;

})();

But I'm not sure what the prevailing wisdom is about what constitutes a 'pass' on this test.

@paulirish
Member

I would recommend doing something like...

(function(){


  var datauri = new Image();

  datauri.onerror = function() {
      Modernizr.datauri.over32kb = false;
  };  
  datauri.onload = function() {
      Modernizr.datauri = Boolean(true);
      Modernizr.datauri.over32kb = (datauri.width == 1 && datauri.height == 1);
  };

  if (!Modernizr.datauri) return datauri.onerror(); 

  var base64str = "R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="
  while (base64str.length < 33000) {
    base64str = "\r\n" + base64str;
  }
  datauri.src= "data:image/gif;base64," + base64str;

})();

so we'd keep the earlier test and just add a secondary aspect onto it.. yah?

@alastaircoote

Sounds good to me. I'd imagine the datauri stuff is still very relevant for icons, etc. that are under 32KB in size, so it would be great to keep both tests.

@stereobooster
Contributor

Why do you want to use Boolean(true). {} is truthy anyway

@paulirish
Member

Because the former is also == true

@paulirish
Member

Hmm.. so @alastaircoote i'd love your help here.. I got this far, but in Chrome (at least), the onload/error handlers arent firing after i set the big img src in.

here's the new combo code:

// data uri test.
// github.com/Modernizr/Modernizr/issues/14

// This test is asynchronous. Watch out.


// in IE7 in HTTPS this can cause a Mixed Content security popup.
//   github.com/Modernizr/Modernizr/issues/362
// To avoid that you can create a new iframe and inject this.. perhaps..

(function(){

  var datauri = new Image();


  datauri.onerror = function() {
      Modernizr.addTest('datauri', false );
  };
  datauri.onload = function() {
      Modernizr.addTest('datauri', (datauri.width == 1 && datauri.height == 1));
      testOver32kb();
  };

  datauri.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";


  // once we have datauri, let's check to see if we have datauri over 32kb. IE8 doesn't.
  // github.com/Modernizr/Modernizr/issues/321
  // this is doubly asynchronous.
  function testOver32kb(){

    datauri.onerror = function() {
        Modernizr.datauri.over32kb = false;
    };
    datauri.onload = function() {
        Modernizr.datauri = Boolean(true);
        Modernizr.datauri.over32kb = (datauri.width == 1 && datauri.height == 1);
    };

    if (!Modernizr.datauri) return datauri.onerror();

    var base64str = "R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
    while (base64str.length < 33000) {
      base64str = "\r\n" + base64str;
    }
    datauri.src= "data:image/gif;base64," + base64str;
  }

})();


@sindresorhus
Member
@alastaircoote

Apologies for the extreme delay in replying to this- somehow I missed the previous notification, I think my GitHub notifications were set up wrong.

@paulirish, the problem appears to be reusing the datauri object. Creating a new Image object (datauriBig) appears to work:

// once we have datauri, let's check to see if we have datauri over 32kb. IE8 doesn't.
  // github.com/Modernizr/Modernizr/issues/321
  // this is doubly asynchronous.
  function testOver32kb(){

    var datauriBig = new Image();
    datauriBig.onerror = function() {
        Modernizr.datauri.over32kb = false;
    };
    datauriBig.onload = function() {
        Modernizr.datauri = Boolean(true);
        Modernizr.datauri.over32kb = (datauri.width == 1 && datauri.height == 1);
    };

    if (!Modernizr.datauri) return datauri.onerror();

    var base64str = "R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
    while (base64str.length < 33000) {
      base64str = "\r\n" + base64str;
    }
    datauriBig.src= "data:image/gif;base64," + base64str;
  }
@stucox stucox added a commit to stucox/Modernizr that closed this issue Mar 24, 2013
@stucox stucox Updated datauri test to blacklist IE7 (to avoid HTTPS warnings) and t…
…o include a `.datauri.over32kb` aspect (fixes #321)
97ecfa0
@patrickkettner patrickkettner pushed a commit to patrickkettner/Modernizr that referenced this issue Feb 22, 2015
@stucox stucox Updated datauri test to blacklist IE7 (to avoid HTTPS warnings) and t…
…o include a `.datauri.over32kb` aspect (fixes #321)
f273bdc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment