GithubHelp home page GithubHelp logo

financial-times / polyfill-service Goto Github PK

View Code? Open in Web Editor NEW
7.4K 238.0 792.0 116.82 MB

Automatic polyfill service.

Home Page: https://polyfill.io/

License: MIT License

origami service systemcode-origami-polyfill-service polyfill-service polyfill

polyfill-service's Introduction

logo

Polyfill.io is a service which makes web development less frustrating by selectively polyfill just what the browser needs. Polyfill.io reads the User-Agent header of each request and returns polyfill that are suitable for the requesting browser.

English | 中文 | 日本語 | Tiếng Việt | española | française | Português | বাংলা | Deutsch | हिंदी

Announcement

We have transitioned to utilizing Cloudflare as our Content Delivery Network (CDN) provider. We apologize for any inconvenience that may have arisen during this migration period. Please rest assured that we will continue to offer the polyfill service at no cost.

Documentation

Polyfill.io documentation is on the website.

Read our contributing guide to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes.

Self-Hosting

https://github.com/jakeChampion/polyfill-service-self-hosted/

License

Polyfill.io is licensed under the terms of the MIT license. Contributors must accept our contribution terms.

polyfill-service's People

Contributors

actions-user avatar apaleslimghost avatar callumlocke avatar caridy avatar casao avatar chee avatar christophehurpeau avatar dependabot-preview[bot] avatar dependabot[bot] avatar falsandtru avatar hannesj avatar ikkyu-os avatar jakechampion avatar jkimbo avatar jonathan-fielding avatar jonathantneal avatar juandopazo avatar kaelig avatar maapteh avatar matthew-andrews avatar monolithed avatar notlee avatar polyfillpolyfill avatar ruiaraujo avatar samgiles avatar tejacques avatar tom-parker avatar triblondon avatar tuukka avatar wheresrhys avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

polyfill-service's Issues

improve es5/6 shims

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:

polyfills/Array.isArray:

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.

Avoid duplicating polyfills already maintained elsewhere?

@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:

  • are not consistently packaged
  • polyfill not just the thing they are for but all their dependent APIs too, resulting in multiple polyfills on the same page potentially duplicating the polyfilling of lower-level APIs
  • require developers to know that a polyfill is needed
  • typically do not offer an easy method of only shipping the polyfill to browsers that lack a native implementation.

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.

requestAnimationFrame falls back directly to setTimeout

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

Unit tests

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:

  • XMLHTTPRequest
  • CustomEvent
  • devicePixelRatio

And of course the big ie7 polyfill.

Promises polyfill is not configured for any UAs

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

Feature groups

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.

Respect dependency relationships in sorting polyfills

@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,

Function.prototype.bind

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'))

matches isn't delivered to ie9

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?

Alias resolution logic

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.

Create feature detection rules for each Polyfill

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.

Provide caniuse-style tables in docs

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.

Include Cache-Control in API response

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

Remove html5shiv

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.

Test framework to check feature-detects

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.

Is browser inclusive or exclusive?

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?

Version the API endpoint

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.

Effect of dependency features that are polyfillable on effective range of dependent polyfills

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?

Set up hosting

Liaise with the FT integration engineering team and get a production environment for this.

Make an Origami alias resolver

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:

  1. Look up the module reference using the Origami build service metadata API
  2. Use the browserFeatures section of origami.json to get feature names
  3. Return those features, for subsequent alias resolvers

Establish canonical browser family names

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.

Implement feature gating flags

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:

  • #4 Create feature detect rules for each polyfill

Should DOMTokenList stop depending on Array.prototype.indexOf?

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):

  1. Keep it as is
  2. utilize trim (to reduce code duplication) and list it as a dependency
  3. make it more standalone by dropping the dependency on Array.prototype.indexOf

Serve permissive CORS response headers

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: *

Object.getOwnPropertyNames

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.

IndexedDB

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.

Decide how to deal with browser-specific polyfill variants when `always` is used

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?

Add licence info to bundle header

The bundle header is outputting LICENCE TODO. Replace this with the licence specified in the config file, or CC0 if not specified.

Define 'polyfill' and evaluate each existing polyfill against this definition.

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.