Skip to content

Instantly share code, notes, and snippets.

@samgiles
Last active September 30, 2023 02:49
Show Gist options
  • Save samgiles/ee430d501bb6e7639719 to your computer and use it in GitHub Desktop.
Save samgiles/ee430d501bb6e7639719 to your computer and use it in GitHub Desktop.
Polyfill.io Name resolution pseudocode
// Functional Helper: When lambda returns an array, compose concat and map to return a flattened result.
// See https://gist.github.com/samgiles/762ee337dff48623e729 for an example
Array.prototype.flatMap = function(lambda) {
return Array.prototype.concat.apply([], this.map(lambda));
};
// Mock, imagine this is some function that maps a modernizr test name to the polyfill.io nomenclature, if it doesn't map,
// it must return the name as is. Must always be an array.
function getListOfPolyFillsForModernizrTest(name) {
var mock = {
'es5array': [
'Array.prototype.every',
'Array.prototype.filter',
'Array.prototype.forEach',
'Array.prototype.indexOf',
'Array.prototype.lastIndexOf',
'Array.prototype.map',
'Array.prototype.some',
'Array.prototype.reduce',
'Array.prototype.reduceRight',
'Array.isArray'
],
'requestanimationframe': [
'Window.requestAnimationFrame'
],
'queryselector': [
'Document.prototype.querySelector',
'Document.prototype.querySelectorAll'
]
};
return mock[name] || [name];
}
// Mock, imagine this is some function that maps Origami module names to Modernizr test names
// If it does not map, then return the name. (Must always be an array)
function getOrigamiModernizrNames(name) {
var mock = {
'o-gallery': [ 'queryselector', 'es5array' ],
'o-ft-buttons': [ 'requestanimationframe', 'es5array' ]
};
return mock[name] || [name];
}
// An ordered list of name resolution functions. The first is called which transforms any origami module names
// then the second which transforms any modernizr names into polyfill.io names.
var polyfillLookUpServices = [
function origami(name) {
return getOrigamiModernizrNames(name);
},
function modernizr(name) {
return getListOfPolyFillsForModernizrTest(name);
}
];
// Apply the service to each polyfill name returning the transformed names.
function processListOfRequestedPolyfills(polyfills, service) {
// Map each name using the service, and flatten into a single array of names.
return polyfills.flatMap(function(polyfillName) {
// Gets an array of polyfills that match the name
return service(polyfillName);
}).filter(function(polyfill, position, self) {
// Filter out any duplicate polyfills
return self.indexOf(polyfill) == position;
});
}
function getPolyfills(polyfills) {
// Keep track of the currently transformed polyfills.
var transformedPolyfills = polyfills;
// Apply each service to the current list of transformed polyfill names.
polyfillLookUpServices.forEach(function(service) {
transformedPolyfills = processListOfRequestedPolyfills(transformedPolyfills, service);
});
// return the final list of transformed polyfill names
return transformedPolyfills;
}
getPolyfills(['es5array', 'requestanimationframe', 'o-gallery']);
// ["Array.prototype.every", "Array.prototype.filter", "Array.prototype.forEach", "Array.prototype.indexOf", "Array.prototype.lastIndexOf", "Array.prototype.map", "Array.prototype.some", "Array.prototype.reduce", "Array.prototype.reduceRight", "Array.isArray", "Window.requestAnimationFrame", "Document.prototype.querySelector", "Document.prototype.querySelectorAll"]
@wheresrhys
Copy link

This seems to avoid the need to hard code an alias list into the config json for a polyfill

I think this is a big benefit, partly because the aliasing is a property of e.g. Modernizr, Origami, not an intrinsic property of the polyfill. Also it makes it clearer what the relationships when it's not a one-to-one correspondence between a polyfill and an alias.

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