🎉 Start new little add-on for Mastodon
This commit is contained in:
commit
1848ff7b54
19 changed files with 520 additions and 0 deletions
38
.editorconfig
Executable file
38
.editorconfig
Executable file
|
@ -0,0 +1,38 @@
|
|||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
# Unix style files
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.sh]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.html]
|
||||
indent_style = tab
|
||||
|
||||
[*.css]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.js]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.eslintrc]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{md,markdown}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = false
|
2
.eslintignore
Normal file
2
.eslintignore
Normal file
|
@ -0,0 +1,2 @@
|
|||
src/common/lib/*
|
||||
src/popup/lib/*
|
103
.eslintrc
Normal file
103
.eslintrc
Normal file
|
@ -0,0 +1,103 @@
|
|||
{
|
||||
"root": true,
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2017,
|
||||
"sourceType": "module",
|
||||
"ecmaFeatures": {
|
||||
"impliedStrict": true
|
||||
}
|
||||
},
|
||||
"env": {
|
||||
"browser": true,
|
||||
"webextensions": true,
|
||||
"es6": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"rules": {
|
||||
// basic rules
|
||||
"semi": 1,
|
||||
"semi-style": 2,
|
||||
"semi-spacing": 1,
|
||||
"camelcase": 2,
|
||||
"quotes": ["warn", "double", {
|
||||
"avoidEscape": true,
|
||||
"allowTemplateLiterals": false
|
||||
}],
|
||||
"brace-style": 2,
|
||||
|
||||
// just to make sure (are defaults)
|
||||
"indent": ["error", 4],
|
||||
|
||||
// downgrade rules (only warning)
|
||||
"no-console": 1,
|
||||
|
||||
// technically required, because of CSP
|
||||
"no-eval": 2,
|
||||
"no-implied-eval": 2,
|
||||
|
||||
// great new EcmaScript features
|
||||
"prefer-const": ["error", {
|
||||
"destructuring": "all"
|
||||
}],
|
||||
"no-var": 1,
|
||||
"prefer-arrow-callback": 1,
|
||||
"prefer-rest-params": 2,
|
||||
"prefer-spread": 2,
|
||||
"prefer-template": 1,
|
||||
"template-curly-spacing": 1,
|
||||
"symbol-description": 2,
|
||||
"object-shorthand": ["warn", "consistent-as-needed"],
|
||||
"prefer-promise-reject-errors": 2,
|
||||
/* "prefer-destructuring": 1, */ // https://github.com/eslint/eslint/issues/10250
|
||||
|
||||
// additional rules
|
||||
"no-new-object": 2,
|
||||
"eqeqeq": ["error", "smart"],
|
||||
"curly": ["error", "all"],
|
||||
"dot-location": 1,
|
||||
"dot-notation": 2,
|
||||
"no-array-constructor": 2,
|
||||
"no-throw-literal": 2,
|
||||
"no-self-compare": 2,
|
||||
"no-useless-call": 1,
|
||||
/* "no-use-before-define": 1, */
|
||||
"consistent-return": 2,
|
||||
"spaced-comment": 1,
|
||||
"no-multi-spaces": 1,
|
||||
"no-new-wrappers": 2,
|
||||
"no-script-url": 2,
|
||||
"no-void": 1,
|
||||
"vars-on-top": 1,
|
||||
"yoda": ["error", "never"],
|
||||
/* "no-warning-comments": 1, */ // should be enabled later
|
||||
"require-await": 1,
|
||||
"require-jsdoc": ["error", {
|
||||
"require": {
|
||||
"FunctionDeclaration": true,
|
||||
"MethodDefinition": false,
|
||||
"ClassDeclaration": false,
|
||||
"ArrowFunctionExpression": false
|
||||
}
|
||||
}],
|
||||
"valid-jsdoc": ["error", {
|
||||
"prefer": {
|
||||
"return": "returns"
|
||||
},
|
||||
"preferType": {
|
||||
"Boolean": "boolean",
|
||||
"Number": "number",
|
||||
"object": "Object",
|
||||
"String": "string",
|
||||
"HTMLElement": "HTMLElement"
|
||||
},
|
||||
"requireReturnType": true,
|
||||
"matchDescription": ".+",
|
||||
"requireParamDescription": false,
|
||||
"requireReturnDescription": false
|
||||
}],
|
||||
"wrap-iife": ["error", "inside"],
|
||||
"no-loop-func": 2,
|
||||
"no-unused-expressions": 2,
|
||||
// "linebreak-style": 1, // cannot be used when contributing on Windows
|
||||
}
|
||||
}
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
build/
|
71
CONTRIBUTING.md
Normal file
71
CONTRIBUTING.md
Normal file
|
@ -0,0 +1,71 @@
|
|||
Nice to see you want to contribute! :+1:
|
||||
|
||||
## Translations
|
||||
|
||||
It would be great, if you can contribute your translations! Currently, it is unfortunately only possible to translate the JSON files directly.
|
||||
To do so, go to [`src/_locales/en`](src/_locales/en) and copy the English (or German) [`messages.json`](src/_locales/en/messages.json) file. (You could also use another source language if you want, but usually English is the best.) Create a new dir at [`src/_locales`](src/_locales) with the abbreviation of the language you want to translate.
|
||||
|
||||
At the end, just submit a Pull Request.
|
||||
Of course, you can (and should) improve existing translations.
|
||||
|
||||
For more details, [see the official docs](https://developer.mozilla.org/Add-ons/WebExtensions/Internationalization#Providing_localized_strings_in__locales).
|
||||
|
||||
### Translation style
|
||||
|
||||
The English "you" should be translated in a personal way, if the target language differentiates between "you" for "anybody"/"they" and "you" for "the user of this extension". In German, that e.g. means you can translate it with "du [kannst etwas machen]" instead of "man [kann etwas machen]".
|
||||
|
||||
Please pay attention to the context and UI area the message is used for. Better translate it to a good native statement than a literal translation.
|
||||
For example messages like "Learn more" may need special (and different) handling and could also be translated with "More information" or so. Generally in the tips you should be a concise as possible. All other texts – like helper texts in the options page – should also be concise, but on point and factually correct. You may use easy terms to explain a thing and link to more resources instead, however. (See also the "Writing for users" guide linked below, where this is explained in more detail.)
|
||||
|
||||
Please have look at [the "Writing for users" guide](https://design.firefox.com/photon/copy/writing-for-users.html) of the Firefox Photon Design for other rules you should adhere to.
|
||||
|
||||
### Translations of add-on description
|
||||
|
||||
All texts shown on AMO (addons.mozilla.org) are maintained in [`assets/texts`](assets/texts). Again, you can use the English template there.
|
||||
The files have different formats, but all of them are easily translatable with any text editor.
|
||||
Note that the `amoScreenshots.csv` file refers to the screenshot descriptions you can see when you click on the screenshots of AMO. The first column there is the file name, which you can see in [`assets/screenshots`](assets/screenshots), and _must not_ be translated.
|
||||
|
||||
## Coding
|
||||
|
||||
### Getting started
|
||||
|
||||
Developing/improving a WebExtension add-on is easy! **If you have ever made some stuff with HTML/CSS/JS you can do that, too!** It's built on the same technologies.
|
||||
|
||||
* **Debug extension:** Just visit `about:debugging` and load the extension by selecting any file from the Web Extensions' dir. In our case, e.g. select `manifest.json` from the `src` dir. [See a video here.](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Your_first_WebExtension#Installing).
|
||||
* **Change code:** When it is loaded you can just change the code (and press "Reload", if needed) and you'll see the result. That is it!
|
||||
|
||||
### Coding guidelines
|
||||
|
||||
As for simple indentation issues, please refer to the [editorconfig file](.editorconfig). Just use a [plugin](http://editorconfig.org/#download), if needed, for your editor.
|
||||
|
||||
Apart from that, there are some simple rules.
|
||||
|
||||
### General
|
||||
* Do not introduce new unnecessary permissions. The add-on should require as few permissions as possible.
|
||||
* Keep the code small. Do not introduce big or unnecessary dependencies. (Better ask before you do.)
|
||||
* There is a loose width limit at 80 characters, except for HTML and text/Markdown files. HTML files should always be intended properly. "Loose limit" means I won't care if you add 3-5 characters more, but when the line becomes too long, you better split it on two lines, if it makes sense. Always prefer readability over such an arbitrary limit, however, so e.g. JSDOC can always be split onto the next line, while JS commands sometimes look better on a single line, even though it may be _a bit_ longer.
|
||||
|
||||
#### JS
|
||||
* Use EcmaScript 2017. (so e.g. `await`/`async` are fine) Basically everything, which is supported by Firefox >= 57 can also be used.
|
||||
* We use [ESLint](https://eslint.org/). Please do use it to lint your files. It specifies all coding guidelines.
|
||||
When something is not specified just use common sense and look at how other code in the project is written.
|
||||
* Especially, as we use a [CSP](src/manifest.json), please do _not_:
|
||||
* use inline JavaScript
|
||||
* use eval, or other insecure features
|
||||
* modify the CSP
|
||||
* The code uses a kind of "Revealing Module Pattern", where the variable `me` contains all public methods (and properties).
|
||||
* Avoid `this`, it mostly causes confusion. The pattern used here, usually does not need `this`.
|
||||
* Use early return instead of nested if blocks to keep the code readable.
|
||||
* Use `const` whenever possible (also in local variables in functions), only use `let` when the variable needs to be changed. Don't use `var`.
|
||||
* If you write real constants (i.e. `const` variables not written in functions, if their scope e.g. is a "module" or whole project, and which do represent static _literals_, e.g. simple variable types, such as integers, strings, but not selected HTML elements), do write them in UPPERCASE (as "real" constants are usually written in other languages), otherwise write them as usual variables in camelCase.
|
||||
* Objects, which should never be modified, should be frozen with `Object.freeze`, so they cannot be modified.
|
||||
* Do _not_ use magic numbers. Use (global/module-scoped) constants instead.
|
||||
* Throw errors when you have them. Avoid logging things with `console.log()`.
|
||||
* Load translations via JS and add the text if needed.
|
||||
* Avoid naming variables by their variable type only, e.g. `element`. Instead try to use the same variable name for an element whenever you refer to it in the source code. E.g. name a message box `elMessage`, so one can search for it in the whole code base to find out, where it is touched.
|
||||
* You should start the variable names of HTML elements with `el` as they are not obvious to differentiate from other variable names. Otherwise, do not prepend the variable type to the variable name.
|
||||
* Avoid anonymous functions, which have no name (i.e. not really assigned ) unless they do really do simple things. In most cases bigger anonymous functions are a point one may refactor. Consider introducing some (private) function in the module instead, so the function is described, documented and maybe re-used.
|
||||
|
||||
### CSS
|
||||
|
||||
* Remember that [WebExtensions automatically](https://discourse.mozilla.org/t/add-ons-have-box-sizing-border-box-by-default/28359) have the CSS property [`box-sizing`](https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing) set to `border-box` instead of `content-box` as on the web.
|
0
CONTRIBUTORS
Normal file
0
CONTRIBUTORS
Normal file
8
LICENSE.md
Normal file
8
LICENSE.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
## Mastodon-auto-remote-follow license
|
||||
Copyright (c) 2018 rugk and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
16
README.md
Normal file
16
README.md
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Mastodon Auto-Remote-Follow
|
||||
|
||||
**Attention:** Prototype version!
|
||||
|
||||
Automatically enters your Mastodon handle into the "Follow remote user" interface and clicks the submit button, so you only need to have one click to confirm the following. :smile:
|
||||
|
||||
[Idea by](https://social.wxcafe.net/@akkes/100550833588126733) [@akkes](https://social.wxcafe.net/@akkes).
|
||||
|
||||
## Download
|
||||
|
||||
**[](https://addons.mozilla.org/firefox/addon/mastodon-auto-remote-follow/)**
|
||||
|
||||
## Support development
|
||||
|
||||
You can support the development of this add-on on Liberapay:
|
||||
[](https://liberapay.com/rugk/donate)
|
BIN
assets/amobutton.png
Normal file
BIN
assets/amobutton.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.9 KiB |
15
make.sh
Executable file
15
make.sh
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
|
||||
EXTENSION_NAME="mastodon-auto-remote-follow@rugk.github.io"
|
||||
|
||||
mkdir -p "build"
|
||||
|
||||
# license should be in add-on
|
||||
mv LICENSE.md src/LICENSE.md
|
||||
|
||||
# create XPI
|
||||
cd src || exit
|
||||
zip -r -FS "../build/$EXTENSION_NAME.xpi" ./*
|
||||
|
||||
mv LICENSE.md ../LICENSE.md
|
||||
cd ..
|
15
src/_locales/de/messages.json
Normal file
15
src/_locales/de/messages.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
// manifest.json
|
||||
"extensionName": {
|
||||
"message": "Mastodon Remote Auto Follow",
|
||||
"description": "Name of the extension."
|
||||
},
|
||||
"extensionNameShort": {
|
||||
"message": "Mastodon Auto",
|
||||
"description": "Name of the extension."
|
||||
},
|
||||
"extensionDescription": {
|
||||
"message": "Gibt automatisch dein Mastodon-Handle ein, um anderen Leuten zu folgen.",
|
||||
"description": "Description of the extension."
|
||||
}
|
||||
}
|
15
src/_locales/en/messages.json
Normal file
15
src/_locales/en/messages.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
// manifest.json
|
||||
"extensionName": {
|
||||
"message": "Mastodon Remote Auto Follow",
|
||||
"description": "Name of the extension."
|
||||
},
|
||||
"extensionNameShort": {
|
||||
"message": "Mastodon Auto",
|
||||
"description": "Name of the extension."
|
||||
},
|
||||
"extensionDescription": {
|
||||
"message": "Automatically enters your Mastodon handle into remote follow, etc. commands.",
|
||||
"description": "Description of the extension."
|
||||
}
|
||||
}
|
13
src/background/background.html
Normal file
13
src/background/background.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
Workaround for including background page as a module script, see https://bugzilla.mozilla.org/show_bug.cgi?id=1394303.
|
||||
See also https://discourse.mozilla.org/t/using-es6-modules-in-background-scripts/29911/3
|
||||
-->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script async src="background.js" type="module" charset="utf-8"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
0
src/background/background.js
Normal file
0
src/background/background.js
Normal file
54
src/content_script/content.js
Normal file
54
src/content_script/content.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* Saves the information about the parent tab and their state.
|
||||
*
|
||||
* @function
|
||||
* @private
|
||||
* @returns {HtmlElement}
|
||||
*/
|
||||
function findMastodonTags() {
|
||||
return document.getElementById("remote_follow_acct");
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the required mastodon handle.
|
||||
*
|
||||
* @function
|
||||
* @private
|
||||
* @param {HtmlElement} inputField
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async function insertMastodonHandle(inputField) {
|
||||
const handleObject = await browser.storage.sync.get("insertHandle");
|
||||
|
||||
inputField.value = handleObject.insertHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* "Click" the button to submit the form.
|
||||
*
|
||||
* @function
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function confirmMastodonEntry() {
|
||||
document.querySelector("form").submit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init AutoRemoteFollower module.
|
||||
*
|
||||
* @function
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async function init() {
|
||||
const mastodon = findMastodonTags();
|
||||
if (!mastodon) {
|
||||
return;
|
||||
}
|
||||
|
||||
await insertMastodonHandle(mastodon);
|
||||
|
||||
confirmMastodonEntry();
|
||||
}
|
||||
|
||||
init();
|
43
src/manifest.json
Normal file
43
src/manifest.json
Normal file
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"name": "__MSG_extensionName__",
|
||||
"short_name": "__MSG_extensionNameShort__",
|
||||
"version": "0.1",
|
||||
"author": "rugk",
|
||||
|
||||
"description": "__MSG_extensionDescription__",
|
||||
"homepage_url": "https://github.com/rugk/mastodon-auto-remote-follow",
|
||||
|
||||
"content_security_policy": "default-src 'self'",
|
||||
"default_locale": "en",
|
||||
|
||||
"options_ui": {
|
||||
"page": "options/options.html",
|
||||
"browser_style": true
|
||||
},
|
||||
|
||||
"background": {
|
||||
"page": "background/background.html"
|
||||
},
|
||||
|
||||
"permissions": [
|
||||
"storage",
|
||||
"tabs",
|
||||
"http://*/*",
|
||||
"https://*/*"
|
||||
],
|
||||
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["https://*/*"],
|
||||
"js": ["content_script/content.js"]
|
||||
}
|
||||
],
|
||||
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"id": "mastodon-auto-remote-follow@rugk.github.io",
|
||||
"strict_min_version": "60.0"
|
||||
}
|
||||
}
|
||||
}
|
88
src/options/options.css
Normal file
88
src/options/options.css
Normal file
|
@ -0,0 +1,88 @@
|
|||
body {
|
||||
/* the style the other options in the settings pane use */
|
||||
font-size: 1.25rem; /* TODO: adjust to font size on mobile */
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* on (small) mobile displays */
|
||||
@media (max-width: 700px) {
|
||||
body {
|
||||
/* smaller size -> default on Firefox for Android is 14px */
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* e.g. the icon is not even displayed there :) */
|
||||
.mobile-incompatible {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* https://design.firefox.com/photon/patterns/inactive.html */
|
||||
[disabled] {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
li {
|
||||
list-style-type: none;
|
||||
margin-top: 8px;
|
||||
padding: 0px;
|
||||
}
|
||||
/* in a fieldset e.g. we use a condensed version */
|
||||
.condensed-list {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
/* same border style as separators above */
|
||||
border: 1px solid;
|
||||
border-radius: 4px;
|
||||
border-color: var(--grey-30); /* Firefox: --in-content-box-border-color */
|
||||
|
||||
/* a big width, but not too big */
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
min-width: 60vw;
|
||||
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
/* when a setting has a label *before* it, add some margin */
|
||||
label + .setting {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.helper-text {
|
||||
display: block;
|
||||
color: var(--grey-50);
|
||||
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* some margin to align with checkbox */
|
||||
input[type=checkbox] ~ .helper-text,
|
||||
input[type=radio] ~ .helper-text {
|
||||
/* 4px margin-left + 16px size + 3px margin-right + 5px space (#text) */
|
||||
margin-left: 28px;
|
||||
}
|
||||
|
||||
/* when a link is used in a helper text, add margin */
|
||||
.helper-text > a {
|
||||
margin-left: 4px;
|
||||
overflow-wrap: none;
|
||||
}
|
||||
|
||||
/* special options values */
|
||||
|
||||
#popupIconColor {
|
||||
display: inline;
|
||||
}
|
||||
/* @TODO: improve ID! size can be anything! Just needed, because of current JS behaviour */
|
||||
#size {
|
||||
width: 4.5em;
|
||||
}
|
||||
|
||||
/* TODO: make i icon bigger */
|
25
src/options/options.html
Normal file
25
src/options/options.html
Normal file
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="options.css">
|
||||
|
||||
<script defer src="./options.js" type="module"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form>
|
||||
<ul>
|
||||
<li>
|
||||
<label data-i18n="__MSG_optionMastodonHandle__" for="insertHandle">Insert the following handle: </label>
|
||||
<input class="setting save-on-change" type="text" id="insertHandle" name="insert-handle">
|
||||
</li>
|
||||
<li>
|
||||
<button disabled data-i18n="__MSG_optionsResetButton__" type="button" name="reset-button" id="resetButton">Reset all settings to defaults</button>
|
||||
</li>
|
||||
</ul>
|
||||
</form>
|
||||
</body>
|
||||
|
||||
</html>
|
13
src/options/options.js
Normal file
13
src/options/options.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
"use strict";
|
||||
|
||||
const insertHandle = document.getElementById("insertHandle");
|
||||
|
||||
insertHandle.addEventListener("input", () => {
|
||||
browser.storage.sync.set({
|
||||
"insertHandle": insertHandle.value
|
||||
});
|
||||
});
|
||||
|
||||
browser.storage.sync.get("insertHandle").then((handleObject) => {
|
||||
insertHandle.value = handleObject.insertHandle;
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue