A very common practice is also something like that :
var func = (navigator.fooAPI.newFunc ||
navigator.fooAPI.oldFunc).bind(navigator.fooAPI)
The call to bind is optional if the func does not need to preserve the
context
The most famous example of such practice is this one :
https://gist.github.com/paulirish/1579671
Best
Jeremie
2013/10/17 Ehsan Akhgari <
ehsan....@gmail.com>
> On 2013-10-17 9:33 AM, Gene Lian wrote:
>
>> Just firing some thoughts about how to make the content safely call APIs
>> with backward compatibility. As you guys know, it'd be very painful to have
>> API changes and to keep the backward compatibility at the same time. For
>> example, if Gecko wants to modify an API like below:
>>
>> navigator.fooAPI.oldFunc(...) -> navigator.fooAPI.newFunc(...)
>>
>
> Is this a real use case? (It's still ok if it's just an abstract
> question!)
>
>
> To avoid breaking the compatibility, one of the possible solution is to
>> make the content side temporally check the presences of
>> functions/attributes to decide how to call the old/new APIs:
>>
>> if (newFunc in navigator.fooAPI) {
>> navigator.fooAPI.newFunc(...);
>> } else if (oldFunc in navigator.fooAPI) {
>> navigator.fooAPI.oldFunc(...);
>> }
>>
>> In this way, Gecko can safely deprecate the old APIs and Gaia can then
>> remove this kind of temporal logic. This might work when we have only few
>> functions/attributes under navigator.fooAPI. If we had many of them,
>> unfortunately, we'd have lots of run-time checks per function/attribute
>> basis, which doesn't look very clean and efficient. For example:
>>
>> if (newFunc_1 in navigator.fooAPI) {
>> navigator.fooAPI.newFunc_1(...**);
>> } else if (oldFunc_1 in navigator.fooAPI) {
>> navigator.fooAPI.oldFun_1(...)**;
>> }
>>
>> if (newFunc_2 in navigator.fooAPI) {
>> navigator.fooAPI.newFunc_2(...**);
>> } else if (oldFunc_2 in navigator.fooAPI) {
>> navigator.fooAPI.oldFun_2(...)**;
>> }
>>
>> ...
>>
>> if (newFunc_N in navigator.fooAPI) {
>> navigator.fooAPI.newFunc_N(...**);
>> } else if (oldFunc_N in navigator.fooAPI) {
>> navigator.fooAPI.oldFun_N(...)**;
>> }
>>
>> where N could be a big number.
>>
>
> I think you're assuming that API changes are always in simple "rename"
> forms. That's not necessarily the case, sometimes the semantics of the API
> needs to change in a way that makes this kind of mechanical case checking
> not work, and would sometimes make authors come up with completely separate
> code paths, or other ways of degrading the experience gracefully. I think
> the pattern you cite above is more common when handling vendor prefixed
> APIs.
>
>
> I wonder is that possible to provide a more generic way for the content
>> side to do API feature detection? Supposing each API can provide some
>> useful information like version number and can flip that number whenever
>> API is changed, then Gaia can have a cleaner way to switch to call the
>> corresponding APIs based on that version number:
>>
>> switch (navigator.getVersion(**navigator.fooAPI)) {
>> case 1:
>> navigator.fooAPI.oldFunc_1(...**);
>> navigator.fooAPI.oldFunc_2(...**);
>> ...
>> navigator.fooAPI.oldFunc_N(...**);
>> break;
>> case 2:
>> navigator.fooAPI.newFunc_1(...**);
>> navigator.fooAPI.newFunc_2(...**);
>> ...
>> navigator.fooAPI.newFunc_N(...**);
>> break;
>> }
>>
>> which considers the API feature set as a whole based on the version
>> information. I'm not sure if we used to discuss similar mechanisms or not.
>> Any thought is appreciated. :)
>>
>
> This is not really a webby way of doing things. The falsity check is the
> standard way of feature detection on the web, but it's mo commonly used for
> new features which are not yet available everywhere (or dealing with vendor
> prefixes) not for backwards compat.
>
> That being said, breaking backwards compat is always hard. If you have
> specific cases in mind, please let's discuss them concretely. This is the
> kind of discussion which may be a bit hard to have in the abstract!
>
> Cheers,
> Ehsan
>
>
> ______________________________**_________________
> dev-webapi mailing list
>
dev-w...@lists.mozilla.org
>
https://lists.mozilla.org/**listinfo/dev-webapi<
https://lists.mozilla.org/listinfo/dev-webapi>
>
--
Jeremie
.............................
Web :
http://jeremie.patonnier.net
Twitter : @JeremiePat <
http://twitter.com/JeremiePat>