{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "additionalProperties": true,
  "definitions": {
    "action": {
      "type": "object",
      "properties": {
        "browser_style": {
          "description": "Use this to include a stylesheet in your popup that will make it look consistent with the browser's UI and with other add-ons that use the browser_style property. Although this key defaults to false, it's recommended that you include it and set it to true.",
          "type": "boolean",
          "default": false
        },
        "default_icon": {
          "$ref": "#/definitions/icon"
        },
        "default_popup": {
          "type": "string",
          "description": "The popup appears when the user clicks the icon."
        },
        "default_title": {
          "type": "string",
          "description": "Tooltip for the main toolbar icon."
        }
      }
    },
    "command": {
      "type": "object",
      "properties": {
        "description": {
          "type": "string"
        },
        "suggested_key": {
          "type": "object",
          "properties": {
            "default": {
              "type": "string"
            },
            "mac": {
              "type": "string"
            },
            "linux": {
              "type": "string"
            },
            "windows": {
              "type": "string"
            },
            "chromeos": {
              "type": "string"
            },
            "ios": {
              "type": "string"
            },
            "android": {
              "type": "string"
            }
          }
        }
      }
    },
    "icon": {
      "type": ["string", "object"],
      "additionalProperties": false,
      "patternProperties": {
        "^[1-9]\\d*$": {
          "type": "string"
        }
      }
    },
    "content_security_policy": {
      "type": "string",
      "description": "This introduces some fairly strict policies that will make extensions more secure by default, and provides you with the ability to create and enforce rules governing the types of content that can be loaded and executed by your extensions and applications.",
      "default": "script-src 'self'; object-src 'self'"
    },
    "glob_pattern": {
      "type": "string"
    },
    "match_pattern": {
      "type": "string",
      "pattern": "^((\\*|http|https|file|ftp|chrome-extension):\\/\\/(\\*|\\*\\.[^\\/\\*]+|[^\\/\\*]+)?(\\/.*))|<all_urls>$"
    },
    "permissions": {
      "type": "array",
      "uniqueItems": true,
      "items": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "enum": [
              "<all_urls>",
              "activeTab",
              "alarms",
              "bookmarks",
              "browsingData",
              "contextMenus",
              "contextualIdentities",
              "cookies",
              "downloads",
              "downloads.open",
              "geolocation",
              "history",
              "identity",
              "idle",
              "management",
              "nativeMessaging",
              "notifications",
              "proxy",
              "sessions",
              "storage",
              "tabs",
              "topSites",
              "webNavigation",
              "webRequest",
              "webRequestBlocking"
            ]
          }
        ]
      }
    },
    "scripts": {
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "string"
      }
    }
  },
  "id": "https://json.schemastore.org/webextension.json",
  "properties": {
    "applications": {
      "type": "object",
      "description": "The applications key contains keys that are specific to a particular host application.",
      "properties": {
        "gecko": {
          "type": "object",
          "properties": {
            "id": {
              "type": "string",
              "description": "id is the extension ID",
              "pattern": "^\\{[A-Fa-f0-9]{8}-([A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}\\}$|^[A-Za-z0-9-._]*@[A-Za-z0-9-._]+$"
            },
            "strict_min_version": {
              "type": "string",
              "description": "Minimum version of Gecko to support. Defaults to '42a1'. (Requires Gecko 45)",
              "default": "42a1"
            },
            "strict_max_version": {
              "type": "string",
              "description": "Maximum version of Gecko to support. Defaults to '*'. (Requires Gecko 45)",
              "default": "*"
            },
            "update_url": {
              "type": "string",
              "description": "Link to an add-on update manifest. (Requires Gecko 45)",
              "format": "uri"
            }
          }
        }
      }
    },
    "author": {
      "description": "\"The extension's author, intended for display in the browser's user interface. If the developer key is supplied and it contains the \"name\" property, it will override the author key. There's no way to specify multiple authors.\"",
      "type": "string"
    },
    "background": {
      "type": "object",
      "description": "The background page is an HTML page that runs in the extension process. It exists for the lifetime of your extension, and only one instance of it at a time is active.",
      "properties": {
        "persistent": {
          "type": "boolean",
          "description": "When false, makes the background page an event page (loaded only when needed).",
          "default": true
        },
        "page": {
          "description": "Specify the HTML of the background page.",
          "type": "string"
        },
        "scripts": {
          "description": "A background page will be generated by the extension system that includes each of the files listed in the scripts property.",
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "browser_action": {
      "allOf": [
        {
          "$ref": "#/properties/page_action"
        }
      ],
      "description": "browser action is a button that your extension adds to the browser's toolbar. The button has an icon, and may optionally have a popup whose content is specified using HTML, CSS, and JavaScript.",
      "properties": {
        "default_area": {
          "description": "Defines the part of the browser in which the button is initially placed.",
          "enum": ["navbar", "menupanel", "tabstrip", "personaltoolbar"],
          "default": "navbar"
        }
      }
    },
    "chrome_settings_overrides": {
      "description": "Use the chrome_settings_overrides key to override certain browser settings",
      "type": "object",
      "properties": {
        "homepage": {
          "description": "Defines the page to be used as the browser's homepage.",
          "type": "string"
        }
      }
    },
    "chrome_url_overrides": {
      "description": "Use the chrome_url_overrides key to provide a custom replacement for the documents loaded into various special pages usually provided by the browser itself.",
      "type": "object",
      "properties": {
        "bookmarks": {
          "description": "Provide a replacement for the page that shows the bookmarks.",
          "type": "string"
        },
        "history": {
          "description": "Provide a replacement for the page that shows the browsing history.",
          "type": "string"
        },
        "newtab": {
          "description": "Provide a replacement for the document that's shown in the \"new tab\" page",
          "type": "string"
        }
      }
    },
    "commands": {
      "type": "object",
      "description": "Use the commands API to add keyboard shortcuts that trigger actions in your extension, for example, an action to open the browser action or send a command to the extension.",
      "properties": {
        "_execute_browser_action": {
          "$ref": "#/definitions/command"
        },
        "_execute_page_action": {
          "$ref": "#/definitions/command"
        },
        "_execute_sidebar_action": {
          "$ref": "#/definitions/command"
        }
      },
      "additionalProperties": {
        "$ref": "#/definitions/command"
      }
    },
    "content_scripts": {
      "type": "array",
      "description": "Content scripts are JavaScript files that run in the context of web pages.",
      "minItems": 1,
      "uniqueItems": true,
      "items": {
        "type": "object",
        "required": ["matches"],
        "additionalProperties": false,
        "properties": {
          "matches": {
            "type": "array",
            "description": "Specifies which pages this content script will be injected into.",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "$ref": "#/definitions/match_pattern"
            }
          },
          "exclude_matches": {
            "type": "array",
            "description": "Excludes pages that this content script would otherwise be injected into.",
            "uniqueItems": true,
            "items": {
              "$ref": "#/definitions/match_pattern"
            }
          },
          "css": {
            "type": "array",
            "description": "The list of CSS files to be injected into matching pages. These are injected in the order they appear in this array, before any DOM is constructed or displayed for the page.",
            "uniqueItems": true,
            "items": {
              "type": "string"
            }
          },
          "js": {
            "$ref": "#/definitions/scripts",
            "description": "The list of JavaScript files to be injected into matching pages. These are injected in the order they appear in this array."
          },
          "run_at": {
            "type": "string",
            "description": "Controls when the files in js are injected.",
            "enum": ["document_start", "document_end", "document_idle"],
            "default": "document_idle"
          },
          "all_frames": {
            "type": "boolean",
            "description": "Controls whether the content script runs in all frames of the matching page, or only the top frame.",
            "default": false
          },
          "include_globs": {
            "type": "array",
            "description": "Applied after matches to include only those URLs that also match this glob. Intended to emulate the @include Greasemonkey keyword.",
            "uniqueItems": true,
            "items": {
              "$ref": "#/definitions/glob_pattern"
            }
          },
          "exclude_globs": {
            "type": "array",
            "description": "Applied after matches to exclude URLs that match this glob. Intended to emulate the @exclude Greasemonkey keyword.",
            "uniqueItems": true,
            "items": {
              "$ref": "#/definitions/glob_pattern"
            }
          },
          "match_about_blank": {
            "type": "boolean",
            "description": "Whether to insert the content script on about:blank and about:srcdoc.",
            "default": false
          }
        }
      }
    },
    "content_security_policy": {
      "$ref": "#/definitions/content_security_policy"
    },
    "default_locale": {
      "type": "string",
      "description": "Specifies the subdirectory of _locales that contains the default strings for this extension.",
      "default": "en"
    },
    "description": {
      "type": "string",
      "description": "A plain text description of the extension"
    },
    "developer": {
      "type": "object",
      "description": "The name of the extension's developer and their homepage URL, intended for display in the browser's user interface.",
      "properties": {
        "name": {
          "type": "string"
        },
        "url": {
          "type": "string",
          "format": "uri"
        }
      }
    },
    "devtools_page": {
      "type": "string",
      "description": "A DevTools extension adds functionality to the Chrome DevTools. It can add new UI panels and sidebars, interact with the inspected page, get information about network requests, and more."
    },
    "experiment_apis": {
      "type": "object",
      "items": {
        "type": "object",
        "required": ["schema"],
        "properties": {
          "child": {
            "type": "object",
            "required": ["paths", "script", "scopes"],
            "properties": {
              "paths": {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "scopes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "script": {
                "type": "string"
              }
            }
          },
          "parent": {
            "type": "object",
            "required": ["paths", "scopes", "scripts"],
            "properties": {
              "events": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "paths": {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "scopes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "script": {
                "type": "string"
              }
            }
          },
          "schema": {
            "type": "string"
          }
        }
      }
    },
    "homepage_url": {
      "type": "string",
      "description": "The URL of the homepage for this add-on. The add-on management page will contain a link to this URL.",
      "format": "uri"
    },
    "icons": {
      "description": "One or more icons that represent the extension, app, or theme. Recommended format: PNG; also BMP, GIF, ICO, JPEG.",
      "additionalProperties": false,
      "patternProperties": {
        "^[1-9]\\d*$": {
          "type": "string"
        }
      }
    },
    "incognito": {
      "type": "string",
      "description": "Specify how this extension will behave if allowed to run in incognito mode.",
      "enum": ["spanning", "split", "not_allowed"],
      "default": "spanning"
    },
    "manifest_version": {
      "type": "integer",
      "description": "One integer specifying the version of the manifest file format your package requires.",
      "enum": [2]
    },
    "name": {
      "type": "string",
      "description": "The name of the extension",
      "minLength": 2,
      "maxLength": 45
    },
    "omnibox": {
      "type": "object",
      "description": "The omnibox API allows you to register a keyword with Google Chrome's address bar, which is also known as the omnibox.",
      "required": ["keyword"],
      "properties": {
        "keyword": {
          "type": "string",
          "description": "The keyword that will trigger your extension."
        }
      }
    },
    "optional_permissions": {
      "description": "Use the optional_permissions key to list permissions which you want to ask for at runtime, after your add-on has been installed.",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "enum": [
              "activeTab",
              "background",
              "bookmarks",
              "clipboardRead",
              "clipboardWrite",
              "contentSettings",
              "contextMenus",
              "cookies",
              "debugger",
              "geolocation",
              "history",
              "idle",
              "management",
              "notifications",
              "pageCapture",
              "tabs",
              "topSites",
              "webNavigation",
              "webRequest",
              "webRequestBlocking"
            ]
          }
        ]
      }
    },
    "options_ui": {
      "type": "object",
      "description": "Use the options_ui key to define an options page for your add-on.",
      "required": ["page"],
      "properties": {
        "page": {
          "type": "string",
          "description": "The path to an HTML file containing the specification of your options page."
        },
        "browser_style": {
          "type": "boolean",
          "default": true,
          "description": "Use this to include a stylesheet in your page that will make it look consistent with the browser's UI and with other add-ons that use the browser_style property."
        },
        "open_in_tab": {
          "type": "boolean",
          "default": false,
          "description": "If true, the options page will open in a normal browser tab, rather than being integrated into the browser's add-ons manager."
        }
      }
    },
    "page_action": {
      "description": "Use the chrome.pageAction API to put icons inside the address bar. Page actions represent actions that can be taken on the current page, but that aren't applicable to all pages.",
      "type": "object",
      "properties": {
        "browser_style": {
          "description": "Use this to include a stylesheet in your popup that will make it look consistent with the browser's UI and with other add-ons that use the browser_style property. Although this key defaults to false, it's recommended that you include it and set it to true.",
          "type": "boolean",
          "default": false
        },
        "default_icon": {
          "$ref": "#/definitions/icon"
        },
        "default_popup": {
          "type": "string",
          "description": "The popup appears when the user clicks the icon."
        },
        "default_title": {
          "type": "string",
          "description": "Tooltip for the main toolbar icon."
        }
      }
    },
    "permissions": {
      "$ref": "#/definitions/permissions",
      "description": "Permissions help to limit damage if your extension or app is compromised by malware. Some permissions are also displayed to users before installation, as detailed in Permission Warnings."
    },
    "protocol_handlers": {
      "type": "array",
      "description": "Use this key to register one of more web-based protocol handlers.",
      "items": {
        "type": "object",
        "description": "Use this object to register a single web-based protocol handler",
        "properties": {
          "protocol": {
            "description": "A string defining the protocol.",
            "anyOf": [
              {
                "enum": [
                  "bitcoin",
                  "geo",
                  "im",
                  "irc",
                  "ircs",
                  "magnet",
                  "mailto",
                  "mms",
                  "news",
                  "nntp",
                  "sip",
                  "sms",
                  "smsto",
                  "ssh",
                  "tel",
                  "urn",
                  "webcal",
                  "wtai",
                  "xmpp"
                ],
                "description": "A pre-existing protocol allowed for use with WebExtensions. See https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/protocol_handlers for more information."
              },
              {
                "type": "string",
                "pattern": "^(ext|web)\\+[0-9a-z]+",
                "description": "A custom-named protocol. These MUST be prefixed with 'web+' or 'ext+', followed by a string consisting of only lower-case ASCII characters."
              }
            ]
          },
          "name": {
            "description": "A string representing the name of the protocol handler. This will be displayed to the user when they are being asked if they want this handler to open the link.",
            "type": "string"
          },
          "uriTemplate": {
            "description": "A string representing the URL of the handler. This string must include \"%s\" as a placeholder: this will be replaced with the escaped URL of the document to be handled. This URL might be a true URL, or it could be a phone number, email address, or so forth.",
            "pattern": "%s"
          }
        }
      }
    },
    "short_name": {
      "type": "string",
      "description": "The short name is typically used where there is insufficient space to display the full name.",
      "minLength": 2,
      "maxLength": 12
    },
    "sidebar_action": {
      "type": "object",
      "description": "A sidebar is a pane that is displayed at the left-hand side of the browser window, next to the web page. The browser provides a UI that enables the user to see the currently available sidebars and to select a sidebar to display.",
      "properties": {
        "default_icon": {
          "$ref": "#/definitions/icon"
        },
        "default_panel": {
          "type": "string",
          "description": "The path to an HTML file that specifies the sidebar's contents."
        },
        "default_title": {
          "type": "string",
          "description": "Title for the sidebar. This is used in the browser UI for listing and opening sidebars, and is displayed at the top of the sidebar when it is open."
        }
      }
    },
    "version": {
      "description": "One to four dot-separated integers identifying the version of this extension.",
      "pattern": "^(?:\\d{1,5}\\.){0,3}\\d{1,5}$"
    },
    "web_accessible_resources": {
      "type": "array",
      "description": "An array of strings specifying the paths (relative to the package root) of packaged resources that are expected to be usable in the context of a web page.",
      "uniqueItems": true,
      "items": {
        "type": "string"
      }
    }
  },
  "required": ["manifest_version", "name", "version"],
  "title": "JSON schema for WebExtensions manifest files",
  "type": "object"
}