From 308e677ede36c680ef2ba2b0761f9d9f05e9087c Mon Sep 17 00:00:00 2001 From: jods Date: Tue, 21 Mar 2017 06:25:05 +0100 Subject: [PATCH] refactor(size): add flag to opt-out of IE support (#18) Saves around 4K in a minified build. --- build/paths.js | 1 + src/class-list.js | 2 +- src/console.js | 28 +++++++++++++++++ src/custom-event.js | 2 +- src/element-matches.js | 12 +++----- src/feature.js | 24 +++++---------- src/function-name.js | 2 +- src/html-template-element.js | 6 ++-- src/index.js | 59 ++++++++---------------------------- src/performance.js | 2 +- 10 files changed, 60 insertions(+), 78 deletions(-) create mode 100644 src/console.js diff --git a/build/paths.js b/build/paths.js index a5334e8..8635b5a 100644 --- a/build/paths.js +++ b/build/paths.js @@ -29,6 +29,7 @@ paths.files = [ 'function-name.js', 'class-list.js', 'performance.js', + 'console.js', 'custom-event.js', 'element-matches.js', 'feature.js', diff --git a/src/class-list.js b/src/class-list.js index ed76ed2..1081a56 100644 --- a/src/class-list.js +++ b/src/class-list.js @@ -1,4 +1,4 @@ -export function _ensureClassList(): void { +if (typeof FEATURE_NO_IE === 'undefined') { /* * classList polyfill. Forked from https://github.com/eligrey/classList.js * diff --git a/src/console.js b/src/console.js new file mode 100644 index 0000000..3debaca --- /dev/null +++ b/src/console.js @@ -0,0 +1,28 @@ +if (typeof FEATURE_NO_IE === 'undefined') { + // References to IE 9 in this file mean the *real* IE 9 browser, not IE 11 in 9 emulation mode. + // Note that in IE 9, until the F12 are actually opened window.console is undefined! + let con = window.console = window.console || {}; + let nop = function() {}; + // console.memory is actually Chrome-only at this point, + // but Aurelia does not use it so we're cutting down on "polyfills" here. + // Moreover, that object is utterly useless in other browsers, as all stats would actually be 'undefined' + if (!con.memory) con.memory = {}; + ('assert,clear,count,debug,dir,dirxml,error,exception,group,' + + 'groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,' + + 'show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn') + .split(',') + .forEach(m => { if (!con[m]) con[m] = nop; }); + + // This is really f***ed up IE 9 stuff. + // You can be in a situation where console.log is an object, not a function. + // And the magic voodoo below that should _not_ work (the Function.prototype.call.bind(object,...) part) + // actually kicks IE 9 into converting that object into a real function that actually logs stuff. + // See http://patik.com/blog/complete-cross-browser-console-log/ + if (typeof con.log === 'object') { + 'log,info,warn,error,assert,dir,clear,profile,profileEnd' + .split(',') + .forEach(function(method) { + console[method] = this.bind(console[method], console); + }, Function.prototype.call); + } +} diff --git a/src/custom-event.js b/src/custom-event.js index 7a7e5f5..baee207 100644 --- a/src/custom-event.js +++ b/src/custom-event.js @@ -1,4 +1,4 @@ -export function _ensureCustomEvent(): void { +if (typeof FEATURE_NO_IE === 'undefined') { if (!window.CustomEvent || typeof window.CustomEvent !== 'function') { let CustomEvent = function(event, params) { params = params || { diff --git a/src/element-matches.js b/src/element-matches.js index b74ab30..c64fd34 100644 --- a/src/element-matches.js +++ b/src/element-matches.js @@ -1,8 +1,6 @@ -export function _ensureElementMatches(): void { - if (Element && !Element.prototype.matches) { - let proto = Element.prototype; - proto.matches = proto.matchesSelector || - proto.mozMatchesSelector || proto.msMatchesSelector || - proto.oMatchesSelector || proto.webkitMatchesSelector; - } +if (Element && !Element.prototype.matches) { + let proto = Element.prototype; + proto.matches = proto.matchesSelector || + proto.mozMatchesSelector || proto.msMatchesSelector || + proto.oMatchesSelector || proto.webkitMatchesSelector; } diff --git a/src/feature.js b/src/feature.js index 75cec37..eb192f6 100644 --- a/src/feature.js +++ b/src/feature.js @@ -1,17 +1,7 @@ -export const _FEATURE = {}; - -_FEATURE.shadowDOM = (function() { - return !!HTMLElement.prototype.attachShadow; -})(); - -_FEATURE.scopedCSS = (function() { - return 'scoped' in document.createElement('style'); -})(); - -_FEATURE.htmlTemplateElement = (function() { - return 'content' in document.createElement('template'); -})(); - -_FEATURE.mutationObserver = (function() { - return !!(window.MutationObserver || window.WebKitMutationObserver); -})(); +export const _FEATURE = { + shadowDOM: !!HTMLElement.prototype.attachShadow, + scopedCSS: 'scoped' in document.createElement('style'), + htmlTemplateElement: 'content' in document.createElement('template'), + mutationObserver: !!(window.MutationObserver || window.WebKitMutationObserver), + ensureHTMLTemplateElement: t => t, +}; diff --git a/src/function-name.js b/src/function-name.js index 09ffc62..1252362 100644 --- a/src/function-name.js +++ b/src/function-name.js @@ -1,4 +1,4 @@ -export function _ensureFunctionName(): void { +if (typeof FEATURE_NO_IE === 'undefined') { // Fix Function#name on browsers that do not support it (IE): function test() {} diff --git a/src/html-template-element.js b/src/html-template-element.js index 055f67b..b3977a0 100644 --- a/src/html-template-element.js +++ b/src/html-template-element.js @@ -1,6 +1,6 @@ import {_FEATURE} from './feature'; -export function _ensureHTMLTemplateElement(): void { +if (typeof FEATURE_NO_IE === 'undefined') { function isSVGTemplate(el) { return el.tagName === 'template' && el.namespaceURI === 'http://www.w3.org/2000/svg'; @@ -53,9 +53,7 @@ export function _ensureHTMLTemplateElement(): void { return template; } - if (_FEATURE.htmlTemplateElement) { - _FEATURE.ensureHTMLTemplateElement = function(template) { return template; }; - } else { + if (!_FEATURE.htmlTemplateElement) { _FEATURE.ensureHTMLTemplateElement = fixHTMLTemplateElementRoot; } } diff --git a/src/index.js b/src/index.js index 0f974cd..551d477 100644 --- a/src/index.js +++ b/src/index.js @@ -2,12 +2,15 @@ import {initializePAL, isInitialized} from 'aurelia-pal'; import {_PLATFORM} from './platform'; import {_FEATURE} from './feature'; import {_DOM} from './dom'; -import {_ensureCustomEvent} from './custom-event'; -import {_ensureFunctionName} from './function-name'; -import {_ensureHTMLTemplateElement} from './html-template-element'; -import {_ensureElementMatches} from './element-matches'; -import {_ensureClassList} from './class-list'; -import {_ensurePerformance} from './performance'; +// DOM polyfills +// Actually inlined by our build because of build/paths.js but `import "m"` is not properly removed!? +// import './console'; +// import './custom-event'; +// import './function-name'; +// import './html-template-element'; +// import './element-matches'; +// import './class-list'; +// import './performance'; /** * Initializes the PAL with the Browser-targeted implementation. @@ -17,58 +20,22 @@ export function initialize(): void { return; } - _ensureCustomEvent(); - _ensureFunctionName(); - _ensureHTMLTemplateElement(); - _ensureElementMatches(); - _ensureClassList(); - _ensurePerformance(); - initializePAL((platform, feature, dom) => { Object.assign(platform, _PLATFORM); Object.assign(feature, _FEATURE); Object.assign(dom, _DOM); - (function(global) { - global.console = global.console || {}; - let con = global.console; - let prop; - let method; - let empty = {}; - let dummy = function() {}; - let properties = 'memory'.split(','); - let methods = ('assert,clear,count,debug,dir,dirxml,error,exception,group,' + - 'groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,' + - 'show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn').split(','); - while (prop = properties.pop()) if (!con[prop]) con[prop] = empty; - while (method = methods.pop()) if (!con[method]) con[method] = dummy; - })(platform.global); - - if (platform.global.console && typeof console.log === 'object') { - ['log', 'info', 'warn', 'error', 'assert', 'dir', 'clear', 'profile', 'profileEnd'].forEach(function(method) { - console[method] = this.bind(console[method], console); - }, Function.prototype.call); - } - Object.defineProperty(dom, 'title', { - get: function() { - return document.title; - }, - set: function(value) { - document.title = value; - } + get: () => document.title, + set: (value) => { document.title = value; } }); Object.defineProperty(dom, 'activeElement', { - get: function() { - return document.activeElement; - } + get: () => document.activeElement }); Object.defineProperty(platform, 'XMLHttpRequest', { - get: function() { - return platform.global.XMLHttpRequest; - } + get: () => platform.global.XMLHttpRequest }); }); } diff --git a/src/performance.js b/src/performance.js index ac04d7c..717bb67 100644 --- a/src/performance.js +++ b/src/performance.js @@ -1,6 +1,6 @@ import {_PLATFORM} from './platform'; -export function _ensurePerformance(): void { +if (typeof FEATURE_NO_IE === 'undefined') { // performance polyfill. Copied from https://gist.github.com/paulirish/5438650 // https://gist.github.com/paulirish/5438650