Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Script to detect buggy IndexedDB implementations
(function (name, definition, global) {
if (typeof define === 'function') {
define(definition);
} else if (typeof module !== 'undefined' && module.exports) {
module.exports = definition();
} else {
global[name] = definition();
}
})('detectIDB', function () {
var detectIDB = function (onResult, dbName) {
if (typeof onResult != 'function') {
throw new Error('No result handler given.');
}
dbName = dbName || '__detectIDB_test';
var env = typeof window == 'object' ? window : self;
var idb = env.indexedDB || env.webkitIndexedDB || env.mozIndexedDB;
var keyRange = env.IDBKeyRange || env.webkitIDBKeyRange || env.mozIDBKeyRange;
// IE detection idea found at http://stackoverflow.com/a/26779525
try {
keyRange.only([1]);
} catch (e) {
onResult(detectIDB.IE);
return;
}
// Safari detection by Nolan Lawson: http://bl.ocks.org/nolanlawson/raw/c83e9039edf2278047e9/
var openRequest = idb.open(dbName, 1);
openRequest.onupgradeneeded = function (evt) {
var db = evt.target.result;
db.createObjectStore('one', {
keyPath: 'key'
});
db.createObjectStore('two', {
keyPath: 'key'
});
};
openRequest.onsuccess = function (evt) {
var db = evt.target.result;
var transaction;
try {
transaction = db.transaction(['one', 'two'], 'readwrite');
} catch (e) {
onResult(detectIDB.SAFARI);
return;
}
transaction.oncomplete = function () {
db.close();
onResult(detectIDB.COMPATIBLE);
};
};
};
detectIDB.COMPATIBLE = 'compatible';
detectIDB.IE = 'IE';
detectIDB.SAFARI = 'Safari';
return detectIDB;
}, this);
<!DOCTYPE html>
<title>Detecting buggy IndexedDB implementations</title>
<script type="text/javascript" src="detectIDB.js"></script>
<script type="text/javascript">
detectIDB(function (result) {
switch (result) {
case detectIDB.COMPATIBLE:
alert('IndexedDB fully compatible!');
break;
case detectIDB.IE:
alert('This is an IE, some features are missing.');
break;
case detectIDB.SAFARI:
alert('This is a Safari, there are bugs in this implementation.');
break;
}
});
</script>
@dumbmatter

I'm using a modified version of this (sorry for all the inconsequential changes, that's why I didn't just fork it, maybe someone else wants to make a nicer minimal change), and I just updated it to also detect https://bugs.webkit.org/show_bug.cgi?id=158833 in Safari 10:

var goodIDB = function (cb) {
  if (typeof window.indexedDB === "undefined") {
    cb(false);
    return;
  }

  var idb = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;
  var keyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.mozIDBKeyRange;

  try {
    keyRange.only([1]);
  } catch (e) {
    cb(false);
    return;
  }

  var openRequest = idb.open('__detectIDB_test2', 1);

  openRequest.onupgradeneeded = function (evt) {
    var db = evt.target.result;
    var one = db.createObjectStore('one', {
      autoIncrement: true,
      keyPath: 'key'
    });
    one.createIndex('one', 'one');
    one.add({one: 1});
    var two = db.createObjectStore('two', {
      autoIncrement: true,
      keyPath: 'key'
    });
    two.createIndex ('two', 'two');
    two.add({two: 2});
  };

  openRequest.onsuccess = function (evt) {
    var db = evt.target.result;
    var transaction;
    try {
      transaction = db.transaction(['one', 'two'], 'readwrite');
    } catch (e) {
      cb(false);
      return;
    }

    var count = 0;
    transaction.objectStore('one').index('one').openCursor().onsuccess = function (evt) {
      cursor = evt.target.result;
      if (cursor) {
        count += 1;
        cursor.continue();
      }
    };

    transaction.oncomplete = function () {
      db.close();
      cb(count === 1); // Will be 2 in Safari 10 https://bugs.webkit.org/show_bug.cgi?id=158833
    };
  };
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment