Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

autopolyfiller

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

autopolyfiller - npm Package Compare versions

Comparing version 1.0.10 to 1.1.0

.idea/jsLibraryMappings.xml

6

CHANGELOG.md

@@ -0,1 +1,7 @@

Version 1.1.0:
* considerably increased speed of polyfill scan by removing `grasp-equery`
* added ability to `.include()` & `.exclude()` polyfills #6
* improved polyfills scan. Now it can find square brackets expressions eg `""["trim"]()` #3
* improved polyfills scan. Now it can find padded expressions eg `new this.Promise()` or `window.atob()` #4
Version 1.0.10:

@@ -2,0 +8,0 @@ * polyfills for `requestAnimationFrame()`, `cancelAnimationFrame()`

19

lib/cli.js

@@ -66,3 +66,5 @@ var Command = require('commander').Command,

createPolyFiller: function () {
var browsers = this.program.browsers;
var browsers = this.program.browsers,
excludedPolyfills = this.program.exclude,
includedPolyfills = this.program.include;

@@ -76,3 +78,13 @@ this.log((function () {

return autopolyfiller(browsers);
if (includedPolyfills.length) {
this.log('Adding extra polyfills: ' + [''].concat(includedPolyfills).join('\n * '));
}
if (excludedPolyfills.length) {
this.log('Ignoring polyfills: ' + [''].concat(excludedPolyfills).join('\n * '));
}
return autopolyfiller(browsers)
.exclude(excludedPolyfills)
.include(includedPolyfills);
},

@@ -86,2 +98,4 @@

.option('-b, --browsers <names>', 'generate polyfills for these browsers', this._list.bind(this), [])
.option('-x, --exclude <polyfills>', 'exclude these polyfills', this._list.bind(this), [])
.option('-i, --include <polyfills>', 'include these polyfills', this._list.bind(this), [])
.option('-v, --verbose', 'verbose output')

@@ -94,2 +108,3 @@ .on('--help', function(){

' $ autopolyfiller -o polyfills.js script.js',
' $ autopolyfiller -o polyfills.js -i Promise -x Array.prototype.map script.js',
' $ autopolyfiller -b "last 1 version, > 1%, Explorer 7" lib/*.js vendors/**/*.js',

@@ -96,0 +111,0 @@ ' $ autopolyfiller lib/*.js !lib/lodash.js',

@@ -17,5 +17,7 @@ var scan = require('./polyfill-scan'),

* })
* .add('"".trim();Object.create();new Promise()')
* .exclude(['Object.create'])
* .include(['Array.prototype.map'])
* .add('"".trim();Object.create();new Promise();')
* .polyfills;
* // ['Promise']
* // ['Promise', 'Array.prototype.map']
*/

@@ -25,2 +27,3 @@ function AutoPolyFiller(options) {

this.polyfills = [];
this.excluedPolyfills = [];
}

@@ -80,5 +83,42 @@

this.include(polyfills.concat(polyfillsOfPolyfills));
return this;
},
/**
*
* @returns {string} code that polyfills all listed functions
*/
toString: function () {
return this.polyfills.map(function (polyfillName) {
var polyfillCode = code(polyfillName);
return wrap(polyfillCode, polyfillName);
}).join('');
},
/**
* Checks if `polyfill` is not in a `excluedPolyfills` list
*
* @param {String} polyfill
* @returns {Boolean}
* @private
*/
_isPolyfillIncluded: function (polyfill) {
return this.excluedPolyfills.indexOf(polyfill) === -1;
},
/**
* Adds `polyfills` to the list of required polyfills
*
* @param {String[]} polyfills
* @returns {AutoPolyFiller}
*/
include: function (polyfills) {
this.polyfills = this.polyfills
.concat(polyfills)
.concat(polyfillsOfPolyfills)
// Filter ignored polyfills
.filter(this._isPolyfillIncluded.bind(this))
// Make unique polyfills

@@ -89,2 +129,3 @@ .reduce(function (polyfills, polyfill) {

}
return polyfills;

@@ -97,10 +138,15 @@ }, []);

/**
* Ignores `polyfills`, excluded their code from result
*
* @returns {string} code that polyfills all listed functions
* @param {String[]} polyfills
* @returns {AutoPolyFiller}
*/
toString: function () {
return this.polyfills.map(function (polyfillName) {
var polyfillCode = code(polyfillName);
return wrap(polyfillCode, polyfillName);
}).join('');
exclude: function (polyfills) {
this.excluedPolyfills.push.apply(this.excluedPolyfills, polyfills);
// Filter ignored polyfills
this.polyfills = this.polyfills
.filter(this._isPolyfillIncluded.bind(this));
return this;
}

@@ -107,0 +153,0 @@ };

42

lib/polyfill-scan/matchers/constructor.js

@@ -1,2 +0,4 @@

var astQuery = require('grasp-equery').query;
var foldExpression = require('../../polyfill-expression-fold');
var grepExpressions = require('../grep-expression');
var matcher = require('../../polyfill-expression-matcher');

@@ -12,18 +14,26 @@ var constructors = {

/**
* @type {Function}
*/
var testConstructor = matcher('constructor', {
constructors: Object.keys(constructors)
});
/**
*
* @param {Object} ast
* @returns {String[]} list of polyfills in this ast
*/
exports.test = function (ast) {
var statements = astQuery('new __(_$)', ast);
/*{
type: 'NewExpression',
callee: {
type: 'Identifier',
name: 'Promise'
},
arguments: []
}*/
return statements.reduce(function (polyfils, statement) {
if (statement.callee && constructors.hasOwnProperty(statement.callee.name)) {
polyfils.push(constructors[statement.callee.name]);
}
return polyfils;
}, []);
return grepExpressions(ast)
.map(foldExpression)
.reduce(function (polyfills, list) {
var polyfill = constructors[testConstructor(list.join('.'))];
if (polyfill) {
polyfills.push(polyfill);
}
return polyfills;
}, []);
};

@@ -1,2 +0,4 @@

var astQuery = require('grasp-equery').query;
var foldExpression = require('../../polyfill-expression-fold');
var grepExpressions = require('../grep-expression');
var matcher = require('../../polyfill-expression-matcher');

@@ -11,250 +13,26 @@ var globalFunctions = {

var functionMethods = {
'bind': true,
'apply': true,
'call': true
};
/**
* @type {Function}
*/
var testMethod = matcher('global', {
methods: Object.keys(globalFunctions)
});
function match_MemberExpression_property_Identifier(statement) {
return statement.callee &&
statement.callee.type === 'MemberExpression' &&
/**
*
* @param {Object} ast
* @returns {String[]} list of polyfills in this ast
*/
exports.test = function (ast) {
return grepExpressions(ast)
.map(foldExpression)
.reduce(function (polyfills, list) {
var polyfill = globalFunctions[testMethod(list.join('.'))];
statement.callee.property &&
statement.callee.property.type === 'Identifier' &&
globalFunctions.hasOwnProperty(statement.callee.property.name);
}
function match_MemberExpression_object_Identifier(statement) {
return statement.callee &&
statement.callee.type === 'MemberExpression' &&
statement.callee.object &&
statement.callee.object.type === 'Identifier' &&
globalFunctions.hasOwnProperty(statement.callee.object.name);
}
function match_MemberExpression_MemberExpression_property_Identifier(statement) {
return statement.callee &&
statement.callee.type === 'MemberExpression' &&
statement.callee.object &&
statement.callee.object.type === 'MemberExpression' &&
statement.callee.object.property &&
statement.callee.object.property.type === 'Identifier' &&
globalFunctions.hasOwnProperty(statement.callee.object.property.name);
}
function match_CallExpression_functionMethod(statement) {
return statement.callee &&
statement.callee.property &&
statement.callee.property.type === 'Identifier' &&
functionMethods.hasOwnProperty(statement.callee.property.name);
}
var matchers = [
/*
btoa();
{
"type": "CallExpression",
"callee": {
"type": "Identifier",
"name": "btoa"
},
"arguments": []
}
*/
function (statement) {
if (statement.callee &&
statement.callee.type === 'Identifier' &&
globalFunctions.hasOwnProperty(statement.callee.name)) {
return globalFunctions[statement.callee.name];
}
},
/*
btoa.{call,apply,bind}();
{
"type": "CallExpression",
"callee": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "btoa"
},
"property": {
"type": "Identifier",
"name": "bind"
},
"computed": false
},
"arguments": []
}
*/
function (statement) {
if (match_MemberExpression_object_Identifier(statement) &&
match_CallExpression_functionMethod(statement)) {
return globalFunctions[statement.callee.object.name];
}
},
/*
window.btoa();
{
"type": "CallExpression",
"callee": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "window"
},
"property": {
"type": "Identifier",
"name": "btoa"
},
"computed": false
},
"arguments": []
}
*/
function (statement) {
if (match_MemberExpression_property_Identifier(statement) &&
statement.callee.object &&
statement.callee.object.type === 'Identifier' &&
statement.callee.object.name === 'window') {
return globalFunctions[statement.callee.property.name];
}
},
/*
this.btoa();
{
"type": "CallExpression",
"callee": {
"type": "MemberExpression",
"object": {
"type": "ThisExpression"
},
"property": {
"type": "Identifier",
"name": "btoa"
},
"computed": false
},
"arguments": []
}
*/
function (statement) {
if (match_MemberExpression_property_Identifier(statement) &&
statement.callee.object &&
statement.callee.object.type === 'ThisExpression') {
return globalFunctions[statement.callee.property.name];
}
},
/*
window.btoa.{call,apply,bind}();
{
"type": "CallExpression",
"callee": {
"type": "MemberExpression",
"object": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "window"
},
"property": {
"type": "Identifier",
"name": "btoa"
},
"computed": false
},
"property": {
"type": "Identifier",
"name": "call"
},
"computed": false
},
"arguments": []
}
*/
function (statement) {
if (match_MemberExpression_MemberExpression_property_Identifier(statement) &&
match_CallExpression_functionMethod(statement) &&
statement.callee.object.object.type === 'Identifier' &&
statement.callee.object.object.name === 'window') {
return globalFunctions[statement.callee.object.property.name];
}
},
/*
this.btoa.{call,apply,bind}();
{
"type": "CallExpression",
"callee": {
"type": "MemberExpression",
"object": {
"type": "MemberExpression",
"object": {
"type": "ThisExpression"
},
"property": {
"type": "Identifier",
"name": "btoa"
},
"computed": false
},
"property": {
"type": "Identifier",
"name": "call"
},
"computed": false
},
"arguments": []
}
*/
function (statement) {
if (match_MemberExpression_MemberExpression_property_Identifier(statement) &&
match_CallExpression_functionMethod(statement) &&
statement.callee.object.object.type === 'ThisExpression') {
return globalFunctions[statement.callee.object.property.name];
}
}
];
var expressions = {
CallExpression: function (polyfils, statement) {
// Tll first match
matchers.some(function (matcher) {
var polyfill = matcher(statement);
if (polyfill) {
polyfils.push(polyfill);
return true;
polyfills.push(polyfill);
}
});
return polyfils;
}
return polyfills;
}, []);
};
exports.test = function (ast) {
var statements = astQuery('__(_$)', ast);
return statements.reduce(function (polyfils, statement) {
return expressions[statement.type](polyfils, statement);
}, []);
};

@@ -1,2 +0,4 @@

var astQuery = require('grasp-equery').query;
var foldExpression = require('../../polyfill-expression-fold');
var grepExpressions = require('../grep-expression');
var matcher = require('../../polyfill-expression-matcher');

@@ -37,84 +39,26 @@ var methods = {

var functionMethods = {
'bind': true,
'apply': true,
'call': true
};
/**
* @type {Function}
*/
var testMethod = matcher('method', {
methods: Object.keys(methods)
});
function addTo(name, polyfils) {
var polyfillName = methods.hasOwnProperty(name) ? methods[name] : void 0;
if (polyfillName) {
polyfils.push(polyfillName);
}
}
/**
*
* @param {Object} ast
* @returns {String[]} list of polyfills in this ast
*/
exports.test = function (ast) {
var statements = astQuery('__.__(_$)', ast);
return grepExpressions(ast)
.map(foldExpression)
.reduce(function (polyfills, list) {
var polyfill = methods[testMethod(list.join('.'))];
/*{
"type": "CallExpression",
"callee": {
"type": "MemberExpression",
"object": {
"type": "Literal",
"value": "",
"raw": "\"\""
},
"property": {
"type": "Identifier",
"name": "trim"
},
"computed": false
},
"arguments": []
}
if (polyfill) {
polyfills.push(polyfill);
}
OR
{
"type": "CallExpression",
"callee": {
"type": "MemberExpression",
"object": {
"type": "MemberExpression",
"object": {
"type": "Literal",
"value": "",
"raw": "\"\""
},
"property": {
"type": "Identifier",
"name": "repeat"
},
"computed": false
},
"property": {
"type": "Identifier",
"name": "apply"
},
"computed": false
},
"arguments": [
]
}
*/
return statements.reduce(function (polyfils, statement) {
var name = statement.callee && statement.callee.property && statement.callee.property.name;
// in case of bind();
addTo(name, polyfils);
// in case of .call() .apply() or .bind() change method name
if (functionMethods.hasOwnProperty(name)) {
name = statement.callee &&
statement.callee.object &&
statement.callee.object.property &&
statement.callee.object.property.name;
addTo(name, polyfils);
}
return polyfils;
}, []);
return polyfills;
}, []);
};

@@ -1,2 +0,4 @@

var astQuery = require('grasp-equery').query;
var foldExpression = require('../../polyfill-expression-fold');
var grepExpressions = require('../grep-expression');
var matcher = require('../../polyfill-expression-matcher');

@@ -63,113 +65,39 @@ var statics = {

var functionMethods = {
'bind': true,
'apply': true,
'call': true
};
/**
* @type {Function}
*/
var testStatic = matcher('static', {
objects: Object.keys(statics).reduce(function (objects, object) {
objects[object] = Object.keys(statics[object]);
return objects;
}, {})
});
var expressions = {
/*
{
"type": "CallExpression",
"callee": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "Object"
},
"property": {
"type": "Identifier",
"name": "create"
},
"computed": false
},
"arguments": []
}
/**
* @type {Object}
*/
var expressionToPolyfillMap = Object.keys(statics).reduce(function (map, object) {
return Object.keys(statics[object]).reduce(function (map, method) {
map[object + '.' + method] = statics[object][method];
return map;
}, map);
}, {});
OR
/**
*
* @param {Object} ast
* @returns {String[]} list of polyfills in this ast
*/
exports.test = function (ast) {
return grepExpressions(ast)
.map(foldExpression)
.reduce(function (polyfills, list) {
var polyfill = expressionToPolyfillMap[testStatic(list.join('.'))];
{
"type": "CallExpression",
"callee": {
"type": "MemberExpression",
"object": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "JSON"
},
"property": {
"type": "Identifier",
"name": "parse"
},
"computed": false
},
"property": {
"type": "Identifier",
"name": "call"
},
"computed": false
},
"arguments": [
]
}
*/
CallExpression: function (polyfils, statement) {
var staticMethodName = statement.callee && statement.callee.property && statement.callee.property.name,
objectName = statement.callee && statement.callee.object && statement.callee.object.name;
if (polyfill) {
polyfills.push(polyfill);
}
// in case of .call() .apply() or .bind() change static method name and object name
if (functionMethods.hasOwnProperty(staticMethodName)) {
staticMethodName = statement.callee &&
statement.callee.object &&
statement.callee.object.property &&
statement.callee.object.property.name;
objectName = statement.callee &&
statement.callee.object &&
statement.callee.object.object &&
statement.callee.object.object.name;
}
var polyFillName = statics.hasOwnProperty(objectName) &&
statics[objectName].hasOwnProperty(staticMethodName) &&
statics[objectName][staticMethodName];
if (polyFillName) {
polyfils.push(polyFillName);
}
return polyfils;
},
/*
{
type: 'MemberExpression',
object: { type: 'Identifier', name: 'Object' },
property: { type: 'Identifier', name: 'create' },
computed: false
}
*/
MemberExpression: function (polyfils, statement) {
var staticMethodName = statement.property && statement.property.name,
objectName = statement.object && statement.object.name;
var polyFillName = statics.hasOwnProperty(objectName) &&
statics[objectName].hasOwnProperty(staticMethodName) &&
statics[objectName][staticMethodName];
if (polyFillName) {
polyfils.push(polyFillName);
}
return polyfils;
}
return polyfills;
}, []);
};
exports.test = function (ast) {
var statements = astQuery('__.__(_$)', ast).concat(astQuery('__.__', ast));
return statements.reduce(function (polyfils, statement) {
return expressions[statement.type](polyfils, statement);
}, []);
};

@@ -5,3 +5,3 @@ {

"keywords": ["polyfill", "polyfills", "dom", "ecmascript", "ecmascript5", "ecmascript6", "postprocessor"],
"version" : "1.0.10",
"version" : "1.1.0",
"author" : "Mikhail Davydov <i@azproduction.ru>",

@@ -23,3 +23,2 @@ "contributors" : [

"acorn": "~0.4.2",
"grasp-equery": "~0.2.0",
"autoprefixer": "1.1.x",

@@ -32,3 +31,5 @@ "debug": "~0.7.4",

"mkdirp": "~0.3.5",
"semver": "~2.2.1"
"semver": "~2.2.1",
"estraverse": "1.5.0",
"quotemeta": "0.0.0"
},

@@ -46,3 +47,5 @@ "devDependencies" : {

"mock-utf8-stream": "*",
"uglify-js": "*"
"uglify-js": "*",
"glob": "~3.2.9",
"grasp-equery": "~0.2.0"
},

@@ -56,4 +59,5 @@ "bin": {

"coverage": "make coverage",
"clean": "make clean"
"clean": "make clean",
"benchmark": "node ./benchmark/scan"
}
}

@@ -79,2 +79,16 @@ # Autopolyfiller — Precise polyfills

**Excluding/including polyfills**
```js
var autopolyfiller = require('autopolyfiller'),
autoprefixer = require('autopolyfiller');
autopolyfiller()
.exclude(['Promise'])
.include(['String.prototype.trim'])
.add('new My.Promise();')
.polyfills;
// ['String.prototype.trim']
```
**Custom polyfill matchers**

@@ -104,3 +118,3 @@

autopolyfiller()
.add('Object.create();Object.newFeature();');
.add('Object.create();Object.newFeature();')
.polyfills;

@@ -110,5 +124,5 @@ // ['Object.create', 'Object.newFeature']

autopolyfiller('Chrome >= 20')
.add('Object.create();Object.newFeature();');
.add('Object.create();Object.newFeature();')
.polyfills;
// []
```

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc