From: Tom Hughes Date: Wed, 29 Aug 2012 11:29:47 +0000 (+0100) Subject: Use augment.js for improved cross browser compatibility X-Git-Tag: live~5429 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/7b626f31be8a5f60d285d39d9b1063de776ddfe0?ds=sidebyside Use augment.js for improved cross browser compatibility Remove the quick hack for that I added for Array.forEach and pull in augment.js instead to add missing JS methods to older browsers. --- diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 352ec9f8a..dcc5d43f8 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -2,10 +2,10 @@ //= require jquery_ujs //= require jquery.autogrowtextarea //= require jquery.timers +//= require augment //= require openlayers //= require i18n/translations //= require globals -//= require compat //= require browse //= require export //= require map diff --git a/app/assets/javascripts/compat.js b/app/assets/javascripts/compat.js deleted file mode 100644 index 3af9297a3..000000000 --- a/app/assets/javascripts/compat.js +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Implement Array.forEach for browsers which don't have it - */ -if ( !Array.prototype.forEach ) { - Array.prototype.forEach = function(fn, scope) { - for(var i = 0, len = this.length; i < len; ++i) { - fn.call(scope || this, this[i], i, this); - } - } -} diff --git a/vendor/assets/augment.js/augment.js b/vendor/assets/augment.js/augment.js new file mode 100644 index 000000000..0bf2fd47c --- /dev/null +++ b/vendor/assets/augment.js/augment.js @@ -0,0 +1,397 @@ +// augment.js JavaScript 1.8.5 methods for all, version: 0.4.2 +// using snippets from Mozilla - https://developer.mozilla.org/en/JavaScript +// (c) 2011 Oliver Nightingale +// +// Released under MIT license. +// +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every +if (!Array.prototype.every) { + Array.prototype.every = function(fun /*, thisp */) { + "use strict"; + + if (this === void 0 || this === null) + throw new TypeError(); + + var t = Object(this); + var len = t.length >>> 0; + if (typeof fun !== "function") + throw new TypeError(); + + var thisp = arguments[1]; + for (var i = 0; i < len; i++) { + if (i in t && !fun.call(thisp, t[i], i, t)) + return false; + } + + return true; + }; +} +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/filter +if (!Array.prototype.filter) { + Array.prototype.filter = function(fun /*, thisp */) { + "use strict"; + + if (this === void 0 || this === null) + throw new TypeError(); + + var t = Object(this); + var len = t.length >>> 0; + if (typeof fun !== "function") + throw new TypeError(); + + var res = []; + var thisp = arguments[1]; + for (var i = 0; i < len; i++) { + if (i in t) { + var val = t[i]; // in case fun mutates this + if (fun.call(thisp, val, i, t)) + res.push(val); + } + } + + return res; + }; +} +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach +if (!Array.prototype.forEach) { + Array.prototype.forEach = function(fun /*, thisp */) { + "use strict"; + + if (this === void 0 || this === null) + throw new TypeError(); + + var t = Object(this); + var len = t.length >>> 0; + if (typeof fun !== "function") + throw new TypeError(); + + var thisp = arguments[1]; + for (var i = 0; i < len; i++) { + if (i in t) + fun.call(thisp, t[i], i, t); + } + }; +} +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf +if (!Array.prototype.indexOf) { + Array.prototype.indexOf = function(searchElement /*, fromIndex */) { + "use strict"; + + if (this === void 0 || this === null) + throw new TypeError(); + + var t = Object(this); + var len = t.length >>> 0; + if (len === 0) + return -1; + + var n = 0; + if (arguments.length > 0) { + n = Number(arguments[1]); + if (n !== n) // shortcut for verifying if it's NaN + n = 0; + else if (n !== 0 && n !== (Infinity) && n !== -(Infinity)) + n = (n > 0 || -1) * Math.floor(Math.abs(n)); + } + + if (n >= len) + return -1; + + var k = n >= 0 + ? n + : Math.max(len - Math.abs(n), 0); + + for (; k < len; k++) { + if (k in t && t[k] === searchElement) + return k; + } + return -1; + }; +} +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray +Array.isArray = Array.isArray || function(o) { return Object.prototype.toString.call(o) === '[object Array]'; }; +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf +if (!Array.prototype.lastIndexOf) { + Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/) { + "use strict"; + + if (this === void 0 || this === null) + throw new TypeError(); + + var t = Object(this); + var len = t.length >>> 0; + if (len === 0) + return -1; + + var n = len; + if (arguments.length > 1) { + n = Number(arguments[1]); + if (n !== n) + n = 0; + else if (n !== 0 && n !== (Infinity) && n !== -(Infinity)) + n = (n > 0 || -1) * Math.floor(Math.abs(n)); + } + + var k = n >= 0 + ? Math.min(n, len - 1) + : len - Math.abs(n); + + for (; k >= 0; k--) { + if (k in t && t[k] === searchElement) + return k; + } + return -1; + }; +} +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map +if (!Array.prototype.map) { + Array.prototype.map = function(fun /*, thisp */) { + "use strict"; + + if (this === void 0 || this === null) + throw new TypeError(); + + var t = Object(this); + var len = t.length >>> 0; + if (typeof fun !== "function") + throw new TypeError(); + + var res = new Array(len); + var thisp = arguments[1]; + for (var i = 0; i < len; i++) { + if (i in t) + res[i] = fun.call(thisp, t[i], i, t); + } + + return res; + }; +} +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Reduce +if (!Array.prototype.reduce) { + Array.prototype.reduce = function(fun /*, initialValue */) { + "use strict"; + + if (this === void 0 || this === null) + throw new TypeError(); + + var t = Object(this); + var len = t.length >>> 0; + if (typeof fun !== "function") + throw new TypeError(); + + // no value to return if no initial value and an empty array + if (len == 0 && arguments.length == 1) + throw new TypeError(); + + var k = 0; + var accumulator; + if (arguments.length >= 2) { + accumulator = arguments[1]; + } else { + do { + if (k in t) { + accumulator = t[k++]; + break; + } + + // if array contains no values, no initial value to return + if (++k >= len) + throw new TypeError(); + } + while (true); + } + + while (k < len) { + if (k in t) + accumulator = fun.call(undefined, accumulator, t[k], k, t); + k++; + } + + return accumulator; + }; +} +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/ReduceRight +if (!Array.prototype.reduceRight) { + Array.prototype.reduceRight = function(callbackfn /*, initialValue */) { + "use strict"; + + if (this === void 0 || this === null) + throw new TypeError(); + + var t = Object(this); + var len = t.length >>> 0; + if (typeof callbackfn !== "function") + throw new TypeError(); + + // no value to return if no initial value, empty array + if (len === 0 && arguments.length === 1) + throw new TypeError(); + + var k = len - 1; + var accumulator; + if (arguments.length >= 2) { + accumulator = arguments[1]; + } else { + do { + if (k in this) { + accumulator = this[k--]; + break; + } + + // if array contains no values, no initial value to return + if (--k < 0) + throw new TypeError(); + } + while (true); + } + + while (k >= 0) { + if (k in t) + accumulator = callbackfn.call(undefined, accumulator, t[k], k, t); + k--; + } + + return accumulator; + }; +} +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some +if (!Array.prototype.some) { + Array.prototype.some = function(fun /*, thisp */) { + "use strict"; + + if (this === void 0 || this === null) + throw new TypeError(); + + var t = Object(this); + var len = t.length >>> 0; + if (typeof fun !== "function") + throw new TypeError(); + + var thisp = arguments[1]; + for (var i = 0; i < len; i++) { + if (i in t && fun.call(thisp, t[i], i, t)) + return true; + } + + return false; + }; +} +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/now +if (!Date.now) { + Date.now = function now () { + return +new Date(); + }; +} +if (!Date.prototype.toISOString) { + Date.prototype.toISOString = (function () { + + var pad = function (n, length) { + length = length || 2 + return (n = n + "", n.length === length) ? n : pad("0" + n, length); + } + + return function () { + var year = this.getUTCFullYear() + year = (year < 0 ? '-' : (year > 9999 ? '+' : '')) + ('00000' + Math.abs(year)).slice(0 <= year && year <= 9999 ? -4 : -6); + + var date = [year, pad(this.getUTCMonth() + 1), pad(this.getUTCDate())].join("-") + var time = [pad(this.getUTCHours()), pad(this.getUTCMinutes()), pad(this.getUTCSeconds())].join(":") + "." + pad(this.getUTCMilliseconds(), 3) + return [date, time].join("T") + "Z" + } + })() +}; +if (!Date.prototype.toJSON) { + Date.prototype.toJSON = Date.prototype.toJSON +}; +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind +if (!Function.prototype.bind ) { + + Function.prototype.bind = function(obj) { + + if (typeof this !== 'function') throw new TypeError ("Function.prototype.bind - what is trying to be bound is not callable") + + var slice = Array.prototype.slice, + args = slice.call(arguments, 1), + self = this, + nop = function () {}, + bound = function () { + + if (nop.prototype && this instanceof nop) { + var result = self.apply(new nop, args.concat(slice.call(arguments))) + return (Object(result) === result) ? result : self + } else { + return self.apply(obj, args.concat(slice.call(arguments))) + }; + }; + + nop.prototype = self.prototype; + + bound.prototype = new nop(); + + return bound; + }; +} +;(function () { "use strict" + + var ensureIsObject = function (param) { + if (param !== Object(param)) throw new TypeError('Object.getPrototypeOf called on non-object'); + } + + if (!Object.getPrototypeOf) { + if (typeof "test".__proto__ === "object") { + Object.getPrototypeOf = function (obj) { + ensureIsObject(obj) + return obj.__proto__ + } + } else { + Object.getPrototypeOf = function (obj) { + ensureIsObject(obj) + return obj.constructor.prototype + } + }; + }; +})(); +// http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation +if (!Object.keys) { + Object.keys = (function () { + var hasOwnProperty = Object.prototype.hasOwnProperty, + hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), + dontEnums = [ + 'toString', + 'toLocaleString', + 'valueOf', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'constructor' + ], + dontEnumsLength = dontEnums.length + + return function (obj) { + if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object') + + var result = [] + + for (var prop in obj) { + if (hasOwnProperty.call(obj, prop)) result.push(prop) + } + + if (hasDontEnumBug) { + for (var i=0; i < dontEnumsLength; i++) { + if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]) + } + } + return result + } + })() +};if (!String.prototype.trim) { + String.prototype.trim = (function () { + + var trimLeft = /^\s+/, + trimRight = /\s+$/ + + return function () { + return this.replace(trimLeft, "").replace(trimRight, "") + } + })() +};