{"action":"created","comment":{"url":"https://api.github.com/repos/mozilla/webextension-polyfill/pulls/comments/82378005","pull_request_review_id":3271087,"id":82378005,"diff_hunk":"@@ -0,0 +1,340 @@\n+/* @@package_name - v@@version - @@timestamp */\n+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */\n+/* vim: set sts=2 sw=2 et tw=80: */\n+/* This Source Code Form is subject to the terms of the Mozilla Public\n+ * License, v. 2.0. If a copy of the MPL was not distributed with this\n+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\n+\"use strict\";\n+\n+if (typeof browser === \"undefined\") {\n+  // Wrapping the bulk of this polyfill in a one-time-use function is a minor\n+  // optimization for Firefox. Since Spidermonkey does not fully parse the\n+  // contents of a function until the first time it's called, and since it will\n+  // never actually need to be called, this allows the polyfill to be included\n+  // in Firefox nearly for free.\n+  const wrapAPIs = () => {\n+    const apiMetadata = {/* include(\"api-metadata.json\") */};\n+\n+    /**\n+     * A WeakMap subclass which creates and stores a value for any key which does\n+     * not exist when accessed, but behaves exactly as an ordinary WeakMap\n+     * otherwise.\n+     *\n+     * @param {function} createItem\n+     *        A function which will be called in order to create the value for any\n+     *        key which does not exist, the first time it is accessed. The\n+     *        function receives, as its only argument, the key being created.\n+     */\n+    class DefaultWeakMap extends WeakMap {\n+      constructor(createItem, items = undefined) {\n+        super(items);\n+        this.createItem = createItem;\n+      }\n+\n+      get(key) {\n+        if (!this.has(key)) {\n+          this.set(key, this.createItem(key));\n+        }\n+\n+        return super.get(key);\n+      }\n+    }\n+\n+    /**\n+     * Returns true if the given object is an object with a `then` method, and can\n+     * therefore be assumed to behave as a Promise.\n+     *\n+     * @param {*} value The value to test.\n+     * @returns {boolean} True if the value is thenable.\n+     */\n+    const isThenable = value => {\n+      return value && typeof value === \"object\" && typeof value.then === \"function\";\n+    };\n+\n+    /**\n+     * Creates and returns a function which, when called, will resolve or reject\n+     * the given promise based on how it is called:\n+     *\n+     * - If, when called, `chrome.runtime.lastError` contains a non-null object,\n+     *   the promise is rejected with that value.\n+     * - If the function is called with exactly one argument, the promise is\n+     *   resolved to that value.\n+     * - Otherwise, the promise is resolved to an array containing all of the\n+     *   function's arguments.\n+     *\n+     * @param {object} promise\n+     *        An object containing the resolution and rejection functions of a\n+     *        promise.\n+     * @param {function} promise.resolve\n+     *        The promise's resolution function.\n+     * @param {function} promise.rejection\n+     *        The promise's rejection function.\n+     *\n+     * @returns {function}\n+     *        The generated callback function.\n+     */\n+    const makeCallback = promise => {\n+      return (...callbackArgs) => {\n+        if (chrome.runtime.lastError) {\n+          promise.reject(chrome.runtime.lastError);\n+        } else if (callbackArgs.length === 1) {\n+          promise.resolve(callbackArgs[0]);\n+        } else {\n+          promise.resolve(callbackArgs);\n+        }\n+      };\n+    };\n+\n+    /**\n+     * Creates a wrapper function for a method with the given name and metadata.\n+     *\n+     * @param {string} name\n+     *        The name of the method which is being wrapped.\n+     * @param {object} metadata\n+     *        Metadata about the method being wrapped.\n+     * @param {integer} metadata.minArgs\n+     *        The minimum number of arguments which must be passed to the\n+     *        function. If called with fewer than this number of arguments, the\n+     *        wrapper will raise an exception.\n+     * @param {integer} metadata.maxArgs\n+     *        The maximum number of arguments which may be passed to the\n+     *        function. If called with more than this number of arguments, the\n+     *        wrapper will raise an exception.\n+     *\n+     * @returns {function(object, ...*)}\n+     *       The generated wrapper function.\n+     */\n+    const wrapAsyncFunction = (name, metadata) => {\n+      return function asyncFunctionWrapper(target, ...args) {\n+        if (args.length < metadata.minArgs) {\n+          throw new Error(`Expected at least ${metadata.minArgs} arguments for ${name}(), got ${args.length}`);\n+        }\n+\n+        if (args.length > metadata.maxArgs) {\n+          throw new Error(`Expected at most ${metadata.maxArgs} arguments for ${name}(), got ${args.length}`);\n+        }\n+\n+        return new Promise((resolve, reject) => {\n+          target[name](...args, makeCallback({resolve, reject}));\n+        });\n+      };\n+    };\n+\n+    /**\n+     * Wraps an existing method of the target object, so that calls to it are\n+     * intercepted by the given wrapper function. The wrapper function receives,\n+     * as its first argument, the original `target` object, followed by each of\n+     * the arguments passed to the orginal method.\n+     *\n+     * @param {object} target\n+     *        The original target object that the wrapped method belongs to.\n+     * @param {function} method\n+     *        The method being wrapped. This is used as the target of the Proxy\n+     *        object which is created to wrap the method.\n+     * @param {function} wrapper\n+     *        The wrapper function which is called in place of a direct invocation\n+     *        of the wrapped method.\n+     *\n+     * @returns {Proxy<function>}\n+     *        A Proxy object for the given method, which invokes the given wrapper\n+     *        method in its place.\n+     */\n+    const wrapMethod = (target, method, wrapper) => {\n+      return new Proxy(method, {\n+        apply(targetMethod, thisObj, args) {\n+          return wrapper.call(thisObj, target, ...args);\n+        },\n+      });\n+    };\n+\n+    let hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);\n+\n+    /**\n+     * Wraps an object in a Proxy which intercepts and wraps certain methods\n+     * based on the given `wrappers` and `metadata` objects.\n+     *\n+     * @param {object} target\n+     *        The target object to wrap.\n+     *\n+     * @param {object} [wrappers = {}]\n+     *        An object tree containing wrapper functions for special cases. Any\n+     *        function present in this object tree is called in place of the\n+     *        method in the same location in the `target` object tree. These\n+     *        wrapper methods are invoked as described in {@see wrapMethod}.\n+     *\n+     * @param {object} [metadata = {}]\n+     *        An object tree containing metadata used to automatically generate\n+     *        Promise-based wrapper functions for asynchronous. Any function in\n+     *        the `target` object tree which has a corresponding metadata object\n+     *        in the same location in the `metadata` tree is replaced with an\n+     *        automatically-generated wrapper function, as described in\n+     *        {@see wrapAsyncFunction}\n+     *\n+     * @returns {Proxy<object>}\n+     */\n+    const wrapObject = (target, wrappers = {}, metadata = {}) => {\n+      let cache = Object.create(null);\n+\n+      let handlers = {\n+        has(target, prop) {\n+          return prop in target || prop in cache;\n+        },\n+\n+        get(target, prop, receiver) {\n+          if (prop in cache) {\n+            return cache[prop];\n+          }\n+\n+          if (!(prop in target)) {\n+            return undefined;\n+          }\n+\n+          let value = target[prop];\n+\n+          if (typeof value == \"function\") {\n+            // This is a method on the underlying object. Check if we need to do\n+            // any wrapping.\n+\n+            if (typeof wrappers[prop] === \"function\") {\n+              // We have a special-case wrapper for this method.\n+              value = wrapMethod(target, target[prop], wrappers[prop]);\n+            } else if (hasOwnProperty(metadata, prop)) {\n+              // This is an async method that we have metadata for. Create a\n+              // Promise wrapper for it.\n+              let wrapper = wrapAsyncFunction(prop, metadata[prop]);\n+              value = wrapMethod(target, target[prop], wrapper);\n+            } else {\n+              // This is a method that we don't know or care about. Return the\n+              // original method, bound to the underlying object.\n+              value = value.bind(target);\n+            }\n+          } else if (typeof value == \"object\" &&\n+                     (hasOwnProperty(wrappers, prop) ||\n+                      hasOwnProperty(metadata, prop))) {\n+            // This is an object that we need to do some wrapping for the children\n+            // of. Create a sub-object wrapper for it with the appropriate child\n+            // metadata.\n+            value = wrapObject(value, wrappers[prop], metadata[prop]);\n+          } else {\n+            // We don't need to do any wrapping for this property,\n+            // so just forward all access to the underlying object.\n+            Object.defineProperty(cache, prop, {\n+              configurable: true,\n+              enumerable: true,\n+              get() {\n+                return target[prop];\n+              },\n+              set(value) {\n+                target[prop] = value;\n+              },\n+            });\n+\n+            return value;\n+          }\n+\n+          cache[prop] = value;\n+          return value;\n+        },\n+\n+        set(target, prop, value, receiver) {\n+          if (prop in cache) {\n+            cache[prop] = value;\n+          } else {\n+            target[prop] = value;\n+          }\n+          return true;\n+        },\n+\n+        defineProperty(target, prop, desc) {\n+          Object.defineProperty(cache, prop, desc);\n+          return true;\n+        },\n+\n+        deleteProperty(target, prop) {\n+          delete cache[prop];\n+          return true;\n+        },\n+      };\n+\n+      return new Proxy(target, handlers);\n+    };\n+\n+    /**\n+     * Creates a set of wrapper functions for an event object, which handles\n+     * wrapping of listener functions that those messages are passed.\n+     *\n+     * A single wrapper is created for each listener function, and stored in a\n+     * map. Subsequent calls to `addListener`, `hasListener`, or `removeListener`\n+     * retrieve the original wrapper, so that  attempts to remove a\n+     * previously-added listener work as expected.\n+     *\n+     * @param {DefaultWeakMap<function, function>} wrapperMap\n+     *        A DefaultWeakMap object which will create the appropriate wrapper\n+     *        for a given listener function when one does not exist, and retrieve\n+     *        an existing one when it does.\n+     *\n+     * @returns {object}\n+     */\n+    const wrapEvent = wrapperMap => ({\n+      addListener(target, listener, ...args) {\n+        target.addListener(wrapperMap.get(listener), ...args);\n+      },\n+\n+      hasListener(target, listener) {\n+        target.hasListener(wrapperMap.get(listener));\n+      },\n+\n+      removeListener(target, listener) {\n+        target.removeListener(wrapperMap.get(listener));\n+      },\n+    });\n+\n+    const onMessageWrappers = new DefaultWeakMap(listener => {\n+      if (typeof listener !== \"function\") {\n+        return listener;\n+      }\n+\n+      /**\n+       * Wraps a message listener function so that it may send responses based on\n+       * its return value, rather than by returning a sentinel value and calling a\n+       * callback. If the listener function returns a Promise, the response is\n+       * sent when the promise either resolves or rejects.\n+       *\n+       * @param {*} message\n+       *        The message sent by the other end of the channel.\n+       * @param {object} sender\n+       *        Details about the sender of the message.\n+       * @param {function(*)} sendResponse\n+       *        A callback which, when called with an arbitrary argument, sends\n+       *        that value as a response.\n+       * @returns {boolean}\n+       *        True if the wrapped listener returned a Promise, which will later\n+       *        yield a response. False otherwise.\n+       */\n+      return function onMessage(message, sender, sendResponse) {\n+        let result = listener(message, sender);","path":"browser-polyfill.js","position":315,"original_position":315,"commit_id":"e4f9ed1630a768de829162fdf5693dd8706269e9","original_commit_id":"e4f9ed1630a768de829162fdf5693dd8706269e9","user":{"login":"Rob--W","id":1365071,"avatar_url":"https://avatars.githubusercontent.com/u/1365071?v=3","gravatar_id":"","url":"https://api.github.com/users/Rob--W","html_url":"https://github.com/Rob--W","followers_url":"https://api.github.com/users/Rob--W/followers","following_url":"https://api.github.com/users/Rob--W/following{/other_user}","gists_url":"https://api.github.com/users/Rob--W/gists{/gist_id}","starred_url":"https://api.github.com/users/Rob--W/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Rob--W/subscriptions","organizations_url":"https://api.github.com/users/Rob--W/orgs","repos_url":"https://api.github.com/users/Rob--W/repos","events_url":"https://api.github.com/users/Rob--W/events{/privacy}","received_events_url":"https://api.github.com/users/Rob--W/received_events","type":"User","site_admin":false},"body":"What if `listener` throws?","created_at":"2016-10-07T12:19:00Z","updated_at":"2016-10-07T12:23:43Z","html_url":"https://github.com/mozilla/webextension-polyfill/pull/1#discussion_r82378005","pull_request_url":"https://api.github.com/repos/mozilla/webextension-polyfill/pulls/1","_links":{"self":{"href":"https://api.github.com/repos/mozilla/webextension-polyfill/pulls/comments/82378005"},"html":{"href":"https://github.com/mozilla/webextension-polyfill/pull/1#discussion_r82378005"},"pull_request":{"href":"https://api.github.com/repos/mozilla/webextension-polyfill/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/mozilla/webextension-polyfill/pulls/1","id":88368372,"html_url":"https://github.com/mozilla/webextension-polyfill/pull/1","diff_url":"https://github.com/mozilla/webextension-polyfill/pull/1.diff","patch_url":"https://github.com/mozilla/webextension-polyfill/pull/1.patch","issue_url":"https://api.github.com/repos/mozilla/webextension-polyfill/issues/1","number":1,"state":"open","locked":false,"title":"Initial checkin.","user":{"login":"kmaglione","id":125842,"avatar_url":"https://avatars.githubusercontent.com/u/125842?v=3","gravatar_id":"","url":"https://api.github.com/users/kmaglione","html_url":"https://github.com/kmaglione","followers_url":"https://api.github.com/users/kmaglione/followers","following_url":"https://api.github.com/users/kmaglione/following{/other_user}","gists_url":"https://api.github.com/users/kmaglione/gists{/gist_id}","starred_url":"https://api.github.com/users/kmaglione/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kmaglione/subscriptions","organizations_url":"https://api.github.com/users/kmaglione/orgs","repos_url":"https://api.github.com/users/kmaglione/repos","events_url":"https://api.github.com/users/kmaglione/events{/privacy}","received_events_url":"https://api.github.com/users/kmaglione/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-10-07T01:23:30Z","updated_at":"2016-10-07T12:23:43Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e367c9716dd41078bde8057cf21e98da47d5638e","assignee":{"login":"aswan","id":3308522,"avatar_url":"https://avatars.githubusercontent.com/u/3308522?v=3","gravatar_id":"","url":"https://api.github.com/users/aswan","html_url":"https://github.com/aswan","followers_url":"https://api.github.com/users/aswan/followers","following_url":"https://api.github.com/users/aswan/following{/other_user}","gists_url":"https://api.github.com/users/aswan/gists{/gist_id}","starred_url":"https://api.github.com/users/aswan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aswan/subscriptions","organizations_url":"https://api.github.com/users/aswan/orgs","repos_url":"https://api.github.com/users/aswan/repos","events_url":"https://api.github.com/users/aswan/events{/privacy}","received_events_url":"https://api.github.com/users/aswan/received_events","type":"User","site_admin":false},"assignees":[{"login":"aswan","id":3308522,"avatar_url":"https://avatars.githubusercontent.com/u/3308522?v=3","gravatar_id":"","url":"https://api.github.com/users/aswan","html_url":"https://github.com/aswan","followers_url":"https://api.github.com/users/aswan/followers","following_url":"https://api.github.com/users/aswan/following{/other_user}","gists_url":"https://api.github.com/users/aswan/gists{/gist_id}","starred_url":"https://api.github.com/users/aswan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aswan/subscriptions","organizations_url":"https://api.github.com/users/aswan/orgs","repos_url":"https://api.github.com/users/aswan/repos","events_url":"https://api.github.com/users/aswan/events{/privacy}","received_events_url":"https://api.github.com/users/aswan/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/mozilla/webextension-polyfill/pulls/1/commits","review_comments_url":"https://api.github.com/repos/mozilla/webextension-polyfill/pulls/1/comments","review_comment_url":"https://api.github.com/repos/mozilla/webextension-polyfill/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mozilla/webextension-polyfill/issues/1/comments","statuses_url":"https://api.github.com/repos/mozilla/webextension-polyfill/statuses/e4f9ed1630a768de829162fdf5693dd8706269e9","head":{"label":"kmaglione:master","ref":"master","sha":"e4f9ed1630a768de829162fdf5693dd8706269e9","user":{"login":"kmaglione","id":125842,"avatar_url":"https://avatars.githubusercontent.com/u/125842?v=3","gravatar_id":"","url":"https://api.github.com/users/kmaglione","html_url":"https://github.com/kmaglione","followers_url":"https://api.github.com/users/kmaglione/followers","following_url":"https://api.github.com/users/kmaglione/following{/other_user}","gists_url":"https://api.github.com/users/kmaglione/gists{/gist_id}","starred_url":"https://api.github.com/users/kmaglione/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kmaglione/subscriptions","organizations_url":"https://api.github.com/users/kmaglione/orgs","repos_url":"https://api.github.com/users/kmaglione/repos","events_url":"https://api.github.com/users/kmaglione/events{/privacy}","received_events_url":"https://api.github.com/users/kmaglione/received_events","type":"User","site_admin":false},"repo":{"id":70186167,"name":"webextension-polyfill","full_name":"kmaglione/webextension-polyfill","owner":{"login":"kmaglione","id":125842,"avatar_url":"https://avatars.githubusercontent.com/u/125842?v=3","gravatar_id":"","url":"https://api.github.com/users/kmaglione","html_url":"https://github.com/kmaglione","followers_url":"https://api.github.com/users/kmaglione/followers","following_url":"https://api.github.com/users/kmaglione/following{/other_user}","gists_url":"https://api.github.com/users/kmaglione/gists{/gist_id}","starred_url":"https://api.github.com/users/kmaglione/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kmaglione/subscriptions","organizations_url":"https://api.github.com/users/kmaglione/orgs","repos_url":"https://api.github.com/users/kmaglione/repos","events_url":"https://api.github.com/users/kmaglione/events{/privacy}","received_events_url":"https://api.github.com/users/kmaglione/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/kmaglione/webextension-polyfill","description":"A lightweight polyfill library for Promise-based WebExtension APIs in Chrome","fork":true,"url":"https://api.github.com/repos/kmaglione/webextension-polyfill","forks_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/forks","keys_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/teams","hooks_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/hooks","issue_events_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/issues/events{/number}","events_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/events","assignees_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/assignees{/user}","branches_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/branches{/branch}","tags_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/tags","blobs_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/git/refs{/sha}","trees_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/statuses/{sha}","languages_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/languages","stargazers_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/stargazers","contributors_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/contributors","subscribers_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/subscribers","subscription_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/subscription","commits_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/commits{/sha}","git_commits_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/git/commits{/sha}","comments_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/comments{/number}","issue_comment_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/issues/comments{/number}","contents_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/contents/{+path}","compare_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/merges","archive_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/downloads","issues_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/issues{/number}","pulls_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/pulls{/number}","milestones_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/milestones{/number}","notifications_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/labels{/name}","releases_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/releases{/id}","deployments_url":"https://api.github.com/repos/kmaglione/webextension-polyfill/deployments","created_at":"2016-10-06T19:30:39Z","updated_at":"2016-10-07T01:20:55Z","pushed_at":"2016-10-07T01:44:43Z","git_url":"git://github.com/kmaglione/webextension-polyfill.git","ssh_url":"git@github.com:kmaglione/webextension-polyfill.git","clone_url":"https://github.com/kmaglione/webextension-polyfill.git","svn_url":"https://github.com/kmaglione/webextension-polyfill","homepage":null,"size":17,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"mozilla:master","ref":"master","sha":"28d5a45905c781ac4e1863898e62858b93005899","user":{"login":"mozilla","id":131524,"avatar_url":"https://avatars.githubusercontent.com/u/131524?v=3","gravatar_id":"","url":"https://api.github.com/users/mozilla","html_url":"https://github.com/mozilla","followers_url":"https://api.github.com/users/mozilla/followers","following_url":"https://api.github.com/users/mozilla/following{/other_user}","gists_url":"https://api.github.com/users/mozilla/gists{/gist_id}","starred_url":"https://api.github.com/users/mozilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mozilla/subscriptions","organizations_url":"https://api.github.com/users/mozilla/orgs","repos_url":"https://api.github.com/users/mozilla/repos","events_url":"https://api.github.com/users/mozilla/events{/privacy}","received_events_url":"https://api.github.com/users/mozilla/received_events","type":"Organization","site_admin":false},"repo":{"id":70184134,"name":"webextension-polyfill","full_name":"mozilla/webextension-polyfill","owner":{"login":"mozilla","id":131524,"avatar_url":"https://avatars.githubusercontent.com/u/131524?v=3","gravatar_id":"","url":"https://api.github.com/users/mozilla","html_url":"https://github.com/mozilla","followers_url":"https://api.github.com/users/mozilla/followers","following_url":"https://api.github.com/users/mozilla/following{/other_user}","gists_url":"https://api.github.com/users/mozilla/gists{/gist_id}","starred_url":"https://api.github.com/users/mozilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mozilla/subscriptions","organizations_url":"https://api.github.com/users/mozilla/orgs","repos_url":"https://api.github.com/users/mozilla/repos","events_url":"https://api.github.com/users/mozilla/events{/privacy}","received_events_url":"https://api.github.com/users/mozilla/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mozilla/webextension-polyfill","description":"A lightweight polyfill library for Promise-based WebExtension APIs in Chrome","fork":false,"url":"https://api.github.com/repos/mozilla/webextension-polyfill","forks_url":"https://api.github.com/repos/mozilla/webextension-polyfill/forks","keys_url":"https://api.github.com/repos/mozilla/webextension-polyfill/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mozilla/webextension-polyfill/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mozilla/webextension-polyfill/teams","hooks_url":"https://api.github.com/repos/mozilla/webextension-polyfill/hooks","issue_events_url":"https://api.github.com/repos/mozilla/webextension-polyfill/issues/events{/number}","events_url":"https://api.github.com/repos/mozilla/webextension-polyfill/events","assignees_url":"https://api.github.com/repos/mozilla/webextension-polyfill/assignees{/user}","branches_url":"https://api.github.com/repos/mozilla/webextension-polyfill/branches{/branch}","tags_url":"https://api.github.com/repos/mozilla/webextension-polyfill/tags","blobs_url":"https://api.github.com/repos/mozilla/webextension-polyfill/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mozilla/webextension-polyfill/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mozilla/webextension-polyfill/git/refs{/sha}","trees_url":"https://api.github.com/repos/mozilla/webextension-polyfill/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mozilla/webextension-polyfill/statuses/{sha}","languages_url":"https://api.github.com/repos/mozilla/webextension-polyfill/languages","stargazers_url":"https://api.github.com/repos/mozilla/webextension-polyfill/stargazers","contributors_url":"https://api.github.com/repos/mozilla/webextension-polyfill/contributors","subscribers_url":"https://api.github.com/repos/mozilla/webextension-polyfill/subscribers","subscription_url":"https://api.github.com/repos/mozilla/webextension-polyfill/subscription","commits_url":"https://api.github.com/repos/mozilla/webextension-polyfill/commits{/sha}","git_commits_url":"https://api.github.com/repos/mozilla/webextension-polyfill/git/commits{/sha}","comments_url":"https://api.github.com/repos/mozilla/webextension-polyfill/comments{/number}","issue_comment_url":"https://api.github.com/repos/mozilla/webextension-polyfill/issues/comments{/number}","contents_url":"https://api.github.com/repos/mozilla/webextension-polyfill/contents/{+path}","compare_url":"https://api.github.com/repos/mozilla/webextension-polyfill/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mozilla/webextension-polyfill/merges","archive_url":"https://api.github.com/repos/mozilla/webextension-polyfill/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mozilla/webextension-polyfill/downloads","issues_url":"https://api.github.com/repos/mozilla/webextension-polyfill/issues{/number}","pulls_url":"https://api.github.com/repos/mozilla/webextension-polyfill/pulls{/number}","milestones_url":"https://api.github.com/repos/mozilla/webextension-polyfill/milestones{/number}","notifications_url":"https://api.github.com/repos/mozilla/webextension-polyfill/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mozilla/webextension-polyfill/labels{/name}","releases_url":"https://api.github.com/repos/mozilla/webextension-polyfill/releases{/id}","deployments_url":"https://api.github.com/repos/mozilla/webextension-polyfill/deployments","created_at":"2016-10-06T19:02:50Z","updated_at":"2016-10-06T19:02:50Z","pushed_at":"2016-10-07T01:44:46Z","git_url":"git://github.com/mozilla/webextension-polyfill.git","ssh_url":"git@github.com:mozilla/webextension-polyfill.git","clone_url":"https://github.com/mozilla/webextension-polyfill.git","svn_url":"https://github.com/mozilla/webextension-polyfill","homepage":null,"size":5,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":1,"forks":1,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mozilla/webextension-polyfill/pulls/1"},"html":{"href":"https://github.com/mozilla/webextension-polyfill/pull/1"},"issue":{"href":"https://api.github.com/repos/mozilla/webextension-polyfill/issues/1"},"comments":{"href":"https://api.github.com/repos/mozilla/webextension-polyfill/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/mozilla/webextension-polyfill/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/mozilla/webextension-polyfill/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mozilla/webextension-polyfill/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/mozilla/webextension-polyfill/statuses/e4f9ed1630a768de829162fdf5693dd8706269e9"}}}}
{"actor":{"display_login":"Rob--W"}}