massive update, probably broken
[dotfiles/.git] / .config / chromium / Default / Extensions / dmkamcknogkgcdfhhbddcghachkejeap / 0.9.10_0 / browser-polyfill.js
1 (function (global, factory) {
2   if (typeof define === "function" && define.amd) {
3     define("webextension-polyfill", ["module"], factory);
4   } else if (typeof exports !== "undefined") {
5     factory(module);
6   } else {
7     var mod = {
8       exports: {}
9     };
10     factory(mod);
11     global.browser = mod.exports;
12   }
13 })(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (module) {
14   /* webextension-polyfill - v0.7.0 - Tue Nov 10 2020 20:24:04 */
15
16   /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
17
18   /* vim: set sts=2 sw=2 et tw=80: */
19
20   /* This Source Code Form is subject to the terms of the Mozilla Public
21    * License, v. 2.0. If a copy of the MPL was not distributed with this
22    * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
23   "use strict";
24
25   if (typeof browser === "undefined" || Object.getPrototypeOf(browser) !== Object.prototype) {
26     const CHROME_SEND_MESSAGE_CALLBACK_NO_RESPONSE_MESSAGE = "The message port closed before a response was received.";
27     const SEND_RESPONSE_DEPRECATION_WARNING = "Returning a Promise is the preferred way to send a reply from an onMessage/onMessageExternal listener, as the sendResponse will be removed from the specs (See https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage)"; // Wrapping the bulk of this polyfill in a one-time-use function is a minor
28     // optimization for Firefox. Since Spidermonkey does not fully parse the
29     // contents of a function until the first time it's called, and since it will
30     // never actually need to be called, this allows the polyfill to be included
31     // in Firefox nearly for free.
32
33     const wrapAPIs = extensionAPIs => {
34       // NOTE: apiMetadata is associated to the content of the api-metadata.json file
35       // at build time by replacing the following "include" with the content of the
36       // JSON file.
37       const apiMetadata = {
38         "alarms": {
39           "clear": {
40             "minArgs": 0,
41             "maxArgs": 1
42           },
43           "clearAll": {
44             "minArgs": 0,
45             "maxArgs": 0
46           },
47           "get": {
48             "minArgs": 0,
49             "maxArgs": 1
50           },
51           "getAll": {
52             "minArgs": 0,
53             "maxArgs": 0
54           }
55         },
56         "bookmarks": {
57           "create": {
58             "minArgs": 1,
59             "maxArgs": 1
60           },
61           "get": {
62             "minArgs": 1,
63             "maxArgs": 1
64           },
65           "getChildren": {
66             "minArgs": 1,
67             "maxArgs": 1
68           },
69           "getRecent": {
70             "minArgs": 1,
71             "maxArgs": 1
72           },
73           "getSubTree": {
74             "minArgs": 1,
75             "maxArgs": 1
76           },
77           "getTree": {
78             "minArgs": 0,
79             "maxArgs": 0
80           },
81           "move": {
82             "minArgs": 2,
83             "maxArgs": 2
84           },
85           "remove": {
86             "minArgs": 1,
87             "maxArgs": 1
88           },
89           "removeTree": {
90             "minArgs": 1,
91             "maxArgs": 1
92           },
93           "search": {
94             "minArgs": 1,
95             "maxArgs": 1
96           },
97           "update": {
98             "minArgs": 2,
99             "maxArgs": 2
100           }
101         },
102         "browserAction": {
103           "disable": {
104             "minArgs": 0,
105             "maxArgs": 1,
106             "fallbackToNoCallback": true
107           },
108           "enable": {
109             "minArgs": 0,
110             "maxArgs": 1,
111             "fallbackToNoCallback": true
112           },
113           "getBadgeBackgroundColor": {
114             "minArgs": 1,
115             "maxArgs": 1
116           },
117           "getBadgeText": {
118             "minArgs": 1,
119             "maxArgs": 1
120           },
121           "getPopup": {
122             "minArgs": 1,
123             "maxArgs": 1
124           },
125           "getTitle": {
126             "minArgs": 1,
127             "maxArgs": 1
128           },
129           "openPopup": {
130             "minArgs": 0,
131             "maxArgs": 0
132           },
133           "setBadgeBackgroundColor": {
134             "minArgs": 1,
135             "maxArgs": 1,
136             "fallbackToNoCallback": true
137           },
138           "setBadgeText": {
139             "minArgs": 1,
140             "maxArgs": 1,
141             "fallbackToNoCallback": true
142           },
143           "setIcon": {
144             "minArgs": 1,
145             "maxArgs": 1
146           },
147           "setPopup": {
148             "minArgs": 1,
149             "maxArgs": 1,
150             "fallbackToNoCallback": true
151           },
152           "setTitle": {
153             "minArgs": 1,
154             "maxArgs": 1,
155             "fallbackToNoCallback": true
156           }
157         },
158         "browsingData": {
159           "remove": {
160             "minArgs": 2,
161             "maxArgs": 2
162           },
163           "removeCache": {
164             "minArgs": 1,
165             "maxArgs": 1
166           },
167           "removeCookies": {
168             "minArgs": 1,
169             "maxArgs": 1
170           },
171           "removeDownloads": {
172             "minArgs": 1,
173             "maxArgs": 1
174           },
175           "removeFormData": {
176             "minArgs": 1,
177             "maxArgs": 1
178           },
179           "removeHistory": {
180             "minArgs": 1,
181             "maxArgs": 1
182           },
183           "removeLocalStorage": {
184             "minArgs": 1,
185             "maxArgs": 1
186           },
187           "removePasswords": {
188             "minArgs": 1,
189             "maxArgs": 1
190           },
191           "removePluginData": {
192             "minArgs": 1,
193             "maxArgs": 1
194           },
195           "settings": {
196             "minArgs": 0,
197             "maxArgs": 0
198           }
199         },
200         "commands": {
201           "getAll": {
202             "minArgs": 0,
203             "maxArgs": 0
204           }
205         },
206         "contextMenus": {
207           "remove": {
208             "minArgs": 1,
209             "maxArgs": 1
210           },
211           "removeAll": {
212             "minArgs": 0,
213             "maxArgs": 0
214           },
215           "update": {
216             "minArgs": 2,
217             "maxArgs": 2
218           }
219         },
220         "cookies": {
221           "get": {
222             "minArgs": 1,
223             "maxArgs": 1
224           },
225           "getAll": {
226             "minArgs": 1,
227             "maxArgs": 1
228           },
229           "getAllCookieStores": {
230             "minArgs": 0,
231             "maxArgs": 0
232           },
233           "remove": {
234             "minArgs": 1,
235             "maxArgs": 1
236           },
237           "set": {
238             "minArgs": 1,
239             "maxArgs": 1
240           }
241         },
242         "devtools": {
243           "inspectedWindow": {
244             "eval": {
245               "minArgs": 1,
246               "maxArgs": 2,
247               "singleCallbackArg": false
248             }
249           },
250           "panels": {
251             "create": {
252               "minArgs": 3,
253               "maxArgs": 3,
254               "singleCallbackArg": true
255             },
256             "elements": {
257               "createSidebarPane": {
258                 "minArgs": 1,
259                 "maxArgs": 1
260               }
261             }
262           }
263         },
264         "downloads": {
265           "cancel": {
266             "minArgs": 1,
267             "maxArgs": 1
268           },
269           "download": {
270             "minArgs": 1,
271             "maxArgs": 1
272           },
273           "erase": {
274             "minArgs": 1,
275             "maxArgs": 1
276           },
277           "getFileIcon": {
278             "minArgs": 1,
279             "maxArgs": 2
280           },
281           "open": {
282             "minArgs": 1,
283             "maxArgs": 1,
284             "fallbackToNoCallback": true
285           },
286           "pause": {
287             "minArgs": 1,
288             "maxArgs": 1
289           },
290           "removeFile": {
291             "minArgs": 1,
292             "maxArgs": 1
293           },
294           "resume": {
295             "minArgs": 1,
296             "maxArgs": 1
297           },
298           "search": {
299             "minArgs": 1,
300             "maxArgs": 1
301           },
302           "show": {
303             "minArgs": 1,
304             "maxArgs": 1,
305             "fallbackToNoCallback": true
306           }
307         },
308         "extension": {
309           "isAllowedFileSchemeAccess": {
310             "minArgs": 0,
311             "maxArgs": 0
312           },
313           "isAllowedIncognitoAccess": {
314             "minArgs": 0,
315             "maxArgs": 0
316           }
317         },
318         "history": {
319           "addUrl": {
320             "minArgs": 1,
321             "maxArgs": 1
322           },
323           "deleteAll": {
324             "minArgs": 0,
325             "maxArgs": 0
326           },
327           "deleteRange": {
328             "minArgs": 1,
329             "maxArgs": 1
330           },
331           "deleteUrl": {
332             "minArgs": 1,
333             "maxArgs": 1
334           },
335           "getVisits": {
336             "minArgs": 1,
337             "maxArgs": 1
338           },
339           "search": {
340             "minArgs": 1,
341             "maxArgs": 1
342           }
343         },
344         "i18n": {
345           "detectLanguage": {
346             "minArgs": 1,
347             "maxArgs": 1
348           },
349           "getAcceptLanguages": {
350             "minArgs": 0,
351             "maxArgs": 0
352           }
353         },
354         "identity": {
355           "launchWebAuthFlow": {
356             "minArgs": 1,
357             "maxArgs": 1
358           }
359         },
360         "idle": {
361           "queryState": {
362             "minArgs": 1,
363             "maxArgs": 1
364           }
365         },
366         "management": {
367           "get": {
368             "minArgs": 1,
369             "maxArgs": 1
370           },
371           "getAll": {
372             "minArgs": 0,
373             "maxArgs": 0
374           },
375           "getSelf": {
376             "minArgs": 0,
377             "maxArgs": 0
378           },
379           "setEnabled": {
380             "minArgs": 2,
381             "maxArgs": 2
382           },
383           "uninstallSelf": {
384             "minArgs": 0,
385             "maxArgs": 1
386           }
387         },
388         "notifications": {
389           "clear": {
390             "minArgs": 1,
391             "maxArgs": 1
392           },
393           "create": {
394             "minArgs": 1,
395             "maxArgs": 2
396           },
397           "getAll": {
398             "minArgs": 0,
399             "maxArgs": 0
400           },
401           "getPermissionLevel": {
402             "minArgs": 0,
403             "maxArgs": 0
404           },
405           "update": {
406             "minArgs": 2,
407             "maxArgs": 2
408           }
409         },
410         "pageAction": {
411           "getPopup": {
412             "minArgs": 1,
413             "maxArgs": 1
414           },
415           "getTitle": {
416             "minArgs": 1,
417             "maxArgs": 1
418           },
419           "hide": {
420             "minArgs": 1,
421             "maxArgs": 1,
422             "fallbackToNoCallback": true
423           },
424           "setIcon": {
425             "minArgs": 1,
426             "maxArgs": 1
427           },
428           "setPopup": {
429             "minArgs": 1,
430             "maxArgs": 1,
431             "fallbackToNoCallback": true
432           },
433           "setTitle": {
434             "minArgs": 1,
435             "maxArgs": 1,
436             "fallbackToNoCallback": true
437           },
438           "show": {
439             "minArgs": 1,
440             "maxArgs": 1,
441             "fallbackToNoCallback": true
442           }
443         },
444         "permissions": {
445           "contains": {
446             "minArgs": 1,
447             "maxArgs": 1
448           },
449           "getAll": {
450             "minArgs": 0,
451             "maxArgs": 0
452           },
453           "remove": {
454             "minArgs": 1,
455             "maxArgs": 1
456           },
457           "request": {
458             "minArgs": 1,
459             "maxArgs": 1
460           }
461         },
462         "runtime": {
463           "getBackgroundPage": {
464             "minArgs": 0,
465             "maxArgs": 0
466           },
467           "getPlatformInfo": {
468             "minArgs": 0,
469             "maxArgs": 0
470           },
471           "openOptionsPage": {
472             "minArgs": 0,
473             "maxArgs": 0
474           },
475           "requestUpdateCheck": {
476             "minArgs": 0,
477             "maxArgs": 0
478           },
479           "sendMessage": {
480             "minArgs": 1,
481             "maxArgs": 3
482           },
483           "sendNativeMessage": {
484             "minArgs": 2,
485             "maxArgs": 2
486           },
487           "setUninstallURL": {
488             "minArgs": 1,
489             "maxArgs": 1
490           }
491         },
492         "sessions": {
493           "getDevices": {
494             "minArgs": 0,
495             "maxArgs": 1
496           },
497           "getRecentlyClosed": {
498             "minArgs": 0,
499             "maxArgs": 1
500           },
501           "restore": {
502             "minArgs": 0,
503             "maxArgs": 1
504           }
505         },
506         "storage": {
507           "local": {
508             "clear": {
509               "minArgs": 0,
510               "maxArgs": 0
511             },
512             "get": {
513               "minArgs": 0,
514               "maxArgs": 1
515             },
516             "getBytesInUse": {
517               "minArgs": 0,
518               "maxArgs": 1
519             },
520             "remove": {
521               "minArgs": 1,
522               "maxArgs": 1
523             },
524             "set": {
525               "minArgs": 1,
526               "maxArgs": 1
527             }
528           },
529           "managed": {
530             "get": {
531               "minArgs": 0,
532               "maxArgs": 1
533             },
534             "getBytesInUse": {
535               "minArgs": 0,
536               "maxArgs": 1
537             }
538           },
539           "sync": {
540             "clear": {
541               "minArgs": 0,
542               "maxArgs": 0
543             },
544             "get": {
545               "minArgs": 0,
546               "maxArgs": 1
547             },
548             "getBytesInUse": {
549               "minArgs": 0,
550               "maxArgs": 1
551             },
552             "remove": {
553               "minArgs": 1,
554               "maxArgs": 1
555             },
556             "set": {
557               "minArgs": 1,
558               "maxArgs": 1
559             }
560           }
561         },
562         "tabs": {
563           "captureVisibleTab": {
564             "minArgs": 0,
565             "maxArgs": 2
566           },
567           "create": {
568             "minArgs": 1,
569             "maxArgs": 1
570           },
571           "detectLanguage": {
572             "minArgs": 0,
573             "maxArgs": 1
574           },
575           "discard": {
576             "minArgs": 0,
577             "maxArgs": 1
578           },
579           "duplicate": {
580             "minArgs": 1,
581             "maxArgs": 1
582           },
583           "executeScript": {
584             "minArgs": 1,
585             "maxArgs": 2
586           },
587           "get": {
588             "minArgs": 1,
589             "maxArgs": 1
590           },
591           "getCurrent": {
592             "minArgs": 0,
593             "maxArgs": 0
594           },
595           "getZoom": {
596             "minArgs": 0,
597             "maxArgs": 1
598           },
599           "getZoomSettings": {
600             "minArgs": 0,
601             "maxArgs": 1
602           },
603           "goBack": {
604             "minArgs": 0,
605             "maxArgs": 1
606           },
607           "goForward": {
608             "minArgs": 0,
609             "maxArgs": 1
610           },
611           "highlight": {
612             "minArgs": 1,
613             "maxArgs": 1
614           },
615           "insertCSS": {
616             "minArgs": 1,
617             "maxArgs": 2
618           },
619           "move": {
620             "minArgs": 2,
621             "maxArgs": 2
622           },
623           "query": {
624             "minArgs": 1,
625             "maxArgs": 1
626           },
627           "reload": {
628             "minArgs": 0,
629             "maxArgs": 2
630           },
631           "remove": {
632             "minArgs": 1,
633             "maxArgs": 1
634           },
635           "removeCSS": {
636             "minArgs": 1,
637             "maxArgs": 2
638           },
639           "sendMessage": {
640             "minArgs": 2,
641             "maxArgs": 3
642           },
643           "setZoom": {
644             "minArgs": 1,
645             "maxArgs": 2
646           },
647           "setZoomSettings": {
648             "minArgs": 1,
649             "maxArgs": 2
650           },
651           "update": {
652             "minArgs": 1,
653             "maxArgs": 2
654           }
655         },
656         "topSites": {
657           "get": {
658             "minArgs": 0,
659             "maxArgs": 0
660           }
661         },
662         "webNavigation": {
663           "getAllFrames": {
664             "minArgs": 1,
665             "maxArgs": 1
666           },
667           "getFrame": {
668             "minArgs": 1,
669             "maxArgs": 1
670           }
671         },
672         "webRequest": {
673           "handlerBehaviorChanged": {
674             "minArgs": 0,
675             "maxArgs": 0
676           }
677         },
678         "windows": {
679           "create": {
680             "minArgs": 0,
681             "maxArgs": 1
682           },
683           "get": {
684             "minArgs": 1,
685             "maxArgs": 2
686           },
687           "getAll": {
688             "minArgs": 0,
689             "maxArgs": 1
690           },
691           "getCurrent": {
692             "minArgs": 0,
693             "maxArgs": 1
694           },
695           "getLastFocused": {
696             "minArgs": 0,
697             "maxArgs": 1
698           },
699           "remove": {
700             "minArgs": 1,
701             "maxArgs": 1
702           },
703           "update": {
704             "minArgs": 2,
705             "maxArgs": 2
706           }
707         }
708       };
709
710       if (Object.keys(apiMetadata).length === 0) {
711         throw new Error("api-metadata.json has not been included in browser-polyfill");
712       }
713       /**
714        * A WeakMap subclass which creates and stores a value for any key which does
715        * not exist when accessed, but behaves exactly as an ordinary WeakMap
716        * otherwise.
717        *
718        * @param {function} createItem
719        *        A function which will be called in order to create the value for any
720        *        key which does not exist, the first time it is accessed. The
721        *        function receives, as its only argument, the key being created.
722        */
723
724
725       class DefaultWeakMap extends WeakMap {
726         constructor(createItem, items = undefined) {
727           super(items);
728           this.createItem = createItem;
729         }
730
731         get(key) {
732           if (!this.has(key)) {
733             this.set(key, this.createItem(key));
734           }
735
736           return super.get(key);
737         }
738
739       }
740       /**
741        * Returns true if the given object is an object with a `then` method, and can
742        * therefore be assumed to behave as a Promise.
743        *
744        * @param {*} value The value to test.
745        * @returns {boolean} True if the value is thenable.
746        */
747
748
749       const isThenable = value => {
750         return value && typeof value === "object" && typeof value.then === "function";
751       };
752       /**
753        * Creates and returns a function which, when called, will resolve or reject
754        * the given promise based on how it is called:
755        *
756        * - If, when called, `chrome.runtime.lastError` contains a non-null object,
757        *   the promise is rejected with that value.
758        * - If the function is called with exactly one argument, the promise is
759        *   resolved to that value.
760        * - Otherwise, the promise is resolved to an array containing all of the
761        *   function's arguments.
762        *
763        * @param {object} promise
764        *        An object containing the resolution and rejection functions of a
765        *        promise.
766        * @param {function} promise.resolve
767        *        The promise's resolution function.
768        * @param {function} promise.rejection
769        *        The promise's rejection function.
770        * @param {object} metadata
771        *        Metadata about the wrapped method which has created the callback.
772        * @param {integer} metadata.maxResolvedArgs
773        *        The maximum number of arguments which may be passed to the
774        *        callback created by the wrapped async function.
775        *
776        * @returns {function}
777        *        The generated callback function.
778        */
779
780
781       const makeCallback = (promise, metadata) => {
782         return (...callbackArgs) => {
783           if (extensionAPIs.runtime.lastError) {
784             promise.reject(extensionAPIs.runtime.lastError);
785           } else if (metadata.singleCallbackArg || callbackArgs.length <= 1 && metadata.singleCallbackArg !== false) {
786             promise.resolve(callbackArgs[0]);
787           } else {
788             promise.resolve(callbackArgs);
789           }
790         };
791       };
792
793       const pluralizeArguments = numArgs => numArgs == 1 ? "argument" : "arguments";
794       /**
795        * Creates a wrapper function for a method with the given name and metadata.
796        *
797        * @param {string} name
798        *        The name of the method which is being wrapped.
799        * @param {object} metadata
800        *        Metadata about the method being wrapped.
801        * @param {integer} metadata.minArgs
802        *        The minimum number of arguments which must be passed to the
803        *        function. If called with fewer than this number of arguments, the
804        *        wrapper will raise an exception.
805        * @param {integer} metadata.maxArgs
806        *        The maximum number of arguments which may be passed to the
807        *        function. If called with more than this number of arguments, the
808        *        wrapper will raise an exception.
809        * @param {integer} metadata.maxResolvedArgs
810        *        The maximum number of arguments which may be passed to the
811        *        callback created by the wrapped async function.
812        *
813        * @returns {function(object, ...*)}
814        *       The generated wrapper function.
815        */
816
817
818       const wrapAsyncFunction = (name, metadata) => {
819         return function asyncFunctionWrapper(target, ...args) {
820           if (args.length < metadata.minArgs) {
821             throw new Error(`Expected at least ${metadata.minArgs} ${pluralizeArguments(metadata.minArgs)} for ${name}(), got ${args.length}`);
822           }
823
824           if (args.length > metadata.maxArgs) {
825             throw new Error(`Expected at most ${metadata.maxArgs} ${pluralizeArguments(metadata.maxArgs)} for ${name}(), got ${args.length}`);
826           }
827
828           return new Promise((resolve, reject) => {
829             if (metadata.fallbackToNoCallback) {
830               // This API method has currently no callback on Chrome, but it return a promise on Firefox,
831               // and so the polyfill will try to call it with a callback first, and it will fallback
832               // to not passing the callback if the first call fails.
833               try {
834                 target[name](...args, makeCallback({
835                   resolve,
836                   reject
837                 }, metadata));
838               } catch (cbError) {
839                 console.warn(`${name} API method doesn't seem to support the callback parameter, ` + "falling back to call it without a callback: ", cbError);
840                 target[name](...args); // Update the API method metadata, so that the next API calls will not try to
841                 // use the unsupported callback anymore.
842
843                 metadata.fallbackToNoCallback = false;
844                 metadata.noCallback = true;
845                 resolve();
846               }
847             } else if (metadata.noCallback) {
848               target[name](...args);
849               resolve();
850             } else {
851               target[name](...args, makeCallback({
852                 resolve,
853                 reject
854               }, metadata));
855             }
856           });
857         };
858       };
859       /**
860        * Wraps an existing method of the target object, so that calls to it are
861        * intercepted by the given wrapper function. The wrapper function receives,
862        * as its first argument, the original `target` object, followed by each of
863        * the arguments passed to the original method.
864        *
865        * @param {object} target
866        *        The original target object that the wrapped method belongs to.
867        * @param {function} method
868        *        The method being wrapped. This is used as the target of the Proxy
869        *        object which is created to wrap the method.
870        * @param {function} wrapper
871        *        The wrapper function which is called in place of a direct invocation
872        *        of the wrapped method.
873        *
874        * @returns {Proxy<function>}
875        *        A Proxy object for the given method, which invokes the given wrapper
876        *        method in its place.
877        */
878
879
880       const wrapMethod = (target, method, wrapper) => {
881         return new Proxy(method, {
882           apply(targetMethod, thisObj, args) {
883             return wrapper.call(thisObj, target, ...args);
884           }
885
886         });
887       };
888
889       let hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);
890       /**
891        * Wraps an object in a Proxy which intercepts and wraps certain methods
892        * based on the given `wrappers` and `metadata` objects.
893        *
894        * @param {object} target
895        *        The target object to wrap.
896        *
897        * @param {object} [wrappers = {}]
898        *        An object tree containing wrapper functions for special cases. Any
899        *        function present in this object tree is called in place of the
900        *        method in the same location in the `target` object tree. These
901        *        wrapper methods are invoked as described in {@see wrapMethod}.
902        *
903        * @param {object} [metadata = {}]
904        *        An object tree containing metadata used to automatically generate
905        *        Promise-based wrapper functions for asynchronous. Any function in
906        *        the `target` object tree which has a corresponding metadata object
907        *        in the same location in the `metadata` tree is replaced with an
908        *        automatically-generated wrapper function, as described in
909        *        {@see wrapAsyncFunction}
910        *
911        * @returns {Proxy<object>}
912        */
913
914       const wrapObject = (target, wrappers = {}, metadata = {}) => {
915         let cache = Object.create(null);
916         let handlers = {
917           has(proxyTarget, prop) {
918             return prop in target || prop in cache;
919           },
920
921           get(proxyTarget, prop, receiver) {
922             if (prop in cache) {
923               return cache[prop];
924             }
925
926             if (!(prop in target)) {
927               return undefined;
928             }
929
930             let value = target[prop];
931
932             if (typeof value === "function") {
933               // This is a method on the underlying object. Check if we need to do
934               // any wrapping.
935               if (typeof wrappers[prop] === "function") {
936                 // We have a special-case wrapper for this method.
937                 value = wrapMethod(target, target[prop], wrappers[prop]);
938               } else if (hasOwnProperty(metadata, prop)) {
939                 // This is an async method that we have metadata for. Create a
940                 // Promise wrapper for it.
941                 let wrapper = wrapAsyncFunction(prop, metadata[prop]);
942                 value = wrapMethod(target, target[prop], wrapper);
943               } else {
944                 // This is a method that we don't know or care about. Return the
945                 // original method, bound to the underlying object.
946                 value = value.bind(target);
947               }
948             } else if (typeof value === "object" && value !== null && (hasOwnProperty(wrappers, prop) || hasOwnProperty(metadata, prop))) {
949               // This is an object that we need to do some wrapping for the children
950               // of. Create a sub-object wrapper for it with the appropriate child
951               // metadata.
952               value = wrapObject(value, wrappers[prop], metadata[prop]);
953             } else if (hasOwnProperty(metadata, "*")) {
954               // Wrap all properties in * namespace.
955               value = wrapObject(value, wrappers[prop], metadata["*"]);
956             } else {
957               // We don't need to do any wrapping for this property,
958               // so just forward all access to the underlying object.
959               Object.defineProperty(cache, prop, {
960                 configurable: true,
961                 enumerable: true,
962
963                 get() {
964                   return target[prop];
965                 },
966
967                 set(value) {
968                   target[prop] = value;
969                 }
970
971               });
972               return value;
973             }
974
975             cache[prop] = value;
976             return value;
977           },
978
979           set(proxyTarget, prop, value, receiver) {
980             if (prop in cache) {
981               cache[prop] = value;
982             } else {
983               target[prop] = value;
984             }
985
986             return true;
987           },
988
989           defineProperty(proxyTarget, prop, desc) {
990             return Reflect.defineProperty(cache, prop, desc);
991           },
992
993           deleteProperty(proxyTarget, prop) {
994             return Reflect.deleteProperty(cache, prop);
995           }
996
997         }; // Per contract of the Proxy API, the "get" proxy handler must return the
998         // original value of the target if that value is declared read-only and
999         // non-configurable. For this reason, we create an object with the
1000         // prototype set to `target` instead of using `target` directly.
1001         // Otherwise we cannot return a custom object for APIs that
1002         // are declared read-only and non-configurable, such as `chrome.devtools`.
1003         //
1004         // The proxy handlers themselves will still use the original `target`
1005         // instead of the `proxyTarget`, so that the methods and properties are
1006         // dereferenced via the original targets.
1007
1008         let proxyTarget = Object.create(target);
1009         return new Proxy(proxyTarget, handlers);
1010       };
1011       /**
1012        * Creates a set of wrapper functions for an event object, which handles
1013        * wrapping of listener functions that those messages are passed.
1014        *
1015        * A single wrapper is created for each listener function, and stored in a
1016        * map. Subsequent calls to `addListener`, `hasListener`, or `removeListener`
1017        * retrieve the original wrapper, so that  attempts to remove a
1018        * previously-added listener work as expected.
1019        *
1020        * @param {DefaultWeakMap<function, function>} wrapperMap
1021        *        A DefaultWeakMap object which will create the appropriate wrapper
1022        *        for a given listener function when one does not exist, and retrieve
1023        *        an existing one when it does.
1024        *
1025        * @returns {object}
1026        */
1027
1028
1029       const wrapEvent = wrapperMap => ({
1030         addListener(target, listener, ...args) {
1031           target.addListener(wrapperMap.get(listener), ...args);
1032         },
1033
1034         hasListener(target, listener) {
1035           return target.hasListener(wrapperMap.get(listener));
1036         },
1037
1038         removeListener(target, listener) {
1039           target.removeListener(wrapperMap.get(listener));
1040         }
1041
1042       }); // Keep track if the deprecation warning has been logged at least once.
1043
1044
1045       let loggedSendResponseDeprecationWarning = false;
1046       const onMessageWrappers = new DefaultWeakMap(listener => {
1047         if (typeof listener !== "function") {
1048           return listener;
1049         }
1050         /**
1051          * Wraps a message listener function so that it may send responses based on
1052          * its return value, rather than by returning a sentinel value and calling a
1053          * callback. If the listener function returns a Promise, the response is
1054          * sent when the promise either resolves or rejects.
1055          *
1056          * @param {*} message
1057          *        The message sent by the other end of the channel.
1058          * @param {object} sender
1059          *        Details about the sender of the message.
1060          * @param {function(*)} sendResponse
1061          *        A callback which, when called with an arbitrary argument, sends
1062          *        that value as a response.
1063          * @returns {boolean}
1064          *        True if the wrapped listener returned a Promise, which will later
1065          *        yield a response. False otherwise.
1066          */
1067
1068
1069         return function onMessage(message, sender, sendResponse) {
1070           let didCallSendResponse = false;
1071           let wrappedSendResponse;
1072           let sendResponsePromise = new Promise(resolve => {
1073             wrappedSendResponse = function (response) {
1074               if (!loggedSendResponseDeprecationWarning) {
1075                 console.warn(SEND_RESPONSE_DEPRECATION_WARNING, new Error().stack);
1076                 loggedSendResponseDeprecationWarning = true;
1077               }
1078
1079               didCallSendResponse = true;
1080               resolve(response);
1081             };
1082           });
1083           let result;
1084
1085           try {
1086             result = listener(message, sender, wrappedSendResponse);
1087           } catch (err) {
1088             result = Promise.reject(err);
1089           }
1090
1091           const isResultThenable = result !== true && isThenable(result); // If the listener didn't returned true or a Promise, or called
1092           // wrappedSendResponse synchronously, we can exit earlier
1093           // because there will be no response sent from this listener.
1094
1095           if (result !== true && !isResultThenable && !didCallSendResponse) {
1096             return false;
1097           } // A small helper to send the message if the promise resolves
1098           // and an error if the promise rejects (a wrapped sendMessage has
1099           // to translate the message into a resolved promise or a rejected
1100           // promise).
1101
1102
1103           const sendPromisedResult = promise => {
1104             promise.then(msg => {
1105               // send the message value.
1106               sendResponse(msg);
1107             }, error => {
1108               // Send a JSON representation of the error if the rejected value
1109               // is an instance of error, or the object itself otherwise.
1110               let message;
1111
1112               if (error && (error instanceof Error || typeof error.message === "string")) {
1113                 message = error.message;
1114               } else {
1115                 message = "An unexpected error occurred";
1116               }
1117
1118               sendResponse({
1119                 __mozWebExtensionPolyfillReject__: true,
1120                 message
1121               });
1122             }).catch(err => {
1123               // Print an error on the console if unable to send the response.
1124               console.error("Failed to send onMessage rejected reply", err);
1125             });
1126           }; // If the listener returned a Promise, send the resolved value as a
1127           // result, otherwise wait the promise related to the wrappedSendResponse
1128           // callback to resolve and send it as a response.
1129
1130
1131           if (isResultThenable) {
1132             sendPromisedResult(result);
1133           } else {
1134             sendPromisedResult(sendResponsePromise);
1135           } // Let Chrome know that the listener is replying.
1136
1137
1138           return true;
1139         };
1140       });
1141
1142       const wrappedSendMessageCallback = ({
1143         reject,
1144         resolve
1145       }, reply) => {
1146         if (extensionAPIs.runtime.lastError) {
1147           // Detect when none of the listeners replied to the sendMessage call and resolve
1148           // the promise to undefined as in Firefox.
1149           // See https://github.com/mozilla/webextension-polyfill/issues/130
1150           if (extensionAPIs.runtime.lastError.message === CHROME_SEND_MESSAGE_CALLBACK_NO_RESPONSE_MESSAGE) {
1151             resolve();
1152           } else {
1153             reject(extensionAPIs.runtime.lastError);
1154           }
1155         } else if (reply && reply.__mozWebExtensionPolyfillReject__) {
1156           // Convert back the JSON representation of the error into
1157           // an Error instance.
1158           reject(new Error(reply.message));
1159         } else {
1160           resolve(reply);
1161         }
1162       };
1163
1164       const wrappedSendMessage = (name, metadata, apiNamespaceObj, ...args) => {
1165         if (args.length < metadata.minArgs) {
1166           throw new Error(`Expected at least ${metadata.minArgs} ${pluralizeArguments(metadata.minArgs)} for ${name}(), got ${args.length}`);
1167         }
1168
1169         if (args.length > metadata.maxArgs) {
1170           throw new Error(`Expected at most ${metadata.maxArgs} ${pluralizeArguments(metadata.maxArgs)} for ${name}(), got ${args.length}`);
1171         }
1172
1173         return new Promise((resolve, reject) => {
1174           const wrappedCb = wrappedSendMessageCallback.bind(null, {
1175             resolve,
1176             reject
1177           });
1178           args.push(wrappedCb);
1179           apiNamespaceObj.sendMessage(...args);
1180         });
1181       };
1182
1183       const staticWrappers = {
1184         runtime: {
1185           onMessage: wrapEvent(onMessageWrappers),
1186           onMessageExternal: wrapEvent(onMessageWrappers),
1187           sendMessage: wrappedSendMessage.bind(null, "sendMessage", {
1188             minArgs: 1,
1189             maxArgs: 3
1190           })
1191         },
1192         tabs: {
1193           sendMessage: wrappedSendMessage.bind(null, "sendMessage", {
1194             minArgs: 2,
1195             maxArgs: 3
1196           })
1197         }
1198       };
1199       const settingMetadata = {
1200         clear: {
1201           minArgs: 1,
1202           maxArgs: 1
1203         },
1204         get: {
1205           minArgs: 1,
1206           maxArgs: 1
1207         },
1208         set: {
1209           minArgs: 1,
1210           maxArgs: 1
1211         }
1212       };
1213       apiMetadata.privacy = {
1214         network: {
1215           "*": settingMetadata
1216         },
1217         services: {
1218           "*": settingMetadata
1219         },
1220         websites: {
1221           "*": settingMetadata
1222         }
1223       };
1224       return wrapObject(extensionAPIs, staticWrappers, apiMetadata);
1225     };
1226
1227     if (typeof chrome != "object" || !chrome || !chrome.runtime || !chrome.runtime.id) {
1228       throw new Error("This script should only be loaded in a browser extension.");
1229     } // The build process adds a UMD wrapper around this file, which makes the
1230     // `module` variable available.
1231
1232
1233     module.exports = wrapAPIs(chrome);
1234   } else {
1235     module.exports = browser;
1236   }
1237 });
1238 //# sourceMappingURL=browser-polyfill.js.map