Skip to content

Instantly share code, notes, and snippets.

@jsguy
Last active June 11, 2021 05:06
Show Gist options
  • Save jsguy/edc7e51ae56e0ab37a5c to your computer and use it in GitHub Desktop.
Save jsguy/edc7e51ae56e0ab37a5c to your computer and use it in GitHub Desktop.
Mithril IE8 polyfill
// IE polyfills needed by mithril for IE8 and below
// array.indexOf - https://gist.github.com/revolunet/1908355
if (!Array.prototype.indexOf)
{
Array.prototype.indexOf = function(elt /*, from*/)
{
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++)
{
if (from in this &&
this[from] === elt)
return from;
}
return -1;
};
}
// array.map - http://tech.pro/tutorial/1834/working-with-es5-javascript-array-functions-in-modern-and-legacy-browsers#map
if (!Array.prototype.map)
{
Array.prototype.map = function(fun /*, thisArg */)
{
"use strict";
if (this === void 0 || this === null)
throw new TypeError();
var t = Object(this),
len = t.length >>> 0;
if (typeof fun !== "function") {
throw new TypeError();
}
var res = new Array(len);
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++)
{
if (i in t)
res[i] = fun.call(thisArg, t[i], i, t);
}
return res;
};
}
// Object.keys - https://gist.github.com/jonfalcon/4715325
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;
}
})()
};
// function bind - https://gist.github.com/dsingleton/1312328
Function.prototype.bind = (function() {}).bind || function(b) {
if (typeof this !== "function") {
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
function c() {}
var a = [].slice,
f = a.call(arguments, 1),
e = this,
d = function() {
return e.apply(this instanceof c ? this : b || window, f.concat(a.call(arguments)));
};
c.prototype = this.prototype;
d.prototype = new c();
return d;
};
// Array.forEach - http://javascript.boxsheep.com/polyfills/Array-prototype-forEach/
if (!Array.prototype.forEach) {
Array.prototype.forEach = function (fn, arg) {
var arr = Object(this),
len = arr.length >>> 0,
thisArg = arg ? arg : undefined,
i;
if (typeof fn !== 'function') {
throw new TypeError();
}
for (i = 0; i < len; i += 1) {
if (arr.hasOwnProperty(i)) {
fn.call(thisArg, arr[i], i, arr);
}
}
return undefined;
};
}
// JSON - https://raw.githubusercontent.com/douglascrockford/JSON-js/master/json2.js (Removed overly-verbose comments)
"object" != typeof JSON && (JSON = {}),
function() {
"use strict";
function f(t) {
return 10 > t ? "0" + t : t
}
function quote(t) {
return escapable.lastIndex = 0, escapable.test(t) ? '"' + t.replace(escapable, function(t) {
var e = meta[t];
return "string" == typeof e ? e : "\\u" + ("0000" + t.charCodeAt(0).toString(16)).slice(-4)
}) + '"' : '"' + t + '"'
}
function str(t, e) {
var n, r, o, f, u, i = gap,
p = e[t];
switch (p && "object" == typeof p && "function" == typeof p.toJSON && (p = p.toJSON(t)), "function" == typeof rep && (p = rep.call(e, t, p)), typeof p) {
case "string":
return quote(p);
case "number":
return isFinite(p) ? String(p) : "null";
case "boolean":
case "null":
return String(p);
case "object":
if (!p) return "null";
if (gap += indent, u = [], "[object Array]" === Object.prototype.toString.apply(p)) {
for (f = p.length, n = 0; f > n; n += 1) u[n] = str(n, p) || "null";
return o = 0 === u.length ? "[]" : gap ? "[\n" + gap + u.join(",\n" + gap) + "\n" + i + "]" : "[" + u.join(",") + "]", gap = i, o
}
if (rep && "object" == typeof rep)
for (f = rep.length, n = 0; f > n; n += 1) "string" == typeof rep[n] && (r = rep[n], o = str(r, p), o && u.push(quote(r) + (gap ? ": " : ":") + o));
else
for (r in p) Object.prototype.hasOwnProperty.call(p, r) && (o = str(r, p), o && u.push(quote(r) + (gap ? ": " : ":") + o));
return o = 0 === u.length ? "{}" : gap ? "{\n" + gap + u.join(",\n" + gap) + "\n" + i + "}" : "{" + u.join(",") + "}", gap = i, o
}
}
"function" != typeof Date.prototype.toJSON && (Date.prototype.toJSON = function() {
return isFinite(this.valueOf()) ? this.getUTCFullYear() + "-" + f(this.getUTCMonth() + 1) + "-" + f(this.getUTCDate()) + "T" + f(this.getUTCHours()) + ":" + f(this.getUTCMinutes()) + ":" + f(this.getUTCSeconds()) + "Z" : null
}, String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function() {
return this.valueOf()
});
var cx, escapable, gap, indent, meta, rep;
"function" != typeof JSON.stringify && (escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, meta = {
"\b": "\\b",
" ": "\\t",
"\n": "\\n",
"\f": "\\f",
"\r": "\\r",
'"': '\\"',
"\\": "\\\\"
}, JSON.stringify = function(t, e, n) {
var r;
if (gap = "", indent = "", "number" == typeof n)
for (r = 0; n > r; r += 1) indent += " ";
else "string" == typeof n && (indent = n);
if (rep = e, e && "function" != typeof e && ("object" != typeof e || "number" != typeof e.length)) throw new Error("JSON.stringify");
return str("", {
"": t
})
}), "function" != typeof JSON.parse && (cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, JSON.parse = function(text, reviver) {
function walk(t, e) {
var n, r, o = t[e];
if (o && "object" == typeof o)
for (n in o) Object.prototype.hasOwnProperty.call(o, n) && (r = walk(o, n), void 0 !== r ? o[n] = r : delete o[n]);
return reviver.call(t, e, o)
}
var j;
if (text = String(text), cx.lastIndex = 0, cx.test(text) && (text = text.replace(cx, function(t) {
return "\\u" + ("0000" + t.charCodeAt(0).toString(16)).slice(-4)
})), /^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) return j = eval("(" + text + ")"), "function" == typeof reviver ? walk({
"": j
}, "") : j;
throw new SyntaxError("JSON.parse")
})
}();
Array.prototype.indexOf||(Array.prototype.indexOf=function(e,d){var g=this.length>>>0,b=Number(d)||0,b=0>b?Math.ceil(b):Math.floor(b);for(0>b&&(b+=g);b<g;b++)if(b in this&&this[b]===e)return b;return-1});Array.prototype.map||(Array.prototype.map=function(e){if(void 0===this||null===this)throw new TypeError;var d=Object(this),g=d.length>>>0;if("function"!==typeof e)throw new TypeError;for(var b=Array(g),c=2<=arguments.length?arguments[1]:void 0,a=0;a<g;a++)a in d&&(b[a]=e.call(c,d[a],a,d));return b});
Object.keys||(Object.keys=function(){var e=Object.prototype.hasOwnProperty,d=!{toString:null}.propertyIsEnumerable("toString"),g="toString toLocaleString valueOf hasOwnProperty isPrototypeOf propertyIsEnumerable constructor".split(" "),b=g.length;return function(c){if("object"!==typeof c&&"function"!==typeof c||null===c)throw new TypeError("Object.keys called on non-object");var a=[],h;for(h in c)e.call(c,h)&&a.push(h);if(d)for(h=0;h<b;h++)e.call(c,g[h])&&a.push(g[h]);return a}}());
Function.prototype.bind=function(){}.bind||function(e){function d(){return a.apply(this instanceof g?this:e||window,c.concat(b.call(arguments)))}function g(){}if("function"!==typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var b=[].slice,c=b.call(arguments,1),a=this;g.prototype=this.prototype;d.prototype=new g;return d};
Array.prototype.forEach||(Array.prototype.forEach=function(e,d){var g=Object(this),b=g.length>>>0,c=d?d:void 0,a;if("function"!==typeof e)throw new TypeError;for(a=0;a<b;a+=1)g.hasOwnProperty(a)&&e.call(c,g[a],a,g)});"object"!=typeof JSON&&(JSON={});
(function(){function e(a){return 10>a?"0"+a:a}function d(a){return c.lastIndex=0,c.test(a)?'"'+a.replace(c,function(a){var b=r[a];return"string"==typeof b?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function g(b,e){var k,c,l,p,m,q=a,f=e[b];switch(f&&"object"==typeof f&&"function"==typeof f.toJSON&&(f=f.toJSON(b)),"function"==typeof n&&(f=n.call(e,b,f)),typeof f){case "string":return d(f);case "number":return isFinite(f)?String(f):"null";case "boolean":case "null":return String(f);
case "object":if(!f)return"null";if(a+=h,m=[],"[object Array]"===Object.prototype.toString.apply(f)){p=f.length;for(k=0;p>k;k+=1)m[k]=g(k,f)||"null";return l=0===m.length?"[]":a?"[\n"+a+m.join(",\n"+a)+"\n"+q+"]":"["+m.join(",")+"]",a=q,l}if(n&&"object"==typeof n)for(p=n.length,k=0;p>k;k+=1)"string"==typeof n[k]&&(c=n[k],l=g(c,f),l&&m.push(d(c)+(a?": ":":")+l));else for(c in f)Object.prototype.hasOwnProperty.call(f,c)&&(l=g(c,f),l&&m.push(d(c)+(a?": ":":")+l));return l=0===m.length?"{}":a?"{\n"+a+
m.join(",\n"+a)+"\n"+q+"}":"{"+m.join(",")+"}",a=q,l}}"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+e(this.getUTCMonth()+1)+"-"+e(this.getUTCDate())+"T"+e(this.getUTCHours())+":"+e(this.getUTCMinutes())+":"+e(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()});var b,c,a,h,r,n;"function"!=typeof JSON.stringify&&(c=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
r={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(b,c,e){var d;if(a="",h="","number"==typeof e)for(d=0;e>d;d+=1)h+=" ";else"string"==typeof e&&(h=e);if(n=c,c&&"function"!=typeof c&&("object"!=typeof c||"number"!=typeof c.length))throw Error("JSON.stringify");return g("",{"":b})});"function"!=typeof JSON.parse&&(b=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,JSON.parse=function(a,c){function e(a,
b){var d,g,f=a[b];if(f&&"object"==typeof f)for(d in f)Object.prototype.hasOwnProperty.call(f,d)&&(g=e(f,d),void 0!==g?f[d]=g:delete f[d]);return c.call(a,b,f)}var d;if(a=String(a),b.lastIndex=0,b.test(a)&&(a=a.replace(b,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})),/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return d=eval("("+
a+")"),"function"==typeof c?e({"":d},""):d;throw new SyntaxError("JSON.parse");})})();
@judwhite
Copy link

judwhite commented Jun 8, 2017

Hi @jsguy,

Mithril 1.1.1 (https://unpkg.com/mithril@1.1.1/mithril.js) needs these polyfills:

// 	Date.now - https://gist.github.com/eliperelman/1035932
Date.now ||
    (Date.now = function () {
        return +new Date // Create a new Date object and return the Unix timestamp epoch.
    })

// 	Object.create - http://jsperf.com/new-vs-object-create-including-polyfill
if (typeof Object.create !== 'function') {
 Object.create = function(o, props) {
  function F() {}
  F.prototype = o;

  if (typeof(props) === "object") {
   for (prop in props) {
    if (props.hasOwnProperty((prop))) {
     F[prop] = props[prop];
    }
   }
  }
  return new F();
 };
}

// 	Array.isArray - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray?v=example#Polyfill
if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}

// 	Node.textContent property - https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#Polyfill_for_IE8
if (Object.defineProperty 
  && Object.getOwnPropertyDescriptor 
  && Object.getOwnPropertyDescriptor(Element.prototype, "textContent") 
  && !Object.getOwnPropertyDescriptor(Element.prototype, "textContent").get) {
  (function() {
    var innerText = Object.getOwnPropertyDescriptor(Element.prototype, "innerText");
    Object.defineProperty(Element.prototype, "textContent",
     {
       get: function() {
         return innerText.get.call(this);
       },
       set: function(s) {
         return innerText.set.call(this, s);
       }
     }
   );
  })();
}

Other IE8 issues:

  • Change PromisePolyfill.prototype.catch to PromisePolyfill.prototype["catch"]
  • Change var className = attrs.className || attrs.class to var className = attrs.className
    • This has the side effect className must be used instead of class in attrs parameter of m(selector, attrs, ...children)
  • Remove this code:
if (attrs.class !== undefined) {
    attrs.class = undefined
    attrs.className = className
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment