IndexedDB getAll in non-Firefox browsers - javascript

I am aware that IDBObjectStore.getAll is not part of the IndexedDB standard and that it might never be. But it is implemented in FireFox, and it makes your code prettier if you do have to retrieve a lot of objects from the database.
Would it be possible to make some kind of polyfill or something to allow getAll to work in other browsers that support IndexedDB? The actual functionality of getAll is simple, but I don't know how to deal with the asynchronous nature of IndexedDB in the context of replicating its precise syntax in non-Firefox browsers.

I made a GitHub repo for a shim to support getAll in other browsers, which seems to work well enough in Chrome. The code is repeated below for posterity:
(function () {
"use strict";
var Event, getAll, IDBIndex, IDBObjectStore, IDBRequest;
IDBObjectStore = window.IDBObjectStore || window.webkitIDBObjectStore || window.mozIDBObjectStore || window.msIDBObjectStore;
IDBIndex = window.IDBIndex || window.webkitIDBIndex || window.mozIDBIndex || window.msIDBIndex;
if (typeof IDBObjectStore.prototype.getAll !== "undefined" && typeof IDBIndex.prototype.getAll !== "undefined") {
return;
}
// https://github.com/axemclion/IndexedDBShim/blob/gh-pages/src/IDBRequest.js
IDBRequest = function () {
this.onsuccess = null;
this.readyState = "pending";
};
// https://github.com/axemclion/IndexedDBShim/blob/gh-pages/src/Event.js
Event = function (type, debug) {
return {
"type": type,
debug: debug,
bubbles: false,
cancelable: false,
eventPhase: 0,
timeStamp: new Date()
};
};
getAll = function (key) {
var request, result;
key = typeof key !== "undefined" ? key : null;
request = new IDBRequest();
result = [];
// this is either an IDBObjectStore or an IDBIndex, depending on the context.
this.openCursor(key).onsuccess = function (event) {
var cursor, e, target;
cursor = event.target.result;
if (cursor) {
result.push(cursor.value);
cursor.continue();
} else {
if (typeof request.onsuccess === "function") {
e = new Event("success");
e.target = {
readyState: "done",
result: result
};
request.onsuccess(e);
}
}
};
return request;
};
if (typeof IDBObjectStore.prototype.getAll === "undefined") {
IDBObjectStore.prototype.getAll = getAll;
}
if (typeof IDBIndex.prototype.getAll === "undefined") {
IDBIndex.prototype.getAll = getAll;
}
}());

Related

WebRTC-Problem: Cannot create answer in stable (no Chrome but AJAX signalizing involved)

can somebody help me out a little? I am a little stuck.
I am trying to write a signaling process with ajax and a database involved (this is just for learning the basics of WebRTC for now).
I am receiving the SDP fine from the JSON-object as it seems, but then I always get an error "Cannot create answer in stable" when I try to create an answer in get_remote_offer() for pc_partner.
I am pretty sure it is something obvious, but I am pretty new to WebRTC and just can't see what.
I am using Firefox here and just trying to connect two instances of it (one in private mode, one in "normal" mode, but I am trying to make it work for remote users.
This is my code:
var opt;
var video_el_partner;
var video_el_local;
var pc_partner;
var pc_local;
var interval_gro;
var remote_offer_available = false;
var service_url = "https://xyz.de/webrtc";
var pwd = "xxx";
var signaling_url = "https://xyz.de/webrtc/sdp_transfer.php";
function init_stream(video_partner_id, video_local_id, allow_video, allow_audio){
if (location.protocol === 'https:') { // only possible for https!
pc_local = new RTCPeerConnection();
pc_partner = new RTCPeerConnection();
if(document.getElementById(video_partner_id) != null){
video_el_partner = document.getElementById(video_partner_id);
video_el_local = document.getElementById(video_local_id);
if(allow_video == null){
allow_video = true;
}
if(allow_audio == null){
allow_audio = true;
}
opt = { audio: allow_audio, video: allow_video };
if(typeof navigator != 'undefined' && typeof navigator.mediaDevices != 'undefined' && navigator.mediaDevices.getUserMedia != null){
navigator.mediaDevices.getUserMedia(opt).then (
function (this_stream){
// local video directly into video element:
video_el_local.srcObject = this_stream;
// remote one is more insteresting:
pc_local.addStream(this_stream);
pc_local.createOffer().then(
function (this_sdp) {
// sdp (session dependend protocol object) is now available... this would need to go to a server somehow now.
// they use socket.io for that... maybe I can use my own thing to do that?
pc_local.setLocalDescription(this_sdp);
var this_sdp_json = JSON.stringify(this_sdp)
var params_ins = "mode=insert_offer&sdp_con=" + this_sdp_json + "&pass=" + pwd + "&service_url=" + service_url;
ajax_request_simple (
signaling_url,
params_ins,
function (res_ins) {
// insert done. Lets read for another candidate.
console.log('Set Interval!');
interval_gro = window.setInterval('get_remote_offer();', 5000);
}
);
}
);
}
).catch(
function (error) {
console.log('Problem: ');
console.log(error);
}
);
} else {
console.log("navgiator or navigator.mediaDevices is not defined.");
}
}
} else {
console.log('init_stream(): We can only do anything like that on https-connections! Http is not supported by the browser!');
}
}
window.onload = function () {
document.getElementById('button_start_stream').onclick = function () {
init_stream('video_partner', 'video_local', true, false);
}
}
function is_json_str(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
function get_remote_offer() {
var params_read = "mode=get_offer&pass=" + pwd + "&service_url=" + service_url;
ajax_request_simple (
signaling_url,
params_read,
function (res_read) {
// done.
if(is_json_str(res_read)){
// seems like we get one now.
// lets use that to connect and stream the video to the remote view.
var partner_offer = res_read;
partner_offer = JSON.parse(partner_offer);
// clear interval if found.
window.clearInterval(interval_gro);
console.log('Cleared Interval. Found!');
pc_local.setRemoteDescription(
new RTCSessionDescription(partner_offer), function(){
// video_el_partner.srcObject = event.stream;
pc_local.onicecandidate = function (e) {
if ( e.candidate != null ) {
pc_partner.addIceCandidate( new RTCIceCandidate(e.candidate) );
}
};
pc_partner.onicecandidate = function (e) {
if ( e.candidate != null ) {
pc_local.addIceCandidate( new RTCIceCandidate(e.candidate) );
}
};
pc_partner.createAnswer(
function (offer) {
pc_local.setRemoteDescription(offer);
pc_partner.setLocalDescription(offer);
}
);
// pc_local.ontrack = function (evt) {
// video_el_local.srcObject = evt.stream;
// };
pc_partner.ontrack = function (evt) {
video_el_partner.srcObject = evt.stream;
};
},
function(e) {
console.log("Problem while doing client-answer: ", e);
}
);
} else {
console.log("Can not parse: ");
console.log(res_read);
}
}
);
}
Sorry for the mix of promises and callbacks... I tried a couple of things out just in case... when it is working I will rewrite the callback parts.
Thank you very much in advance for any hint you can give me :).
Best regards and thanks for reading till now ;).
Fuchur

Call functions from sources directly in Chrome console?

For a website there is this function under sources with the code:
betSlipView.prototype.stakeOnKeyUp = function(_key) {
var model = ob.slip.getModel(),
defval = ob.cfg.default_bet_amount;
selector = toJqId(["#stake-", _key].join('')),
stake_box = $(selector),
spl = stake_box.val();
if(spl != defval) {
spl = ob.slip.cleanFormatedAmount(spl);
if(spl === '' || isNaN(spl)) {
spl = 0;
$(selector).val('');
}
model.setBetStake(_key, spl);
$(toJqId(['#ob-slip-estimate-', _key].join(''))).html(
model.getBet(_key, 'pretty_returns')
);
} else {
$(selector).val(defval);
model.setBetStake(_key, defval);
$(toJqId(['#ob-slip-estimate-', _key].join(''))).html(
model.getBet(_key, 'pretty_returns')
);
}
//Update bonus amount
try {
var offers = model.getBet(_key, 'offers');
}
catch(err) {
var offers = "";
}
if(offers !== "" && typeof offers['STLWIN'] !== "undefined") {
this._handleAccumulatorBonusElements(_key, offers['STLWIN']);
};
// potential returns for this bet
this.updateTotals();
};
I cannot figure out how to (if possible) call this function directly from the console. Firstly, when I try to write betSlipView in the console, it cannot be found. Consequently if I copy the code to the console to define the function, betSlipView is still not found and if I try to change the function name, there are some names in the function body that cannot be found either. I wish to call this function with certain arguments, is this possible?
The whole code can be found here https://obstatic1.danskespil.dk/static/compressed/js/ob/slip/crunched.pkg.js?ver=0305f181cb96b61490e0fd2adafa3a91

