diff --git a/user-script/README.md b/content-script-register/README.md
similarity index 51%
rename from user-script/README.md
rename to content-script-register/README.md
index 61ad8f4a..8adf8252 100644
--- a/user-script/README.md
+++ b/content-script-register/README.md
@@ -1,7 +1,9 @@
-# User script
+# Content script registration
This extension demonstrates the `browser.contentScripts.register()` API, which enables an extension to register URL-matching content scripts at runtime.
+The contentScripts.register() API is intended to enable an extension to register scripts that are packaged in the extension. If you want to register third-party user scripts, use the [userScripts API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts). Please refer to [user script registration](https://github.com/mdn/webextensions-examples/tree/master/user-script-register) for an example of that API.
+
This extension adds a browser action that shows a popup. The popup lets you specify:
* some code that comprises your content script
@@ -9,16 +11,16 @@ This extension adds a browser action that shows a popup. The popup lets you spec
Once these are set up you can register the content script by clicking "Register script". The extension will then register a content script with the given properties by calling `browser.contentScripts.register()`.
-To keep things simple, you can only have one script registered at any time: if you click "Register script" again, the old script is unregistered. To do this, the extension keeps a reference to the `RegisteredContentScript` object returned from `browser.contentScripts.register()`: this object provides the `unregister()` method.
+To keep things simple, you can only have one script registered at any time: if you click "Register script" again, the active script is unregistered. To do this, the extension keeps a reference to the `RegisteredContentScript` object returned from `browser.contentScripts.register()`: this object provides the `unregister()` method.
Note that the extension uses a background script to register the content scripts and to keep a reference to the `RegisteredContentScript` object. If it did not do this, then as soon as the popup window closed, the `RegisteredContentScript` would go out of scope and be destroyed, and the browser would then unregister the content script as part of cleanup.
## Default settings
-The popup is initialized with some default values for the pattern and the code:
+The popup is initialized with default values for the pattern and the code:
-* the pattern `*://*.org/*`, which will load the script into any HTTP or HTTPS pages on a `.org` domain.
+* the pattern `*://*.org/*`, which loads the script into any HTTP or HTTPS pages on a `.org` domain.
* the code `document.body.innerHTML = '
This page has been eaten
'`
-To try the extension out quickly, just click "Register script" with these defaults, and load http://example.org/ or
-https://www.mozilla.org/. Then try changing the pattern or the code, and reloading these or related pages.
+To try the extension, open the browser action, click "Register script" with the defaults, and load http://example.org/ or
+https://www.mozilla.org/. Then change the pattern or the code, and reload these or related pages.
diff --git a/user-script/background.js b/content-script-register/background.js
similarity index 100%
rename from user-script/background.js
rename to content-script-register/background.js
diff --git a/user-script/icons/LICENSE b/content-script-register/icons/LICENSE
similarity index 100%
rename from user-script/icons/LICENSE
rename to content-script-register/icons/LICENSE
diff --git a/user-script/icons/if_source_code_103710.svg b/content-script-register/icons/if_source_code_103710.svg
similarity index 100%
rename from user-script/icons/if_source_code_103710.svg
rename to content-script-register/icons/if_source_code_103710.svg
diff --git a/user-script/manifest.json b/content-script-register/manifest.json
similarity index 73%
rename from user-script/manifest.json
rename to content-script-register/manifest.json
index b233b836..c59c14a7 100644
--- a/user-script/manifest.json
+++ b/content-script-register/manifest.json
@@ -1,12 +1,12 @@
{
"manifest_version": 2,
- "name": "User script",
+ "name": "Content script registration",
"version": "1.1",
"browser_specific_settings": {
"gecko": {
- "id": "user-script-example@mozilla.org",
+ "id": "content-script-example@mozilla.org",
"strict_min_version": "59.0a1"
}
},
@@ -24,8 +24,8 @@
"default_icon": {
"32" : "icons/if_source_code_103710.svg"
},
- "default_title": "User script",
- "default_popup": "popup/user-script.html",
+ "default_title": "Content script",
+ "default_popup": "popup/content-script.html",
"browser_style": true
},
diff --git a/user-script/popup/user-script.css b/content-script-register/popup/content-script.css
similarity index 100%
rename from user-script/popup/user-script.css
rename to content-script-register/popup/content-script.css
diff --git a/user-script/popup/user-script.html b/content-script-register/popup/content-script.html
similarity index 77%
rename from user-script/popup/user-script.html
rename to content-script-register/popup/content-script.html
index 30739628..328696d5 100644
--- a/user-script/popup/user-script.html
+++ b/content-script-register/popup/content-script.html
@@ -3,7 +3,7 @@
-
+
@@ -20,7 +20,7 @@
-
+
diff --git a/user-script/popup/user-script.js b/content-script-register/popup/content-script.js
similarity index 100%
rename from user-script/popup/user-script.js
rename to content-script-register/popup/content-script.js
diff --git a/examples.json b/examples.json
index b3864c55..d952b100 100644
--- a/examples.json
+++ b/examples.json
@@ -94,6 +94,15 @@
],
"name": "commands"
},
+ {
+ "description": "Illustrates how an extension can register URL-matching content scripts at runtime.",
+ "javascript_apis": [
+ "contentScripts.register",
+ "runtime.onMessage",
+ "runtime.sendMessage"
+ ],
+ "name": "content-script-register"
+ },
{
"description": "Add a context menu option to links to copy the link to the clipboard, as plain text and as a link in rich HTML.",
"javascript_apis": [
@@ -546,13 +555,13 @@
"name": "user-agent-rewriter"
},
{
- "description": "Illustrates how an extension can register URL-matching content scripts at runtime.",
+ "description": "Illustrates how an extension can register URL-matching user scripts at runtime.",
"javascript_apis": [
- "contentScripts.register",
+ "userScripts.register",
"runtime.onMessage",
"runtime.sendMessage"
],
- "name": "user-script"
+ "name": "user-script-register"
},
{
"description": "Demonstrates how to use webpack to package npm modules in an extension.",
diff --git a/user-script-register/README.md b/user-script-register/README.md
new file mode 100644
index 00000000..2f111d87
--- /dev/null
+++ b/user-script-register/README.md
@@ -0,0 +1,20 @@
+# User script registration
+
+This extension demonstrates the [`browser.userScripts.register()`](https://wiki.developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts/Register) API.
+
+The extension includes an [API script](https://wiki.developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/user_scripts) (`customUserScriptAPIs.js`) that enables user scripts to make use of `browser.storage.local`.
+
+To enable a user script to be specified and registered, this extension includes a sidebar action. The sidebar enables you to define the following properties that control the execution of a registered script, with default values provided:
+
+* the host pattern `*://*.org/*`, which loads the script into any HTTP or HTTPS pages on a `.org` domain.
+* script code that replaces the content of the pattern matched page with the message "This page has been eaten". The script also uses the API script stubs to save and recall the URL of each page "eaten". Information on the last and current "eaten" page is then included in the "eaten" message.
+* a script ID that is stored in the user script metadata and then used in the API script to store separate values for each registered script.
+
+All other properties use their default value.
+
+Clicking "Register script" registers the script by calling `browser.userScripts.register()`.
+
+In this example, only one script can be registered at a time: registering a new script unregisters the active script. The extension does this by keeping a reference to the `RegisteredUserScript` object returned from `browser.userScripts.register()`: this object provides the `unregister()` method.
+
+To try the extension, click "Register script" with the defaults and load http://example.org/ or
+https://www.mozilla.org/. Then change the pattern or the code and reload these or related pages.
diff --git a/user-script-register/background.js b/user-script-register/background.js
new file mode 100644
index 00000000..cb793111
--- /dev/null
+++ b/user-script-register/background.js
@@ -0,0 +1,24 @@
+'use strict';
+
+let registered = null;
+
+async function registerScript(message) {
+ const {
+ hosts,
+ code,
+ userScriptID,
+ } = message;
+
+ if (registered) {
+ await registered.unregister();
+ registered = null;
+ }
+
+ registered = await browser.userScripts.register({
+ matches: hosts,
+ js: [{code}],
+ scriptMetadata: {userScriptID},
+ });
+}
+
+browser.runtime.onMessage.addListener(registerScript);
diff --git a/user-script-register/customUserScriptAPIs.js b/user-script-register/customUserScriptAPIs.js
new file mode 100644
index 00000000..3f067066
--- /dev/null
+++ b/user-script-register/customUserScriptAPIs.js
@@ -0,0 +1,27 @@
+
+browser.userScripts.onBeforeScript.addListener(script => {
+
+ const scriptMetadata = script.metadata;
+ const id = scriptMetadata.userScriptID;
+
+ function getScopedName(name) {
+ return `${id}:${name}`;
+ }
+
+ script.defineGlobals({
+ async GM_getValue(name) {
+ const scopedName = getScopedName(name);
+ const res = await browser.storage.local.get(scopedName);
+ console.log("GM_getValue", {id, name, res, scriptMetadata});
+ return res[scopedName];
+ },
+ GM_setValue(name, value) {
+ console.log("GM_setValue", {id, name, value, scriptMetadata});
+ return browser.storage.local.set({[getScopedName(name)]: value});
+ },
+ });
+
+ console.log("custom userScripts APIs defined");
+});
+
+console.log("apiScript executed and userScripts.onBeforeScript listener subscribed");
\ No newline at end of file
diff --git a/user-script-register/icons/LICENSE b/user-script-register/icons/LICENSE
new file mode 100644
index 00000000..8b397ff0
--- /dev/null
+++ b/user-script-register/icons/LICENSE
@@ -0,0 +1 @@
+The icon "if_source_code_103710.svg" is from picol.org (http://www.picol.org/) and is used under the terms of the Creative Commons Attribution license: http://creativecommons.org/licenses/by/3.0/.
diff --git a/user-script-register/icons/if_source_code_103710.svg b/user-script-register/icons/if_source_code_103710.svg
new file mode 100644
index 00000000..503d9537
--- /dev/null
+++ b/user-script-register/icons/if_source_code_103710.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/user-script-register/manifest.json b/user-script-register/manifest.json
new file mode 100644
index 00000000..d3f45dec
--- /dev/null
+++ b/user-script-register/manifest.json
@@ -0,0 +1,40 @@
+{
+
+ "manifest_version": 2,
+ "name": "User script registration",
+ "version": "1.0",
+
+ "browser_specific_settings": {
+ "gecko": {
+ "id": "user-script-example@mozilla.org",
+ "strict_min_version": "65.0"
+ }
+ },
+
+ "description": "Demonstration of userScripts.register.",
+ "icons": {
+ "48": "icons/if_source_code_103710.svg"
+ },
+
+ "permissions": [
+ "",
+ "storage"
+ ],
+
+ "sidebar_action": {
+ "default_icon": {
+ "32" : "icons/if_source_code_103710.svg"
+ },
+ "default_title": "User script",
+ "default_panel": "popup/user-script.html",
+ "browser_style": true
+ },
+
+ "background": {
+ "scripts": ["background.js"]
+ },
+
+ "user_scripts": {
+ "api_script": "customUserScriptAPIs.js"
+ }
+}
diff --git a/user-script-register/popup/user-script.css b/user-script-register/popup/user-script.css
new file mode 100644
index 00000000..3aaa614e
--- /dev/null
+++ b/user-script-register/popup/user-script.css
@@ -0,0 +1,16 @@
+body {
+ padding: 1.0em;
+}
+
+input {
+ width: 100%;
+ margin-bottom: 1em;
+}
+
+textarea {
+ width: 100%;
+ resize: none;
+ border: 1px solid #e4e4e4;
+ margin-bottom: 1em;
+ min-height: 380px;
+}
diff --git a/user-script-register/popup/user-script.html b/user-script-register/popup/user-script.html
new file mode 100644
index 00000000..00838ab6
--- /dev/null
+++ b/user-script-register/popup/user-script.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+