polyfillpolyfill / polyfill-service Goto Github PK
View Code? Open in Web Editor NEWAutomatic polyfill service.
Home Page: https://polyfill.io/
License: MIT License
Automatic polyfill service.
Home Page: https://polyfill.io/
License: MIT License
I think there might be a need to define what a polyfill is and then evaluate each polyfill against this definition.
This stems from the AudioContext polyfill, it doesn't polyfill a missing API, it simply un-prefixes and normalises the API to the current spec. Can this be considered a polyfill? If it can, what behaviour should we define for 'non-polyfillable' APIs on browsers that are unsupported? Can say we can guarantee a feature if we have it as a polyfill and it is requested?
Each polyfill in the source directory has a config.json. In each config, if applicable, a Modernizr test name should be specified. So for each polyfill explicitly tested by a Modernizr test, an alias should be created in the form: modernizr:testname
.
See https://github.com/Financial-Times/polyfill-service/blob/master/source/Array.isArray/config.json for an example.
Conform to https://docs.google.com/a/ft.com/document/d/11paOrAIl9eIOqUEERc9XMaaL3zouJDdkmb-gExYFnw0/edit to expose backend health for routing decisions.
Could I request that an IndexedDB polyfill be added (that uses WebSQL as an underlying storage tech if IDB is not available)? [Perhaps - as it is quite big - one that is only added when it is explicitly requested, ie. http://polyfill.io/maybe/indexeddb ]
(The use case of the optional-ness of it would be just that such a polyfill is likely to be huge and [for most people] unwanted)
http://nparashuram.com/IndexedDBShim/
Also the IndexedDB wrapper could be handy for 'smoothing over the differences' in IDB implementations across browsers.
We're unclear currently on what the useragent module classifies browser families as, so we need to establish a canonical set of names, using either theirs, or caniuse's list, so that we can update documentation on how to reference browser families in polyfill configs.
It is now a modernizr test too: 'customevent'
Implement the feature gating flags. For each alias or polyfill, if the 'gated' flag is set, return a gated version of the polyfill.
For example:
The request /polyfill.js?default=Array.prototype.forEach|gated
would return a gated forEach
polyfill where the feature is detected before being polyfilled:
// Feature Gated (detect.js = Array.prototype.forEach)
if (!(Array.prototype.forEach)) { Array.prototype.forEach = function forEach(x) { ... } };
// Not Feature Gated
Array.prototype.forEach = function forEach(x) { ... };
Dependencies:
The bundle header is outputting LICENCE TODO. Replace this with the licence specified in the config file, or CC0 if not specified.
On / and /v1, serve a page that documents the API, similar to http://image.webservices.ft.com/v1/.
Appears to be only suitable for IE8.
Add a command line option to the server to allow the specification of the port number to listen on. For example:
node app.js --port=8080
I'd like to see some kind of very basic rendering of caniuse data with polyfilled browsers on top, so you can see which browsers we can't support at all vs which ones we are supporting with a polyfill vs which have the feature natively.
Patrick Kettner notes in the Google doc that he would prefer not to have the index of included polyfills output in prod. I'd have it on, personally, so it seems there's a reason to make it configurable.
Instead of requiring each polyfill to be assigned browser versions manually we should use the
caniuse-db
data to keep the browser support up to date.
RAF at https://github.com/Financial-Times/polyfill-service/blob/master/polyfills/requestAnimationFrame/polyfill.js will polyfill directly to setTimeout without checking if vendor browser prefixed implementations are available: webkitRequestAnimationFrame, moz, ms.
Wouldn't Paul Irish poly from https://gist.github.com/paulirish/1579671 be better by taking some load off, in cases that there is still a native implementation but prefixed? Am I missing something?
Thanks
I've revised the bundle header comment and changed the lib so that the aliases and request URL are no longer passed from the service to the lib. But although modernizr:es5array gets expanded to the correct set of polyfills, aliases are not coming out when I need to produce the bundle and all the aliasOf elements are undefined.
I'm afraid the architecture of aliases.js is baffling me. I might need to improve my JS but I can't help feeling this could be simpler. And it does feel wrong that the default alias resolver needs to be constructed from index.js - shouldn't we encapsulate all alias related functionality inside the aliases module?
Anyway, a walkthough at least would be appreciated :-) My work is in the bundle-header branch.
Would there be interest in an Object.getOwnPropertyNames
polyfill that returns non-enumerable properties in IE6-8 by “memorizing” them? While it’s possible, I’m not convinced it’s useful.
For instance, if we want to get all property names in a plain Object, in addition to finding enumerable properties using for (key in object)
, we can manually check if constructor
, toString
, toLocaleString
, valueOf
, hasOwnProperty
, isPrototypeOf
, or propertyIsEnumerable
are present.
Comply with https://docs.google.com/a/ft.com/document/d/18hefJjImF5IFp9WvPAm9Iq5_GmWzI9ahlKSzShpQl1s/edit.
Since the app is largely self contained and doesn't have any external services, I can't immediately think of what checks we'd have, but we should at least have something, even if it's just 'server is up'.
This is not ideal, particularly as freegeoip.net is currently down.
Alternatives:
http://polyfill.webservices.ft.com/v1/polyfill.min.js?features=Element.prototype.matches
/* /v1/polyfill.min.js?features=Element.prototype.matches
* Detected ie/9.0.0
*/
http://caniuse.com/matchesselector
What's the logic here. ie9 has matchesSelector
but the polyfill does nothing along the lines of testing for non standard implementations, delegating it to other polyfills e.g. https://github.com/Financial-Times/polyfill-service/blob/master/polyfills/Element.prototype.matches.webkit/polyfill.js
Why aren't these checks for prefixed/non-standard implementations of matches running in ie9?
To avoid encouraging users to send fake UA headers, we should accept a 'ua' query argument which, if present, overrides the HTTP header.
Actually this is not a polyfill. When the returned function by bind is called as: new (String.bind('test'));
then it's called the [[Construct]] method of the bound function. Since built-in constructors has overloaded behavior depends on its calling, your polyfill is not reliable. If you don't sure, try this: new (String.bind('test')) === new (String.bind('test'))
Allow use from the browser for all origins. Clients may wish to download a polyfill bundle using AJAX and store it locally in localstorage for offline applications, or predictively pre-cache required resources for later use.
Access-Control-Allow-Origin: *
Response must be opinionated about its cacheability. My first-stab proposal is that all polyfills return:
Vary: User-Agent
Cache-Control: public, max-age=3600
Liaise with the FT integration engineering team and get a production environment for this.
If we can understand what Jonathan's solution in Window.polyfill
does, we'll probably realise that we didn't need to add html5shim as a separate polyfill.
Awesome service, one question/issue from what I understand the gated
flag should be used to either show the polyfill or not and resolve to the native api...
However when using the following http://cdn.polyfill.io/v1/polyfill.js?features=Promise|gated
in safari the polyfill is empty but safari 7.0.6
does not have a native promise support...
I am missing something?
Thanks for the help
-David
I currently maintain the Object.observe polyfill at (https://github.com/jdarling/Object.observe) and will gladly create a PR to add it to the list, but I'm not sure how exactly the browsers section in the config.json file should look.
As far as I know (and from testing) Object.observe is only available in Chrome 36+.
So, how should the browser section look?
@Bockit says:
If the topological dependency sorting is something you'd also be interested in then it would be worth keeping in mind how the dependencies part of the config objects would work (or not work, it may be fine just leaving them as is) with these databases to avoid circular dependencies.
So we need to ensure that any dependencies listed in config.json
are included in the bundle, and ordered so they come before the polyfill that is dependent on them,
The shims offered by polyfill-service are a bit rough around the edges in terms of being on par with the usual es5/es6 shims. Perhaps you could team up with es-shims (@ljharb, @mathiasbynens, and friends) to audit the existing shims or transition to using those provided by es-shims.
Simple examples:
Array.isArray(""); // => returns "" instead of `false`
polyfills/Array.prototype.forEach:
Array(1).forEach(alert); // => should not alert, but does
It would be rad if you also indicated which polyfills are only partial-fills, like Object.create
and Object.defineProperty
. The es-shims folks call them "shams", instead of "shims", and give developers a heads up on any usage restrictions they may have.
Comply with http://origami.ft.com/docs/syntax/origamijson/
Each polyfill should contain a detect.js
file containing a single Javascript expression which would evaluate to false if the polyfill is not detected and true if it's present in the browser.
For example:
The expression Array.prototype.forEach
will evaluate as falsey if it is undefined.
In #72, @jonathantneal raised the issue that while we've updated the DOMTokenList polyfill to remove the trim() dependency, we still have an Array indexOf dependency. That's an inconsistent approach. Should we (copying Jonathan's options):
Comply with http://origami.ft.com/docs/syntax/metrics/.
Suggested metrics:
Polyfill API endpoint should be on /v1/polyfill rather than /polyfill, to comply with Origami spec and allow for future breaking changes to the API to maintain legacy service.
When we set the browser versions to which we are going to serve a polyfill, we should set the upper limit to the last version before the feature was implemented natively, and the lower limit to the first version that has all the features on which the polyfill depends.
However, say feature A's polyfill depends on feature B, and we develop a polyfill for B. We can now extend the range of polyfill A at the lower end to encompass browsers in which we can polyfill feature B, provided that the lack of B was what was constraining the range of browsers in which we could run A.
Currently, this is accomplished by manually setting the range on A's polyfill, knowing that we have a polyfill for B and requiring that B's polyfill is also included if required. Is this good enough? Is there a smarter way?
By default each polyfill specified in the features
argument should be conditionally included based on the UA. If an always
flag is appended to a polyfill string in the URL then the polyfill should always be included (identical to gimme
and the current default
query string implementation).
See 0db3060 for an example.
Hello,
This library looks really cool. Do you support IEs with a document mode set?
/t
While it worked just fine yesterday, I now get a 'Out of stack space' error in IE8 caused by the Object.defineProperty(.ie8) polyfill on this line: return defineProperty(object, property, descriptor);
When the file extension is .css
the CSS polyfills should be looked up and returned.
This is based on the data in: https://github.com/jonathantneal/polyfill/blob/master/agent.css.json and https://github.com/jonathantneal/polyfill/blob/master/normalize.json
These should additionally be assigned equivalent Modernizr aliases where appropriate.
We need some tests. The first step seems to be to choose a test runner (Mocha?) and connect it to Sauce Labs, using their open sauce service to run each polyfill and check the feature-detect returns true in all the browsers that config.json shows to be polyfillable.
I think we should add the concept of a feature group, so that large organisations (ahem, us) with lots of products can advocate a single, simple tag that all products should include unconditionally, eg:
/polyfills.min.js?features=group:ft-origami
This would expand inside the polyfill server into a list of features that can be defined in the server, so that we can roll out a polyfill to lots of sites at once.
See https://github.com/Financial-Times/o-hierarchical-nav/issues/14#issuecomment-49010161 for rationale.
In jonathantneal#43, Jonathan defines the prollyfill
and gives an example of the linked polyfill 'matches'. The polyfill is in various states of implementation, some browsers don't have it and never will, others implement with a different name (e.g IE 9 matchesSelector [#57]) (see polyfills/Element.prototype.matches.ms
) and others have it. Currently these linked polyfills aren't served. The current implementation in Jonathan's repo makes this quite easy to implement: 'https://github.com/jonathantneal/polyfill/blob/master/agent.js.json', each browser has a list of versions, and each version has a list of names of polyfills to use. Now that this logic is contained in config.json for each polyfill, it becomes slightly more difficult to decide what to include and how for each browser as the config for each browser is split across configurations.
I think the ideal logic would be - when requesting Element.prototype.matches
from a browser that requires one of these linked implementations the correct linked implementation is selected and served based on the UA. The problem with this however is that when Element.prototype.matches|always
is requested you can't easily say which linked implementation is the most appropriate to serve, but we need to serve something!
We could say that top level polyfill X
is the default polyfill to include if the 'always' flag is specified, else, look at the linked polyfills in a linked
property in the config.json and include based on UA? Alternatively we could bring all the logic for applying the polyfill into a single file and do feature detection case by case.
I'd like to canvas some opinion on this one. @jonathantneal @triblondon any thoughts?
Right now the FT app fixes broken localStorage implementations (eg. on iOS private browsing mode). with a library called 'superstore' - https://github.com/matthew-andrews/superstore
Could there a way to deal with this via Polyfill?
Add an alias resolver that, faced with a feature list such as:
polyfills.min.js?features=ft-origami:o-grid^2.0.0
would do the following:
browserFeatures
section of origami.json to get feature names@jdalton raised on #86 (comment) the issue that we are duplicating work by reimplementing polyfills maintained by others elsewhere, such as the es6shim project.
The reasons this project exists are that things like es6shim:
However, it makes sense to avoid duplicating work, and we don't want to upset anyone who has the generosity to publish and maintain these polyfills, so I'm open to suggestions for how we could reach our objectives in a way that is more effective for the whole community.
With #75 we can set up some basic test scaffolding and get some benefits without actually writing any dedicated tests for each polyfill. But we need to start thinking about testing the full API of each one.
This requires some thought because a lot of the browser features being polyfilled are quite hard to test, eg:
And of course the big ie7 polyfill.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.