How to copy the objects from chrome console window?

I have tried to copy the objects as text, but it show just [object object]. Before this I had tried with copy commend it was success but not now.Is that chrome issue?
What I tried?
Just Right click on the object and store as global variable from chrome console window, then next just used copy(temp6) command and tried to paste in notepad++.
It should ideally copy the object with the copy command that you wrote.
I just tried it and worked for me.
Something else that you can try to do is to stringify that object and then copy it.
Ex.
copy(JSON.stringify(temp6))
If the object already logged
Right-click on the object in console and click Store as a global
variable the output will be something like temp1
Copy and paste below code in chrome console and hit enter
(function(console){
console.save = function(data, filename){
if(!data) {
console.error('Console.save: No data')
return;
}
if(!filename) filename = 'console.json'
if(typeof data === "object"){
data = JSON.stringify(data, undefined, 4)
}
var blob = new Blob([data], {type: 'text/json'}),
e = document.createEvent('MouseEvents'),
a = document.createElement('a')
a.download = filename
a.href = window.URL.createObjectURL(blob)
a.dataset.downloadurl = ['text/json', a.download, a.href].join(':')
e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
a.dispatchEvent(e)
}
})(console)
Then you can use the function for downloading,
console.save(temp1);
-If it shows Uncaught TypeError: Converting circular structure to JSON
then you need decycle JSON object and paste below code in chrome browser console and hit enter
if (typeof JSON.decycle !== "function") {
JSON.decycle = function decycle(object, replacer) {
"use strict";
var objects = new WeakMap(); // object to path mappings
return (function derez(value, path) {
var old_path;
var nu;
if (replacer !== undefined) {
value = replacer(value);
}
if (
typeof value === "object" && value !== null &&
!(value instanceof Boolean) &&
!(value instanceof Date) &&
!(value instanceof Number) &&
!(value instanceof RegExp) &&
!(value instanceof String)
) {
old_path = objects.get(value);
if (old_path !== undefined) {
return {$ref: old_path};
}
objects.set(value, path);
if (Array.isArray(value)) {
nu = [];
value.forEach(function (element, i) {
nu[i] = derez(element, path + "[" + i + "]");
});
} else {
nu = {};
Object.keys(value).forEach(function (name) {
nu[name] = derez(
value[name],
path + "[" + JSON.stringify(name) + "]"
);
});
}
return nu;
}
return value;
}(object, "$"));
};
}
if (typeof JSON.retrocycle !== "function") {
JSON.retrocycle = function retrocycle($) {
"use strict";
var px = /^\$(?:\[(?:\d+|"(?:[^\\"\u0000-\u001f]|\\([\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*")\])*$/;
(function rez(value) {
if (value && typeof value === "object") {
if (Array.isArray(value)) {
value.forEach(function (element, i) {
if (typeof element === "object" && element !== null) {
var path = element.$ref;
if (typeof path === "string" && px.test(path)) {
value[i] = eval(path);
} else {
rez(element);
}
}
});
} else {
Object.keys(value).forEach(function (name) {
var item = value[name];
if (typeof item === "object" && item !== null) {
var path = item.$ref;
if (typeof path === "string" && px.test(path)) {
value[name] = eval(path);
} else {
rez(item);
}
}
});
}
}
}($));
return $;
};
}
Then finally execute code for downloading.
console.save(JSON.decycle(temp1));
You can use command in console as follows:
Let say our object is:
var object = {x:"xyz"}
Now use below command in console -
copy(JSON.stringify(object))
object is now available to clipboard.You can now use Ctrl + v to use this object.
You should check thecount object to avoid circular reference, before using copy(JSON.stringify(count)), please see here
there can be many ways to do this. One way could be to do JSON.stringify(yourObject) and then copy the output.
You can also do this without having to write any code. At least with later version of chrome.
When you right click the object you get this context:
But if you left click the line to highlight it, the right click the console line you get this context menu:
The "Save as..." option will create text file (*.log) of everything "as is" currently on the console log. So if you want to see more of the object simply expand it as far as you need.
collapsed example:
let tmpArr = []; tmpArr.push([]); tmpArr[0].push({ some: 'test'}); tmpArr[0].push({ some: 'next'}); console.log(tmpArr);
VM242:1 [Array(2)]0: (2) [{…}, {…}]length: 1[[Prototype]]: Array(0)
undefined
null
null
expanded example:
let tmpArr = []; tmpArr.push([]); tmpArr[0].push({ some: 'test'}); tmpArr[0].push({ some: 'next'}); console.log(tmpArr);
VM242:1 [Array(2)]0: Array(2)0: some: "test"[[Prototype]]: Object1: some: "next"[[Prototype]]: Objectlength: 2[[Prototype]]: Array(0)length: 1[[Prototype]]: Array(0)
undefined
null
null

How to detect if browser supports HTML5 Local Storage

The following code alerts ls exist in IE7:
if(window.localStorage) {
alert('ls exists');
} else {
alert('ls does not exist');
}
IE7 doesn't really support local storage but this still alerts it does. Perhaps this is because I am using IE9 in IE7 browser and document modes using the IE9 developer tool. Or maybe this is just the wrong way to test if LS is supported. What is the right way?
Also I don't want to use Modernizr since I am using only a few HTML5 features and loading a large script isn't worth it just to detect support for those few things.
You don't have to use modernizr, but you can use their method to detect if localStorage is supported
modernizr at github
test for localStorage
// In FF4, if disabled, window.localStorage should === null.
// Normally, we could not test that directly and need to do a
// `('localStorage' in window) && ` test first because otherwise Firefox will
// throw bugzil.la/365772 if cookies are disabled
// Also in iOS5 & Safari Private Browsing mode, attempting to use localStorage.setItem
// will throw the exception:
// QUOTA_EXCEEDED_ERRROR DOM Exception 22.
// Peculiarly, getItem and removeItem calls do not throw.
// Because we are forced to try/catch this, we'll go aggressive.
// Just FWIW: IE8 Compat mode supports these features completely:
// www.quirksmode.org/dom/html5.html
// But IE8 doesn't support either with local files
Modernizr.addTest('localstorage', function() {
var mod = 'modernizr';
try {
localStorage.setItem(mod, mod);
localStorage.removeItem(mod);
return true;
} catch(e) {
return false;
}
});
updated with current source code
if(typeof Storage !== "undefined")
{
// Yes! localStorage and sessionStorage support!
// Some code.....
}
else
{
// Sorry! No web storage support..
}
This function works fine:
function supports_html5_storage(){
try {
return 'localStorage' in window && window['localStorage'] !== null;
} catch(e) {
return false;
}
}
Source: www.diveintohtml5.info
Also I don't want to use Modernizr since I am using only a few HTML5
features and loading a large script isn't worth it just to detect
support for those few things.
To reduce Modernizr file size customize the file at http://modernizr.com/download/ to fit your needs. A localStorage-only version of Modernizr comes in at 1.55KB.
Try window.localStorage!==undefined:
if(window.localStorage!==undefined){
//Do something
}else{
alert('Your browser is outdated!');
}
You can also use typeof window.localStorage!=="undefined", but the statement above already does it
I didn't see it in the answers, but I think it's good to know that you can easily use vanilla JS or jQuery for such simple tests, and while Modernizr helps a lot, there are clean solutions without it.
If you use jQuery, you can do:
var _supportsLocalStorage = !!window.localStorage
&& $.isFunction(localStorage.getItem)
&& $.isFunction(localStorage.setItem)
&& $.isFunction(localStorage.removeItem);
Or, with pure Vanilla JavaScript:
var _supportsLocalStorage = !!window.localStorage
&& typeof localStorage.getItem === 'function'
&& typeof localStorage.setItem === 'function'
&& typeof localStorage.removeItem === 'function';
Then, you would simply do an IF to test the support:
if (_supportsLocalStorage) {
console.log('ls is supported');
alert('ls is supported');
}
So the whole idea is that whenever you need JavaScript features, you would first test the parent object and then the methods your code uses.
Try catch will do the job :
try{
localStorage.setItem("name",name.value);
localStorage.setItem("post",post.value);
}
catch(e){
alert(e.message);
}
Try:
if(typeof window.localStorage != 'undefined') {
}
if (window.localStorage){
alert('localStorage is supported');
window.localStorage.setItem("whatever", "string value");
}
Modifying Andrea's answer to add a getter makes it easier to use. With the below you simply say: if(ls)...
var ls = {
get: function () {
var test = 'test';
try {
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
} catch(e) {
return false;
}
}
};
var ls = {
get: function () {
var test = 'test';
try {
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
} catch(e) {
return false;
}
}
};
function script(){
if(ls){
alert('Yes');
} else {
alert('No');
}
}
<button onclick="script()">Local Storage Support?</button>
I know I'm a little late to the party, but I have a few useful functions I cooked up and threw into a file named 'manage_storage.js'. I hope they are as useful to you guys, as they have served me well.
Remember: The function you're looking for (that answers this question) is isLclStorageAllowed.
So without further ado here is my code:
/* Conditional Function checks a web browser for 'session storage' support. [BEGIN] */
if (typeof isSessStorageAllowed !== 'function')
{
function isSessStorageAllowed()
{
if (!!window.sessionStorage && typeof sessionStorage.getItem === 'function' && typeof sessionStorage.setItem === 'function' && typeof sessionStorage.removeItem === 'function')
{
try
{
var cur_dt = new Date();
var cur_tm = cur_dt.getTime();
var ss_test_itm_key = 'ss_test_itm_' + String(cur_tm);
var ss_test_val = 'ss_test_val_' + String(cur_tm);
sessionStorage.setItem(ss_test_itm_key, String(ss_test_val));
if (sessionStorage.getItem(ss_test_itm_key) == String(ss_test_val))
{
return true;
}
else
{
return false;
};
sessionStorage.removeItem(ss_test_itm_key);
}
catch (exception)
{
return false;
};
}
else
{
return false;
};
};
};
/* Conditional Function checks a web browser for 'session storage' support. [END] */
/* Conditional Function checks a web browser for 'local storage' support. [BEGIN] */
if (typeof isLclStorageAllowed !== 'function')
{
function isLclStorageAllowed()
{
if (!!window.localStorage && typeof localStorage.getItem === 'function' && typeof localStorage.setItem === 'function' && typeof localStorage.removeItem === 'function')
{
try
{
var cur_dt = new Date();
var cur_tm = cur_dt.getTime();
var ls_test_itm_key = 'ls_test_itm_' + String(cur_tm);
var ls_test_val = 'ls_test_val_' + String(cur_tm);
localStorage.setItem(ls_test_itm_key, String(ls_test_val));
if (localStorage.getItem(ls_test_itm_key) == String(ls_test_val))
{
return true;
}
else
{
return false;
};
localStorage.removeItem(ls_test_itm_key);
}
catch (exception)
{
return false;
};
}
else
{
return false;
};
};
};
/* Conditional Function checks a web browser for 'local storage' support. [END] */
/* Conditional Function checks a web browser for 'web storage' support. [BEGIN] */
/* Prerequisites: 'isSessStorageAllowed()', 'isLclStorageAllowed()' */
if (typeof isWebStorageAllowed !== 'function')
{
function isWebStorageAllowed()
{
if (isSessStorageAllowed() === true && isLclStorageAllowed() === true)
{
return true;
}
else
{
return false;
};
};
};
/* Conditional Function checks a web browser for 'web storage' support. [END] */

determine whether Web Storage is supported or not

I need to verify that Web Storage API is supported and available (it may be disabled due to security issues).
So, I thought it would suffice to check whether the type sessionStorage or localStorage is defined or not:
if (typeof sessionStorage != 'undefined')
{
alert('sessionStorage available');
}
else
{
alert('sessionStorage not available');
}
However, I was wondering if it could be possible that the type exists, but I wouldn't been able to use the Web Storage API anyway.
Remarks:
I know Firefox will throw a security error if cookies are disabled and sessionStorage or localStorage are accessed.
Why don't you use the Modernizr library to detect if local storage is supported or not? Any differences between browers will be taken care of for you, you can then just use code like this:
if (Modernizr.localstorage) {
// browser supports local storage
} else {
// browser doesn't support local storage
}
I think you're on the right track with your original code, no need to make this too fancy.
Using the KISS principle with no additional dependencies in your code:
var storageEnabled = function() {
try {
sessionStorage.setItem('test-key','test-value');
if (sessionStorage.getItem('test-key') == 'test-value'){
return true;
}
} catch (e) {};
return false;
};
alert(storageEnabled() ? 'sessionStorage available' : 'sessionStorage not available');
try{
ssSupport = Object.prototype.toString.call( sessionStorage ) === "[object Storage]";
}
catch(e){
ssSupport = false;
}
So, because Modernizr.localstorage respectively Modernizr.sessionstorage will return true while Firefox might be used with disabled Cookies (which will lead into an security error) or any other proprietary (unexpected) behavior could occur: I've written my own webStorageEnabled function which seems to work very well.
function cookiesEnabled()
{
// generate a cookie to probe cookie access
document.cookie = '__cookieprobe=0;path=/';
return document.cookie.indexOf('__cookieprobe') != -1;
}
function webStorageEnabled()
{
if (typeof webStorageEnabled.value == 'undefined')
{
try
{
localStorage.setItem('__webstorageprobe', '');
localStorage.removeItem('__webstorageprobe');
webStorageEnabled.value = true;
}
catch (e) {
webStorageEnabled.value = false;
}
}
return webStorageEnabled.value;
}
// conditional
var storage = new function()
{
if (webStorageEnabled())
{
return {
local: localStorage,
session: sessionStorage
};
}
else
{
return {
local: cookiesEnabled() ? function()
{
// use cookies here
}() : null,
session: function()
{
var data = {};
return {
clear: function () {
data = {};
},
getItem: function(key) {
return data[key] || null;
},
key: function(i)
{
var index = 0;
for (var value in data)
{
if (index == i)
return value;
++index;
}
},
removeItem: function(key) {
delete data[key];
},
setItem: function(key, value) {
data[key] = value + '';
}
};
}()
};
}
}
Hope this will be useful for someone too.
My version (because IE 9 running in IE 8 more on an intranet site is broken).
if (typeof (Storage) != "undefined" && !!sessionStorage.getItem) {
}
a longer version that adds setObject to allow storing objects:
var sstorage;
if (typeof (Storage) != "undefined" && !!sessionStorage.getItem) {
Storage.prototype.setObject = function (key, value) {
this.setItem(key, JSON.stringify(value));
};
Storage.prototype.getObject = function (key) {
return JSON.parse(this.getItem(key));
};
if (typeof sessionStorage.setObject == "function") {
sstorage = sessionStorage;
}
else {
setupOldBrowser();
}
}
else {
setupOldBrowser();
}
function setupOldBrowser() {
sstorage = {};
sstorage.setObject = function (key, value) {
this[key] = JSON.stringify(value);
};
sstorage.getObject = function (key) {
if (typeof this[key] == 'string') {
return JSON.parse(this[key]);
}
else {
return null;
}
};
sstorage.removeItem = function (key) {
delete this[key];
};
}
Here's what I do to use session storage if available if it's not, use cookies..
var setCookie;
var getCookie;
var sessionStorageSupported = 'sessionStorage' in window
&& window['sessionStorage'] !== null;
if (sessionStorageSupported) {
setCookie = function (cookieName, value) {
window.sessionStorage.setItem(cookieName, value);
return value; //you can introduce try-catch here if required
};
getCookie = function (cookieName) {
return window.sessionStorage.getItem(cookieName);
};
}
else {
setCookie = function (cookieName, value) {
$.cookie(cookieName, value);
return value; // null if key not present
};
getCookie = function(cookieName) {
console.log("using cookies");
return $.cookie(cookieName);
};
}

Categories

Resources