Skip to content

Instantly share code, notes, and snippets.

@Loupax
Created January 20, 2015 14:48
Show Gist options
  • Save Loupax/f0735bc91e9fa8700eaa to your computer and use it in GitHub Desktop.
Save Loupax/f0735bc91e9fa8700eaa to your computer and use it in GitHub Desktop.
Shims
(function(){
// We do not know if this file is used inside a web script or a webworker script,
// so we use this hack to get access to the current global object
var get = eval;
var window = get("this");
// Some versions of IE have no set method in the Uint8ClampedArray.
// This was propably a bug that was fixed in a later update but we'll add it here
// just to be sure...
Uint8ClampedArray.prototype.set = Uint8ClampedArray.prototype.set || function(data){
var len = this.length, data_len = data.length;
if(len !== data_len){
throw new (RangeError||Error)("Source is too large");
}
for(var i = 0; i < len; i++){
this[i] = data[i];
}
};
// Only IE10 has the CanvasPixelArray, so if it doesn't exist, don't bother
// extending it
if(window.CanvasPixelArray){
CanvasPixelArray.prototype.set = CanvasPixelArray.prototype.set || function(data){
var len = this.length, data_len = data.length;
if(len !== data_len){
throw new (RangeError||Error)("Source is too large");
}
for(var i = 0; i < len; i++){
this[i] = data[i];
}
};
}
if (!ArrayBuffer.prototype.slice) {
//Returns a new ArrayBuffer whose contents are a copy of this ArrayBuffer's
//bytes from `begin`, inclusive, up to `end`, exclusive
ArrayBuffer.prototype.slice = function (begin, end) {
//If `begin` is unspecified, Chrome assumes 0, so we do the same
if (begin === void 0) {
begin = 0;
}
//If `end` is unspecified, the new ArrayBuffer contains all
//bytes from `begin` to the end of this ArrayBuffer.
if (end === void 0) {
end = this.byteLength;
}
//Chrome converts the values to integers via flooring
begin = Math.floor(begin);
end = Math.floor(end);
//If either `begin` or `end` is negative, it refers to an
//index from the end of the array, as opposed to from the beginning.
if (begin < 0) {
begin += this.byteLength;
}
if (end < 0) {
end += this.byteLength;
}
//The range specified by the `begin` and `end` values is clamped to the
//valid index range for the current array.
begin = Math.min(Math.max(0, begin), this.byteLength);
end = Math.min(Math.max(0, end), this.byteLength);
//If the computed length of the new ArrayBuffer would be negative, it
//is clamped to zero.
if (end - begin <= 0) {
return new ArrayBuffer(0);
}
var result = new ArrayBuffer(end - begin);
var resultBytes = new Uint8Array(result);
var sourceBytes = new Uint8Array(this, begin, end - begin);
resultBytes.set(sourceBytes);
return result;
};
}
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
// requestAnimationFrame polyfill by Erik Möller
// fixes from Paul Irish and Tino Zijdel
(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
|| window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
//if(window.URL === undefined){
window.URL = (function() {
function parseSearch(s) {
var result = [];
var k = 0;
var parts = s.slice(1).split('&');
for (var i = 0; i < parts.length; i++) {
var part = parts[i];
var key = part.split('=', 1)[0];
if (key) {
var value = part.slice(key.length + 1);
result[k++] = [key, value];
}
}
return result;
}
function serializeParsed(array) {
return array.map(function(pair) {
return pair[1] !== '' ? pair.join('=') : pair[0];
}).join('&');
}
function URL(url, base) {
if (!url)
throw new TypeError('Invalid argument');
var doc = document.implementation.createHTMLDocument('');
if (base) {
var baseElement = doc.createElement('base');
baseElement.href = base || window.lo;
doc.head.appendChild(baseElement);
}
var anchorElement = doc.createElement('a');
anchorElement.href = url;
doc.body.appendChild(anchorElement);
if (anchorElement.href === '')
throw new TypeError('Invalid URL');
Object.defineProperty(this, '_anchorElement', {value: anchorElement});
}
URL.prototype = {
toString: function() {
return this.href;
},
get href() {
return this._anchorElement.href;
},
set href(value) {
this._anchorElement.href = value;
},
get protocol() {
return this._anchorElement.protocol;
},
set protocol(value) {
this._anchorElement.protocol = value;
},
// NOT IMPLEMENTED
// get username() {
// return this._anchorElement.username;
// },
// set username(value) {
// this._anchorElement.username = value;
// },
// get password() {
// return this._anchorElement.password;
// },
// set password(value) {
// this._anchorElement.password = value;
// },
// get origin() {
// return this._anchorElement.origin;
// },
get host() {
return this._anchorElement.host;
},
set host(value) {
this._anchorElement.host = value;
},
get hostname() {
return this._anchorElement.hostname;
},
set hostname(value) {
this._anchorElement.hostname = value;
},
get port() {
return this._anchorElement.port;
},
set port(value) {
this._anchorElement.port = value;
},
get pathname() {
return this._anchorElement.pathname;
},
set pathname(value) {
this._anchorElement.pathname = value;
},
get search() {
return this._anchorElement.search;
},
set search(value) {
this._anchorElement.search = value;
},
get hash() {
return this._anchorElement.hash;
},
set hash(value) {
this._anchorElement.hash = value;
},
get filename() {
var match;
if ((match = this.pathname.match(/\/([^\/]+)$/)))
return match[1];
return '';
},
set filename(value) {
var match, pathname = this.pathname;
if ((match = pathname.match(/\/([^\/]+)$/)))
this.pathname = pathname.slice(0, -match[1].length) + value;
else
this.pathname = value;
},
get parameterNames() {
var seen = Object.create(null);
return parseSearch(this.search).map(function(pair) {
return pair[0];
}).filter(function(key) {
if (key in seen)
return false;
seen[key] = true;
return true;
});
},
getParameter: function(name) {
return this.getParameterAll(name).pop();
},
getParameterAll: function(name) {
name = String(name);
var result = [];
var k = 0;
parseSearch(this.search).forEach(function(pair) {
if (pair[0] === name)
result[k++] = pair[1];
});
return result;
},
appendParameter: function(name, values) {
if (!Array.isArray(values))
values = [values];
var parsed = parseSearch(this.search);
for (var i = 0; i < values.length; i++) {
parsed.push([name, values[i]]);
}
this.search = serializeParsed(parsed);
},
clearParameter: function(name) {
this.search = serializeParsed(
parseSearch(this.search).filter(function(pair) {
return pair[0] !== name;
}));
},
};
var oldURL = window.URL || window.webkitURL || window.mozURL;
URL.createObjectURL = function(blob) {
return oldURL.createObjectURL.apply(oldURL, arguments);
};
URL.revokeObjectURL = function(url) {
return oldURL.revokeObjectURL.apply(oldURL, arguments);
};
// Methods should not be enumerable.
Object.defineProperty(URL.prototype, 'toString', {enumerable: false});
Object.defineProperty(URL.prototype, 'getParameter', {enumerable: false});
Object.defineProperty(URL.prototype, 'getParameterAll', {enumerable: false});
Object.defineProperty(URL.prototype, 'appendParameter', {enumerable: false});
Object.defineProperty(URL.prototype, 'clearParameter', {enumerable: false});
Object.defineProperty(URL, 'createObjectURL', {enumerable: false});
Object.defineProperty(URL, 'revokeObjectURL', {enumerable: false});
return URL;
})();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment