Rewritten the entire app to TS

This commit is contained in:
mickie 2021-08-17 23:57:59 -05:00
parent fa52828641
commit cd322127d6
76 changed files with 23118 additions and 5724 deletions

48
.all-contributorsrc Normal file
View File

@ -0,0 +1,48 @@
{
"files": [
"README.md"
],
"imageSize": 100,
"commit": false,
"contributors": [
{
"login": "davidnguyen179",
"name": "David Nguyen",
"avatar_url": "https://avatars.githubusercontent.com/u/6290720?v=4",
"profile": "https://www.dzungnguyen.dev",
"contributions": [
"code",
"doc",
"design",
"maintenance",
"review",
"test"
]
},
{
"login": "immint023",
"name": "Minh Ngo",
"avatar_url": "https://avatars.githubusercontent.com/u/38607460?v=4",
"profile": "https://github.com/immint023",
"contributions": [
"code",
"test"
]
},
{
"login": "3BenLee",
"name": "Ben Harned",
"avatar_url": "https://avatars.githubusercontent.com/u/35267414?v=4",
"profile": "http://benlee3.com",
"contributions": [
"doc"
]
}
],
"contributorsPerLine": 7,
"projectName": "web-extension-boilerplate",
"projectOwner": "davidnguyen179",
"repoType": "github",
"repoHost": "https://github.com",
"skipCi": true
}

63
.eslintrc.json Normal file
View File

@ -0,0 +1,63 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:import/errors",
"plugin:import/warnings"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint",
"import"
],
"rules": {
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
],
"eol-last": [
"error",
"always"
],
"import/newline-after-import": [
"error",
{
"count": 1
}
],
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"no-console": "error",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/no-unused-vars": "error"
},
"settings": {
"import/resolver": {
"node": {
"extensions": [
".js",
".jsx",
".ts",
".tsx"
]
}
}
}
}

View File

@ -0,0 +1,3 @@
#!/bin/bash
echo "Fixing eslint 🔧 🪚 🔨"
npm run code:lint-fix

View File

@ -0,0 +1,14 @@
#!/bin/bash
CHANGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR "*.js" "*.jsx" "*.ts" "*.tsx" | sed 's| |\\ |g')
[[ -z "$CHANGED_FILES" ]] && exit 0
echo "Running prettier 🚀🚀"
echo "$CHANGED_FILES" | xargs ./node_modules/.bin/prettier --write
echo "$CHANGED_FILES" | xargs git add
echo "Done prettier ✨✨"
exit 0

View File

@ -0,0 +1,4 @@
#!/bin/bash
echo "Running eslint... 👀"
npm run code:lint

View File

@ -0,0 +1,4 @@
#!/bin/bash
echo "Running unit test... 🤞 🚑 💊"
npm run test:unit -- --coverage

View File

@ -0,0 +1,4 @@
#!/bin/bash
echo "Running typecheck... 🩺 🔬 🔭"
npm run code:typecheck

3
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,3 @@
# These are supported funding model platforms
custom: paypal.me/davidnguyen179

50
.github/workflows/workflow-config.yml vendored Normal file
View File

@ -0,0 +1,50 @@
name: 'ci/cd'
# This workflow is triggered on pushes to the repository.
on: [push, pull_request]
jobs:
test:
# Job name
name: test
# This job runs on Linux
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
steps:
- name: Checkout repository
uses: actions/checkout@v2
id: checkout
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Cache node_modules
uses: actions/cache@v2
id: cache
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: |
**/node_modules
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
- name: Installing packages...🏃‍♂️ 🏃‍♂️ 🏃‍♂️
if: steps.cache.outputs.cache-hit != 'true'
run: npm ci
- name: Running typecheck... 🩺 🔬 🔭
run: npm run code:typecheck
- name: Running eslint... 👀
run: npm run code:lint
- name: Running unit test... 🤞 🚑 💊
run: npm run test:unit -- --runInBand --coverage
- name: Trigger codecov
run: bash <(curl -s https://codecov.io/bash)
- name: Run build Chrome
run: npm run app:chrome
- name: Run build Firefox
run: npm run app:firefox
- name: Run build Edge
run: npm run app:edge

8
.gitignore vendored
View File

@ -1,5 +1,5 @@
web-ext-artifacts dist/
web-ext-artifacts.*
src.*
*.org
node_modules/ node_modules/
coverage/
.DS_Store
.log/

1
.prettierignore Normal file
View File

@ -0,0 +1 @@
node_modules/

5
.prettierrc.json Normal file
View File

@ -0,0 +1,5 @@
{
"printWidth": 120,
"singleQuote": true,
"trailingComma": "es5"
}

20
PRIVACY_POLICY.txt Normal file
View File

@ -0,0 +1,20 @@
Chrome Web Store & Mozilla Add-on Store & Microsoft Edge Add-on Store Privacy Policies.
======================================================================================================
Introduction
============
Introduce your web extension
Information We Collect
======================
Does your web extension collect data?
- I collect data
- I don't collect data
How it uses cookies
========================
If your web extension uses cookies, describe where your extension uses cookies and why?

138
README.md
View File

@ -21,35 +21,6 @@ Supported services/protocols:
- Osada / Zap / Zot6 - Osada / Zap / Zot6
- XMPP - XMPP
## Screenshots
![img](/src/img/screenshot-1.png)
![img](/src/img/screenshot-2.png)
![img](/src/img/screenshot-3.png)
## Build
You need Node.js/npm
`npm install` then
`npm install --global web-ext`
Use the next command to generate the package (.zip file)
`web-ext build`
See [web-ext page](https://extensionworkshop.com/documentation/develop/getting-started-with-web-ext/).
**Optional:** Add-ons Linter by Mozilla
`npm install -g addons-linter`
See [repo](https://github.com/mozilla/addons-linter).
## Contributing ## Contributing
You can contribute in the following ways: You can contribute in the following ways:
@ -88,3 +59,112 @@ Copyleft (ɔ) 2021 - Miguel (mickie)
See LICENSE file for more information. See LICENSE file for more information.
## TODO
This boilerplate provides a skeleton to start developing cross-browser web extensions.
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
[![jest](https://jestjs.io/img/jest-badge.svg)](https://github.com/facebook/jest) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/davidnguyen179/web-extension-boilerplate/pulls)
![ci/cd](https://github.com/davidnguyen179/web-extension-boilerplate/workflows/ci/cd/badge.svg)
## Development
```bash
npm i
```
**Chrome**
```bash
npm run app:chrome-dev
```
**Edge**
```bash
npm run app:edge-dev
```
**Firefox**
```bash
npm run app:firefox-dev
```
## Production
```bash
npm i
```
```bash
npm run app:chrome
```
**Edge**
```bash
npm run app:edge
```
**Firefox**
```bash
npm run app:firefox
```
## Load package to browsers
**Chrome**
1. Go to the browser's URL address bar
2. Enter `chrome://extensions/`
3. Switch to "**Developer mode**"
4. Load extension by clicking "**Load unpacked**"
5. Browse to `dist/` in source code
6. Done!
Check here for more detail: [https://developer.chrome.com/extensions/getstarted](https://developer.chrome.com/extensions/getstarted)
**Edge**
1. Go to the browser's URL address bar
2. Enter `edge://extensions/`
3. Turn on `Developer mode`
4. Load extension by clicking "**Load unpacked**"
5. Browse to `dist/` in source code
6. Done!
**Firefox**
1. Go to the browser's URL address bar
2. Enter `about:debugging#/runtime/this-firefox`
3. Click **Load Temporary Add-on...**
4. Browse to your `manifest.json` & click **Open**
5. Done!
Check here for more details: [https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/)
## Contributors ✨
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tr>
<td align="center"><a href="https://www.dzungnguyen.dev"><img src="https://avatars.githubusercontent.com/u/6290720?v=4?s=100" width="100px;" alt=""/><br /><sub><b>David Nguyen</b></sub></a><br /><a href="https://github.com/davidnguyen179/web-extension-boilerplate/commits?author=davidnguyen179" title="Code">💻</a> <a href="https://github.com/davidnguyen179/web-extension-boilerplate/commits?author=davidnguyen179" title="Documentation">📖</a> <a href="#design-davidnguyen179" title="Design">🎨</a> <a href="#maintenance-davidnguyen179" title="Maintenance">🚧</a> <a href="https://github.com/davidnguyen179/web-extension-boilerplate/pulls?q=is%3Apr+reviewed-by%3Adavidnguyen179" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/davidnguyen179/web-extension-boilerplate/commits?author=davidnguyen179" title="Tests">⚠️</a></td>
<td align="center"><a href="https://github.com/immint023"><img src="https://avatars.githubusercontent.com/u/38607460?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Minh Ngo</b></sub></a><br /><a href="https://github.com/davidnguyen179/web-extension-boilerplate/commits?author=immint023" title="Code">💻</a> <a href="https://github.com/davidnguyen179/web-extension-boilerplate/commits?author=immint023" title="Tests">⚠️</a></td>
<td align="center"><a href="http://benlee3.com"><img src="https://avatars.githubusercontent.com/u/35267414?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ben Harned</b></sub></a><br /><a href="https://github.com/davidnguyen179/web-extension-boilerplate/commits?author=3BenLee" title="Documentation">📖</a></td>
</tr>
</table>
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!

7
babel.config.js Normal file
View File

@ -0,0 +1,7 @@
// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-typescript',
],
};

24
jest.config.js Normal file
View File

@ -0,0 +1,24 @@
const ignores = ['/node_modules/', '__mocks__'];
module.exports = {
collectCoverageFrom: ['src/lib/app.ts', 'src/lib/utils.ts'],
testMatch: ['**/test/**/*.spec.+(ts|tsx|js)'],
testPathIgnorePatterns: [...ignores],
coveragePathIgnorePatterns: [...ignores, 'src/(umd|cjs|esm)-entry.js$'],
transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$'],
coverageDirectory: './coverage',
coverageThreshold: {
global: {
branches: 80,
functions: 100,
lines: 100,
statements: 100,
},
},
moduleFileExtensions: ['ts', 'tsx', 'js'],
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest',
},
verbose: true,
setupFilesAfterEnv: ['./jest.setup.js'],
};

1
jest.setup.js Normal file
View File

@ -0,0 +1 @@
require('whatwg-fetch');

View File

@ -1,59 +0,0 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"lib": ["es6"],
// "allowJs": true,
// "checkJs": true,
// "jsx": "preserve",
"declaration": true,
// "declarationMap": true,
// "sourceMap": true,
// "outFile": "./",
"outDir": "./dist",
// "rootDir": "./",
// "composite": true,
"removeComments": true,
// "noEmit": true,
// "importHelpers": true,
"downlevelIteration": true,
// "isolatedModules": true,
/* Strict Type-Checking Options */
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true,
/* Additional Checks */
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
/* Module Resolution Options */
// "moduleResolution": "node",
// "baseUrl": "./",
// "paths": {},
// "rootDirs": [],
// "typeRoots": [],
// "types": [],
// "allowSyntheticDefaultImports": true,
"esModuleInterop": true,
// "preserveSymlinks": true,
/* Source Map Options */
// "sourceRoot": "./",
// "mapRoot": "./",
// "inlineSourceMap": true,
// "inlineSources": true,
/* Experimental Options */
// "experimentalDecorators": true,
// "emitDecoratorMetadata": true,
},
"include": ["./src"]
}

View File

@ -1,63 +0,0 @@
{
"manifest_version": 2,
"name": "Share Freedom",
"description": "share the current tab on the fediverse",
"version": "2.1.3",
"author": "Miguel",
"background": {
"scripts": ["src/js/background.js"],
"persistent": true
},
"browser_action": {
"default_icon": "src/img/icon-32-dark.png",
"default_popup": "src/html/index.html",
"default_title": "Share freedom",
"theme_icons": [{
"light": "src/img/icon-16-light.png",
"dark": "src/img/icon-16-dark.png",
"size": 16
}, {
"light": "src/img/icon-32-light.png",
"dark": "src/img/icon-32-dark.png",
"size": 32
}]
},
"icons": {
"16":"src/img/icon-16-dark.png",
"32":"src/img/icon-32-dark.png"
},
"commands": {
"_execute_browser_action": {
"suggested_key": {
"default": "Ctrl+Shift+U"
},
"description": "Execute the extension"
}
},
"options_ui": {
"page": "src/html/options.html",
"browser_style": true,
"chrome_style": true
},
"applications": {
"gecko": {
"id": "{c5880375-5496-4d02-ba27-7830809dbf08}",
"strict_min_version": "59.0"
}
},
"permissions": [
"tabs",
"activeTab",
"https://*/*",
"storage"
]
}

25548
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,29 +1,73 @@
{ {
"name": "share-freedom", "name": "fedishare",
"version": "2.2.0", "version": "0.9.0",
"description": "Share the current tab on the fediverse", "description": "Share the current tab on the fediverse",
"main": "index.js", "main": "background.js",
"scripts": { "scripts": {
"build:css": "postcss ./src/css/styles.css -o ./src/css/main.css", "code:lint": "eslint '**/**/*.{ts,tsx}'",
"build": "NODE_ENV=production postcss ./src/css/styles.css -o ./src/css/main.css" "code:lint-fix": "eslint --fix '**/**/*.{ts,tsx}'",
"code:prettier": "prettier --write '**/**/*.{ts,tsx}'",
"code:typecheck": "./node_modules/.bin/tsc --noEmit",
"app:chrome": "rimraf dist && cross-env BROWSER='chrome' webpack --config webpack/webpack.prod.js",
"app:chrome-dev": "cross-env BROWSER='chrome' webpack --config webpack/webpack.dev.js --watch",
"app:edge": "rimraf dist && cross-env BROWSER='edge' webpack --config webpack/webpack.prod.js",
"app:edge-dev": "cross-env BROWSER='edge' webpack --config webpack/webpack.dev.js --watch",
"app:firefox": "rimraf dist && cross-env BROWSER='firefox' webpack --config webpack/webpack.prod.js",
"app:firefox-dev": "cross-env BROWSER='firefox' webpack --config webpack/webpack.dev.js --watch",
"test:unit": "jest",
"build:css": "postcss ./public/css/styles.css -o ./dist/css/main.css",
"build": "NODE_ENV=production postcss ./public/css/styles.css -o ./dist/css/main.css"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://gitlab.com/mugcake/share-freedom-extension.git" "url": "git+https://gitlab.com/mugcake/fedishare.git"
}, },
"keywords": [ "keywords": [
"share", "chrome extension",
"fediverse" "microsoft edge extension",
"firefox addon",
"web extension",
"typescript",
"ts",
"jest",
"sinon"
], ],
"author": "Mickie", "author": "Mickie <millet@tuta.io>",
"license": "GPL-3.0", "license": "GPL-3.0",
"bugs": { "bugs": {
"url": "https://gitlab.com/mugcake/share-freedom-extension/issues" "url": "https://gitlab.com/mugcake/fedishare/issues"
}, },
"homepage": "https://gitlab.com/mugcake/share-freedom-extension#readme", "homepage": "https://gitlab.com/mugcake/fedishare#readme",
"dependencies": { "devDependencies": {
"autoprefixer": "^10.2.5", "@babel/preset-env": "7.12.11",
"@babel/preset-typescript": "7.12.7",
"@types/chrome": "0.0.135",
"@types/jest": "26.0.20",
"@types/sinon": "^10.0.0",
"@typescript-eslint/eslint-plugin": "4.17.0",
"@typescript-eslint/parser": "4.17.0",
"autoprefixer": "^10.3.1",
"babel-jest": "26.6.3",
"copy-webpack-plugin": "^8.1.1",
"cross-env": "7.0.3",
"eslint": "7.21.0",
"eslint-plugin-import": "2.22.1",
"git-hooks-plus": "1.0.1",
"jest": "26.6.3",
"postcss": "^8.3.6",
"postcss-cli": "^8.3.1", "postcss-cli": "^8.3.1",
"tailwindcss": "^2.0.4" "prettier": "2.2.1",
"rimraf": "3.0.2",
"sinon": "^10.0.0",
"tailwindcss": "^2.2.7",
"terser-webpack-plugin": "5.1.1",
"ts-jest": "26.4.4",
"ts-loader": "^9.1.1",
"typescript": "^4.2.4",
"web-ext-types": "3.2.1",
"webpack": "5.18.0",
"webpack-cli": "4.4.0",
"webpack-merge": "5.7.3",
"whatwg-fetch": "3.0.0"
} }
} }

View File

@ -1,6 +1,6 @@
module.exports ={ module.exports = {
plugins: { plugins: {
tailwindcss: {}, tailwindcss: {},
autoprefixer: {} autoprefixer: {},
} },
} };

View File

@ -0,0 +1,27 @@
{
"name": "datetime",
"version": "1.0",
"description": "Build a Datetime Extension!",
"permissions": [
"declarativeContent"
],
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "images/logo/date-time-16.png",
"32": "images/logo/date-time-32.png",
"48": "images/logo/date-time-48.png",
"128": "images/logo/date-time-128.png"
}
},
"icons": {
"16": "images/logo/date-time-16.png",
"32": "images/logo/date-time-32.png",
"48": "images/logo/date-time-48.png",
"128": "images/logo/date-time-128.png"
}
}

12
public/css/fork-awesome.min.css vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

58
public/css/styles.css Normal file
View File

@ -0,0 +1,58 @@
@tailwind base;
@tailwind components;
/* popout */
.button {
@apply bg-white text-gray-800 font-bold py-3 px-3;
}
.icon {
@apply text-xl;
}
.btn-mastodon {
@apply hover:bg-blue-200 hover:text-blue-700 active:bg-blue-400;
}
.btn-pleroma {
@apply hover:bg-yellow-400 hover:text-white active:bg-yellow-500;
}
.btn-diaspora {
@apply hover:bg-gray-900 hover:text-white active:bg-gray-700;
}
.btn-friendica {
@apply hover:bg-blue-700 hover:text-yellow-300 active:bg-blue-800;
}
.btn-hubzilla {
@apply hover:bg-indigo-800 hover:text-white active:bg-indigo-900;
}
.btn-lemmy {
@apply hover:bg-green-700 hover:text-white active:bg-green-800;
}
.btn-socialhome {
@apply hover:bg-gray-700 hover:text-green-300 active:bg-gray-800;
}
.btn-gnusocial {
@apply hover:bg-red-200 hover:text-red-800 active:bg-red-400;
}
.btn-xmpp {
@apply hover:bg-gray-200 hover:text-green-500 active:bg-gray-300;
}
.btn-options {
@apply cursor-pointer hover:bg-gray-100 hover:text-black active:bg-gray-300;
}
/* options */
.span-custom {
@apply text-xl text-blue-700 border border-2 font-bold rounded-l px-4 py-2 bg-white;
}
.text-custom {
@apply border px-4 py-2 w-full;
}
.checkbox-custom {
@apply m-3;
}
.btn-save {
@apply bg-blue-500 text-xl hover:bg-pink-500 active:bg-pink-700 text-white font-bold py-2 px-4 rounded-full w-44 text-center;
}
@tailwind utilities;

446
public/css/v5-compat.css Normal file
View File

@ -0,0 +1,446 @@
/*!
Fork Awesome 1.1.7
License - https://forkaweso.me/Fork-Awesome/license
Copyright 2018 Dave Gandy & Fork Awesome
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.
*/
.fas,
.fab,
.far {
display: inline-block;
font: normal normal normal 14px/1 ForkAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.fas.fa-chart-area:before {
content: "\f1fe";
}
.fas.fa-arrows-alt:before {
content: "\f047";
}
.fas.fa-expand-arrows-alt:before {
content: "\f0b2";
}
.fas.fa-arrows-alt-h:before {
content: "\f07e";
}
.fas.fa-arrows-alt-v:before {
content: "\f07d";
}
.fas.fa-calendar-alt:before {
content: "\f073";
}
.fas.fa-circle-notch:before {
content: "\f1ce";
}
.fas.fa-cloud-download-alt:before {
content: "\f0ed";
}
.fas.fa-cloud-upload-alt:before {
content: "\f0ee";
}
.fas.fa-credit-card:before {
content: "\f283";
}
.fas.fa-dollar-sign:before {
content: "\f155";
}
.fas.fa-euro-sign:before {
content: "\f153";
}
.fas.fa-exchange-alt:before {
content: "\f0ec";
}
.fas.fa-external-link-alt:before {
content: "\f08e";
}
.fas.fa-external-link-square-alt:before {
content: "\f14c";
}
.fas.fa-eye-dropper:before {
content: "\f1fb";
}
.fas.fa-pound-sign:before {
content: "\f154";
}
.fas.fa-glass-martini:before {
content: "\f000";
}
.fas.fa-shekel-sign:before {
content: "\f20b";
}
.fas.fa-rupee-sign:before {
content: "\f156";
}
.fas.fa-won-sign:before {
content: "\f159";
}
.fas.fa-level-down-alt:before {
content: "\f149";
}
.fas.fa-level-up-alt:before {
content: "\f148";
}
.fas.fa-chart-line:before {
content: "\f201";
}
.fas.fa-long-arrow-alt-down:before {
content: "\f175";
}
.fas.fa-long-arrow-alt-left:before {
content: "\f177";
}
.fas.fa-long-arrow-alt-right:before {
content: "\f178";
}
.fas.fa-long-arrow-alt-up:before {
content: "\f176";
}
.fas.fa-map-marker-alt:before {
content: "\f041";
}
.fas.fa-mobile-alt:before {
content: "\f10b";
}
.fas.fa-pencil-alt:before {
content: "\f040";
}
.fas.fa-pen-square:before {
content: "\f14b";
}
.fas.fa-chart-pie:before {
content: "\f200";
}
.fas.fa-yen-sign:before {
content: "\f157";
}
.fas.fa-ruble-sign:before {
content: "\f158";
}
.fas.fa-shield-alt:before {
content: "\f132";
}
.fas.fa-sign-in-alt:before {
content: "\f090";
}
.fas.fa-sign-out-alt:before {
content: "\f08b";
}
.fas.fa-sliders-h:before {
content: "\f1de";
}
.fas.fa-tablet-alt:before {
content: "\f10a";
}
.fas.fa-tachometer-alt:before {
content: "\f0e4";
}
.fas.fa-thumbtack:before {
content: "\f08d";
}
.fas.fa-ticket-alt:before {
content: "\f145";
}
.fas.fa-trash-alt:before {
content: "\f1f8";
}
.fas.fa-lira-sign:before {
content: "\f195";
}
.fab.fa-linkedin-in:before {
content: "\fe01";
}
.fab.fa-linkedin:before {
content: "\f08c";
}
.far.fa-address-book:before {
content: "\f2ba";
}
.far.fa-address-card:before {
content: "\f2bc";
}
.far.fa-arrow-alt-circle-down:before {
content: "\f01a";
}
.far.fa-arrow-alt-circle-left:before {
content: "\f190";
}
.far.fa-arrow-alt-circle-right:before {
content: "\f18e";
}
.far.fa-arrow-alt-circle-up:before {
content: "\f01b";
}
.far.fa-bell:before {
content: "\f0f3";
}
.far.fa-bell-slash:before {
content: "\f1f7";
}
.far.fa-bookmark:before {
content: "\f097";
}
.far.fa-building:before {
content: "\f0f7";
}
.far.fa-calendar-check:before {
content: "\f274";
}
.far.fa-calendar-minus:before {
content: "\f272";
}
.far.fa-calendar:before {
content: "\f133";
}
.far.fa-calendar-plus:before {
content: "\f271";
}
.far.fa-calendar-times:before {
content: "\f273";
}
.far.fa-caret-square-down:before {
content: "\f150";
}
.far.fa-caret-square-left:before {
content: "\f191";
}
.far.fa-caret-square-right:before {
content: "\f152";
}
.far.fa-caret-square-up:before {
content: "\f151";
}
.far.fa-check-circle:before {
content: "\f05d";
}
.far.fa-check-square:before {
content: "\f046";
}
.far.fa-circle:before {
content: "\f10c";
}
.far.fa-clock:before {
content: "\f017";
}
.far.fa-comment:before {
content: "\f0e5";
}
.far.fa-comment-dots:before {
content: "\f27b";
}
.far.fa-comments:before {
content: "\f0e6";
}
.far.fa-dot-circle:before {
content: "\f192";
}
.far.fa-id-card:before {
content: "\f2c3";
}
.far.fa-envelope:before {
content: "\f003";
}
.far.fa-envelope-open:before {
content: "\f2b7";
}
.far.fa-file-archive:before {
content: "\f1c6";
}
.far.fa-file-audio:before {
content: "\f1c7";
}
.far.fa-file-code:before {
content: "\f1c9";
}
.far.fa-file-excel:before {
content: "\f1c3";
}
.far.fa-file-image:before {
content: "\f1c5";
}
.far.fa-file-video:before {
content: "\f1c8";
}
.far.fa-copy:before,
.far.fa-file:before {
content: "\f016";
}
.far.fa-file-pdf:before {
content: "\f1c1";
}
.far.fa-file-powerpoint:before {
content: "\f1c4";
}
.far.fa-file-alt:before {
content: "\f0f6";
}
.far.fa-file-word:before {
content: "\f1c2";
}
.far.fa-flag:before {
content: "\f11d";
}
.far.fa-save:before {
content: "\f0c7";
}
.far.fa-folder:before {
content: "\f114";
}
.far.fa-folder-open:before {
content: "\f115";
}
.far.fa-frown:before {
content: "\f119";
}
.far.fa-futbol:before {
content: "\f1e3";
}
.far.fa-hand-rock:before {
content: "\f255";
}
.far.fa-hand-lizard:before {
content: "\f258";
}
.far.fa-hand-point-down:before {
content: "\f0a7";
}
.far.fa-hand-point-left:before {
content: "\f0a5";
}
.far.fa-hand-point-right:before {
content: "\f0a4";
}
.far.fa-hand-point-up:before {
content: "\f0a6";
}
.far.fa-hand-paper:before {
content: "\256";
}
.far.fa-hand-pointer:before {
content: "\f25a";
}
.far.fa-hand-scissors:before {
content: "\f257";
}
.far.fa-hand-spock:before {
content: "\f259";
}
.far.fa-handshake:before {
content: "\f2b5";
}
.far.fa-hdd:before {
content: "\f0a0";
}
.far.fa-heart:before {
content: "\f08a";
}
.far.fa-hospital:before {
content: "\f0f8";
}
.far.fa-hourglass:before {
content: "\f250";
}
.far.fa-id-card:before {
content: "\f2c3";
}
.far.fa-keyboard:before {
content: "\f11c";
}
.far.fa-lemon:before {
content: "\f094";
}
.far.fa-lightbulb:before {
content: "\f0eb";
}
.far.fa-meh:before {
content: "\f11a";
}
.far.fa-minus-square:before {
content: "\f147";
}
.far.fa-money-bill-alt:before {
content: "\f0d6";
}
.far.fa-moon:before {
content: "\f186";
}
.far.fa-newspaper:before {
content: "\f1ea";
}
.far.fa-paper-plane:before {
content: "\f1d9";
}
.far.fa-pause-circle:before {
content: "\f28c";
}
.far.fa-edit:before {
content: "\f044";
}
.far.fa-image:before {
content: "\f03e";
}
.far.fa-play-circle:before {
content: "\f01d";
}
.far.fa-plus-square:before {
content: "\f196";
}
.far.fa-question-circle:before {
content: "\f92c";
}
.far.fa-share-square:before {
content: "\f045";
}
.far.fa-smile:before {
content: "\f118";
}
.far.fa-snowflake:before {
content: "\f2dc";
}
.far.fa-futbol:before {
content: "\f1e3";
}
.far.fa-star-half:before {
content: "\f089";
}
.far.fa-star:before {
content: "\f006";
}
.far.fa-sticky-note:before {
content: "\f24a";
}
.far.fa-stop-circle:before {
content: "\f28e";
}
.far.fa-sun:before {
content: "\f185";
}
.far.fa-thumbs-down:before {
content: "\f088";
}
.far.fa-thumbs-up:before {
content: "\f087";
}
.far.fa-times-circle:before {
content: "\f05c";
}
.far.fa-window-close:before {
content: "\f2d4";
}
.far.fa-trash-alt:before {
content: "\f014";
}
.far.fa-user-circle:before {
content: "\f2be";
}
.far.fa-user:before {
content: "\f2c0";
}

12
public/css/v5-compat.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":3,"sources":["v5-compat.css"],"names":[],"mappings":";;;;;;;;;;;AAaA,KACA,KAFA,KAGE,QAAA,aACA,KAAA,OAAA,OAAA,OAAA,KAAA,EAAA,YACA,UAAA,QACA,eAAA,KACA,uBAAA,YACA,wBAAA,UAEgB,0BAChB,QAAA,QAEgB,0BAChB,QAAA,QAEuB,iCACvB,QAAA,QAEkB,4BAClB,QAAA,QAEkB,4BAClB,QAAA,QAEkB,4BAClB,QAAA,QAEkB,4BAClB,QAAA,QAEwB,kCACxB,QAAA,QAEsB,gCACtB,QAAA,QAEiB,2BACjB,QAAA,QAEiB,2BACjB,QAAA,QAEe,yBACf,QAAA,QAEkB,4BAClB,QAAA,QAEuB,iCACvB,QAAA,QAE8B,wCAC9B,QAAA,QAEiB,2BACjB,QAAA,QAEgB,0BAChB,QAAA,QAEmB,6BACnB,QAAA,QAEiB,2BACjB,QAAA,QAEgB,0BAChB,QAAA,QAEc,wBACd,QAAA,QAEoB,8BACpB,QAAA,QAEkB,4BAClB,QAAA,QAEgB,0BAChB,QAAA,QAEyB,mCACzB,QAAA,QAEyB,mCACzB,QAAA,QAE0B,oCAC1B,QAAA,QAEuB,iCACvB,QAAA,QAEoB,8BACpB,QAAA,QAEgB,0BAChB,QAAA,QAEgB,0BAChB,QAAA,QAEgB,0BAChB,QAAA,QAEe,yBACf,QAAA,QAEc,wBACd,QAAA,QAEgB,0BAChB,QAAA,QAEgB,0BAChB,QAAA,QAEiB,2BACjB,QAAA,QAEkB,4BAClB,QAAA,QAEe,yBACf,QAAA,QAEgB,0BAChB,QAAA,QAEoB,8BACpB,QAAA,QAEe,yBACf,QAAA,QAEgB,0BAChB,QAAA,QAEe,yBACf,QAAA,QAEe,yBACf,QAAA,QAEiB,2BACjB,QAAA,QAEc,wBACd,QAAA,QAEkB,4BAClB,QAAA,QAEkB,4BAClB,QAAA,QAE2B,qCAC3B,QAAA,QAE2B,qCAC3B,QAAA,QAE4B,sCAC5B,QAAA,QAEyB,mCACzB,QAAA,QAEU,oBACV,QAAA,QAEgB,0BAChB,QAAA,QAEc,wBACd,QAAA,QAEc,wBACd,QAAA,QAEoB,8BACpB,QAAA,QAEoB,8BACpB,QAAA,QAEc,wBACd,QAAA,QAEmB,6BACnB,QAAA,QAEoB,8BACpB,QAAA,QAEuB,iCACvB,QAAA,QAEuB,iCACvB,QAAA,QAEwB,kCACxB,QAAA,QAEqB,+BACrB,QAAA,QAEkB,4BAClB,QAAA,QAEkB,4BAClB,QAAA,QAEY,sBACZ,QAAA,QAEW,qBACX,QAAA,QAEa,uBACb,QAAA,QAEkB,4BAClB,QAAA,QAEc,wBACd,QAAA,QAEgB,0BAChB,QAAA,QAEa,uBACb,QAAA,QAEc,wBACd,QAAA,QAEmB,6BACnB,QAAA,QAEkB,4BAClB,QAAA,QAEgB,0BAChB,QAAA,QAEe,yBACf,QAAA,QAEgB,0BAChB,QAAA,QAEgB,0BAChB,QAAA,QAEgB,0BAChB,QAAA,QAEU,oBACA,oBACV,QAAA,QAEc,wBACd,QAAA,QAEqB,+BACrB,QAAA,QAEc,wBACd,QAAA,QAEe,yBACf,QAAA,QAEU,oBACV,QAAA,QAEU,oBACV,QAAA,QAEY,sBACZ,QAAA,QAEiB,2BACjB,QAAA,QAEW,qBACX,QAAA,QAEY,sBACZ,QAAA,QAEe,yBACf,QAAA,QAEiB,2BACjB,QAAA,QAEqB,+BACrB,QAAA,QAEqB,+BACrB,QAAA,QAEsB,gCACtB,QAAA,QAEmB,6BACnB,QAAA,QAEgB,0BAChB,QAAA,OAEkB,4BAClB,QAAA,QAEmB,6BACnB,QAAA,QAEgB,0BAChB,QAAA,QAEe,yBACf,QAAA,QAES,mBACT,QAAA,QAEW,qBACX,QAAA,QAEc,wBACd,QAAA,QAEe,yBACf,QAAA,QAEa,uBACb,QAAA,QAEc,wBACd,QAAA,QAEW,qBACX,QAAA,QAEe,yBACf,QAAA,QAES,mBACT,QAAA,QAEkB,4BAClB,QAAA,QAEoB,8BACpB,QAAA,QAEU,oBACV,QAAA,QAEe,yBACf,QAAA,QAEiB,2BACjB,QAAA,QAEkB,4BAClB,QAAA,QAEU,oBACV,QAAA,QAEW,qBACX,QAAA,QAEiB,2BACjB,QAAA,QAEiB,2BACjB,QAAA,QAEqB,+BACrB,QAAA,QAEkB,4BAClB,QAAA,QAEW,qBACX,QAAA,QAEe,yBACf,QAAA,QAEY,sBACZ,QAAA,QAEe,yBACf,QAAA,QAEU,oBACV,QAAA,QAEiB,2BACjB,QAAA,QAEiB,2BACjB,QAAA,QAES,mBACT,QAAA,QAEiB,2BACjB,QAAA,QAEe,yBACf,QAAA,QAEkB,4BAClB,QAAA,QAEkB,4BAClB,QAAA,QAEe,yBACf,QAAA,QAEiB,2BACjB,QAAA,QAEU,oBACV,QAAA"}

27
public/edge_manifest.json Normal file
View File

@ -0,0 +1,27 @@
{
"name": "datetime",
"version": "1.0",
"description": "Build a Datetime Extension!",
"permissions": [
"declarativeContent"
],
"manifest_version": 2,
"background": {
"content_scripts": "background.js"
},
"browser_action": {
"default_popup": "popup.html",
"default_icon": {
"16": "images/logo/date-time-16.png",
"32": "images/logo/date-time-32.png",
"48": "images/logo/date-time-48.png",
"128": "images/logo/date-time-128.png"
}
},
"icons": {
"16": "images/logo/date-time-16.png",
"32": "images/logo/date-time-32.png",
"48": "images/logo/date-time-48.png",
"128": "images/logo/date-time-128.png"
}
}

View File

@ -0,0 +1,21 @@
{
"name": "Fedishare",
"version": "0.9.0",
"description": "Share the current tab on the fediverse",
"permissions": ["tabs", "activeTab", "https://*/*", "storage"],
"manifest_version": 2,
"browser_action": {
"default_popup": "popup.html",
"default_icon": "images/logo/logo.svg",
"default_title": "Fedishare"
},
"options_ui": {
"page": "options.html"
},
"applications": {
"gecko": {
"id": "{c5880375-5496-4d02-ba27-7830809dbf08}",
"strict_min_version": "59.0"
}
}
}

View File

Before

Width:  |  Height:  |  Size: 470 KiB

After

Width:  |  Height:  |  Size: 470 KiB

170
public/images/logo/logo.svg Normal file
View File

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="64.139938mm"
height="64.139938mm"
viewBox="0 0 64.139939 64.139939"
version="1.1"
id="svg5"
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
sodipodi:docname="logo1.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#111111"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:document-units="mm"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="0.53183923"
inkscape:cx="187.08661"
inkscape:cy="331.86721"
inkscape:window-width="1366"
inkscape:window-height="722"
inkscape:window-x="1366"
inkscape:window-y="46"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-36.247858,-3.9111803)">
<g
id="g1977"
transform="matrix(0.34447216,0,0,0.34447216,-23.727704,18.906576)"
style="display:inline">
<circle
style="display:inline;fill:#374548;stroke-width:9.68693"
id="path426-0"
cx="267.20746"
cy="49.567352"
r="93.098869" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ccff00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 217.45324,24.073894 a 18.227783,18.227783 0 0 1 -7.79591,7.759731 l 42.79842,42.96534 10.31823,-5.22914 z m 56.45236,56.670441 -10.31823,5.22914 21.68601,21.770755 a 18.227783,18.227783 0 0 1 7.79746,-7.760755 z"
id="path9722-62"
inkscape:connector-curvature="0" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 323.42299,41.074404 -24.22953,12.279355 1.78646,11.427206 27.41486,-13.894239 a 18.227783,18.227783 0 0 1 -4.97179,-9.812322 z m -38.29533,19.407603 -57.28901,29.033888 a 18.227783,18.227783 0 0 1 4.97282,9.81335 l 54.10264,-27.41951 z"
id="path9729-6"
inkscape:connector-curvature="0" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 266.70398,-11.036108 -27.6438,53.967247 8.16178,8.193299 29.26901,-57.13863 a 18.227783,18.227783 0 0 1 -9.78699,-5.021916 z M 231.87044,56.967491 217.8682,84.302775 a 18.227783,18.227783 0 0 1 9.78596,5.0214 l 12.37754,-24.1639 z"
id="path9713-1"
inkscape:connector-curvature="0" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 209.41962,31.953516 a 18.227783,18.227783 0 0 1 -9.10591,1.903759 18.227783,18.227783 0 0 1 -1.75958,-0.183967 l 8.17625,52.298097 a 18.227783,18.227783 0 0 1 9.1059,-1.90376 18.227783,18.227783 0 0 1 1.75855,0.18397 z"
id="path1015-8"
inkscape:connector-curvature="0" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 232.85488,99.588145 a 18.227783,18.227783 0 0 1 0.19069,3.671605 18.227783,18.227783 0 0 1 -1.92289,7.19129 l 52.28932,8.39072 a 18.227783,18.227783 0 0 1 -0.1912,-3.67214 18.227783,18.227783 0 0 1 1.92339,-7.19077 z"
id="path1674-7"
inkscape:connector-curvature="0" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 328.57875,51.07793 -24.13496,47.117535 a 18.227783,18.227783 0 0 1 9.78803,5.022425 l 24.13445,-47.117012 a 18.227783,18.227783 0 0 1 -9.78752,-5.022948 z"
id="path1676-9"
inkscape:connector-curvature="0" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 295.6619,-15.562446 a 18.227783,18.227783 0 0 1 -7.79746,7.760766 l 37.37653,37.520708 a 18.227783,18.227783 0 0 1 7.79694,-7.760769 z"
id="path1678-20"
inkscape:connector-curvature="0" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="M 261.5477,-21.039115 214.29942,2.905161 a 18.227783,18.227783 0 0 1 4.97231,9.812319 l 47.24776,-23.945308 a 18.227783,18.227783 0 0 1 -4.97179,-9.811287 z"
id="path1680-2"
inkscape:connector-curvature="0" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 287.77814,-7.758272 a 18.227783,18.227783 0 0 1 -9.25576,1.979723 18.227783,18.227783 0 0 1 -1.59526,-0.167431 l 4.18528,26.799916 11.41997,1.832446 z m -4.23333,44.192652 9.89552,63.363055 a 18.227783,18.227783 0 0 1 8.97309,-1.8371 18.227783,18.227783 0 0 1 1.90686,0.20929 L 294.9653,38.266307 Z"
id="path9758-3"
inkscape:connector-curvature="0" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ccff00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 219.30532,12.918502 a 18.227783,18.227783 0 0 1 0.2005,3.729487 18.227783,18.227783 0 0 1 -1.89445,7.139099 l 26.82058,4.307747 5.27151,-10.294461 z m 45.96774,7.381978 -5.27203,10.295496 63.37132,10.177674 a 18.227783,18.227783 0 0 1 -0.18397,-3.629753 18.227783,18.227783 0 0 1 1.94459,-7.229533 z"
id="path9760-7"
inkscape:connector-curvature="0" />
<circle
style="display:inline;fill:#ffffff;fill-opacity:0.995968;stroke:none;stroke-width:0.264583;stroke-opacity:0.960784"
id="path817-5"
cx="277.79572"
cy="-39.146599"
r="16.570711"
transform="rotate(3.1178174)" />
<circle
id="path819-9"
style="display:inline;fill:#ccff00;fill-opacity:0.995968;stroke:none;stroke-width:0.264583;stroke-opacity:0.960784"
cx="342.95813"
cy="19.511126"
r="16.570711"
transform="rotate(3.1178174)" />
<circle
id="path823-2"
style="display:inline;fill:#ccff00;fill-opacity:0.995968;stroke:none;stroke-width:0.264583;stroke-opacity:0.960784"
cx="307.29355"
cy="99.594879"
r="16.570711"
transform="rotate(3.1178174)" />
<circle
style="display:inline;fill:#ffffff;fill-opacity:0.995968;stroke:none;stroke-width:0.264583;stroke-opacity:0.960784"
id="path825-2"
cx="220.08923"
cy="90.431641"
r="16.570711"
transform="rotate(3.1178174)" />
<circle
id="path827-8"
style="display:inline;fill:#ccff00;fill-opacity:0.995968;stroke:none;stroke-width:0.264583;stroke-opacity:0.960784"
cx="201.85857"
cy="4.6846833"
r="16.570711"
transform="rotate(3.1178174)" />
</g>
</g>
<metadata
id="metadata65">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

20
public/options.html Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="css/fork-awesome.css" rel="stylesheet">
<link href="css/main.css" rel="stylesheet">
</head>
<body class="bg-fixed px-2 py-3 bg-gradient-to-r from-blue-900 via-blue-600 to-blue-400">
<div class="text-5xl px-2 py-4 text-blue-100">Set your instance(s)</div>
<form class="grid gap-5">
<div class="root" id="root"></div>
<button class="btn-save" type="submit">Save changes</button>
</form>
<script src="options.js"></script>
</body>
</html>

20
public/popup.html Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="css/fork-awesome.css" rel="stylesheet">
<link href="css/main.css" rel="stylesheet">
</head>
<body>
<div class="inline-flex">
<div class="root" id="root"></div>
</div>
<script src="popup.js"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
/// <reference types="chrome"/>
chrome.runtime.onInstalled.addListener(function () {
// Make extension work on all pages
chrome.declarativeContent.onPageChanged.removeRules(undefined, function () {
chrome.declarativeContent.onPageChanged.addRules([
{
conditions: [new chrome.declarativeContent.PageStateMatcher({})],
actions: [new chrome.declarativeContent.ShowPageAction()],
},
]);
});
});

View File

@ -0,0 +1,13 @@
/// <reference types="chrome"/>
chrome.runtime.onInstalled.addListener(function () {
// Make extension work on all pages
chrome.declarativeContent.onPageChanged.removeRules(undefined, function () {
chrome.declarativeContent.onPageChanged.addRules([
{
conditions: [new chrome.declarativeContent.PageStateMatcher({})],
actions: [new chrome.declarativeContent.ShowPageAction()],
},
]);
});
});

View File

@ -0,0 +1,2 @@
/// <reference types="web-ext-types"/>

View File

@ -1,841 +0,0 @@
/*! tailwindcss v2.0.4 | MIT License | https://tailwindcss.com */
/*! modern-normalize v1.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */
/*
Document
========
*/
/**
Use a better box model (opinionated).
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
/**
Use a more readable tab size (opinionated).
*/
:root {
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
}
/**
1. Correct the line height in all browsers.
2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/*
Sections
========
*/
/**
Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
*/
body {
font-family:
system-ui,
-apple-system, /* Firefox supports this but not yet `system-ui` */
'Segoe UI',
Roboto,
Helvetica,
Arial,
sans-serif,
'Apple Color Emoji',
'Segoe UI Emoji';
}
/*
Grouping content
================
*/
/**
1. Add the correct height in Firefox.
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
*/
hr {
height: 0; /* 1 */
color: inherit; /* 2 */
}
/*
Text-level semantics
====================
*/
/**
Add the correct text decoration in Chrome, Edge, and Safari.
*/
abbr[title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
}
/**
Add the correct font weight in Edge and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
2. Correct the odd 'em' font sizing in all browsers.
*/
code,
kbd,
samp,
pre {
font-family:
ui-monospace,
SFMono-Regular,
Consolas,
'Liberation Mono',
Menlo,
monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
Prevent 'sub' and 'sup' elements from affecting the line height in all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/*
Tabular data
============
*/
/**
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
*/
table {
text-indent: 0; /* 1 */
border-color: inherit; /* 2 */
}
/*
Forms
=====
*/
/**
1. Change the font styles in all browsers.
2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
Remove the inheritance of text transform in Edge and Firefox.
1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type='button'],
[type='submit'] {
-webkit-appearance: button;
}
/**
Remove the inner border and padding in Firefox.
*/
/**
Restore the focus styles unset by the previous rule.
*/
/**
Remove the additional ':invalid' styles in Firefox.
See: https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737
*/
/**
Remove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.
*/
legend {
padding: 0;
}
/**
Add the correct vertical alignment in Chrome and Firefox.
*/
progress {
vertical-align: baseline;
}
/**
Correct the cursor style of increment and decrement buttons in Safari.
*/
/**
1. Correct the odd appearance in Chrome and Safari.
2. Correct the outline style in Safari.
*/
/**
Remove the inner padding in Chrome and Safari on macOS.
*/
/**
1. Correct the inability to style clickable types in iOS and Safari.
2. Change font properties to 'inherit' in Safari.
*/
/*
Interactive
===========
*/
/*
Add the correct display in Chrome and Safari.
*/
summary {
display: list-item;
}
/**
* Manually forked from SUIT CSS Base: https://github.com/suitcss/base
* A thin layer on top of normalize.css that provides a starting point more
* suitable for web applications.
*/
/**
* Removes the default spacing and border for appropriate elements.
*/
blockquote,
dl,
dd,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
figure,
p,
pre {
margin: 0;
}
button {
background-color: transparent;
background-image: none;
}
/**
* Work around a Firefox/IE bug where the transparent `button` background
* results in a loss of the default `button` focus styles.
*/
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
fieldset {
margin: 0;
padding: 0;
}
ol,
ul {
list-style: none;
margin: 0;
padding: 0;
}
/**
* Tailwind custom reset styles
*/
/**
* 1. Use the user's configured `sans` font-family (with Tailwind's default
* sans-serif font stack as a fallback) as a sane default.
* 2. Use Tailwind's default "normal" line-height so the user isn't forced
* to override it to ensure consistency even when using the default theme.
*/
html {
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 1 */
line-height: 1.5; /* 2 */
}
/**
* Inherit font-family and line-height from `html` so users can set them as
* a class directly on the `html` element.
*/
body {
font-family: inherit;
line-height: inherit;
}
/**
* 1. Prevent padding and border from affecting element width.
*
* We used to set this in the html element and inherit from
* the parent element for everything else. This caused issues
* in shadow-dom-enhanced elements like <details> where the content
* is wrapped by a div with box-sizing set to `content-box`.
*
* https://github.com/mozdevs/cssremedy/issues/4
*
*
* 2. Allow adding a border to an element by just adding a border-width.
*
* By default, the way the browser specifies that an element should have no
* border is by setting it's border-style to `none` in the user-agent
* stylesheet.
*
* In order to easily add borders to elements by just setting the `border-width`
* property, we change the default border-style for all elements to `solid`, and
* use border-width to hide them instead. This way our `border` utilities only
* need to set the `border-width` property instead of the entire `border`
* shorthand, making our border utilities much more straightforward to compose.
*
* https://github.com/tailwindcss/tailwindcss/pull/116
*/
*,
::before,
::after {
box-sizing: border-box; /* 1 */
border-width: 0; /* 2 */
border-style: solid; /* 2 */
border-color: #e5e7eb; /* 2 */
}
/*
* Ensure horizontal rules are visible by default
*/
hr {
border-top-width: 1px;
}
/**
* Undo the `border-style: none` reset that Normalize applies to images so that
* our `border-{width}` utilities have the expected effect.
*
* The Normalize reset is unnecessary for us since we default the border-width
* to 0 on all elements.
*
* https://github.com/tailwindcss/tailwindcss/issues/362
*/
img {
border-style: solid;
}
textarea {
resize: vertical;
}
input::-moz-placeholder, textarea::-moz-placeholder {
opacity: 1;
color: #9ca3af;
}
input:-ms-input-placeholder, textarea:-ms-input-placeholder {
opacity: 1;
color: #9ca3af;
}
input::placeholder,
textarea::placeholder {
opacity: 1;
color: #9ca3af;
}
button {
cursor: pointer;
}
table {
border-collapse: collapse;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-size: inherit;
font-weight: inherit;
}
/**
* Reset links to optimize for opt-in styling instead of
* opt-out.
*/
a {
color: inherit;
text-decoration: inherit;
}
/**
* Reset form element properties that are easy to forget to
* style explicitly so you don't inadvertently introduce
* styles that deviate from your design system. These styles
* supplement a partial reset that is already applied by
* normalize.css.
*/
button,
input,
optgroup,
select,
textarea {
padding: 0;
line-height: inherit;
color: inherit;
}
/**
* Use the configured 'mono' font family for elements that
* are expected to be rendered with a monospace font, falling
* back to the system monospace stack if there is no configured
* 'mono' font family.
*/
pre,
code,
kbd,
samp {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
/**
* Make replaced elements `display: block` by default as that's
* the behavior you want almost all of the time. Inspired by
* CSS Remedy, with `svg` added as well.
*
* https://github.com/mozdevs/cssremedy/issues/14
*/
img,
svg,
video,
canvas,
audio,
iframe,
embed,
object {
display: block;
vertical-align: middle;
}
/**
* Constrain images and videos to the parent width and preserve
* their instrinsic aspect ratio.
*
* https://github.com/mozdevs/cssremedy/issues/14
*/
img,
video {
max-width: 100%;
height: auto;
}
/* index */
.button {
--tw-bg-opacity: 1;
background-color: rgba(209, 213, 219, var(--tw-bg-opacity));
}
.button:hover {
--tw-bg-opacity: 1;
background-color: rgba(156, 163, 175, var(--tw-bg-opacity));
}
.button {
font-weight: 700;
padding-left: 1rem;
padding-right: 1rem;
padding-top: 0.125rem;
padding-bottom: 0.125rem;
--tw-text-opacity: 1;
color: rgba(31, 41, 55, var(--tw-text-opacity));
}
.icon {
font-size: 1.875rem;
line-height: 2.25rem;
}
.btn-mastodon:hover {
--tw-bg-opacity: 1;
background-color: rgba(191, 219, 254, var(--tw-bg-opacity));
--tw-text-opacity: 1;
color: rgba(29, 78, 216, var(--tw-text-opacity));
}
.btn-pleroma:hover {
--tw-bg-opacity: 1;
background-color: rgba(251, 191, 36, var(--tw-bg-opacity));
--tw-text-opacity: 1;
color: rgba(255, 255, 255, var(--tw-text-opacity));
}
.btn-diaspora:hover {
--tw-bg-opacity: 1;
background-color: rgba(17, 24, 39, var(--tw-bg-opacity));
--tw-text-opacity: 1;
color: rgba(255, 255, 255, var(--tw-text-opacity));
}
.btn-friendica:hover {
--tw-bg-opacity: 1;
background-color: rgba(29, 78, 216, var(--tw-bg-opacity));
--tw-text-opacity: 1;
color: rgba(252, 211, 77, var(--tw-text-opacity));
}
.btn-hubzilla:hover {
--tw-bg-opacity: 1;
background-color: rgba(55, 48, 163, var(--tw-bg-opacity));
--tw-text-opacity: 1;
color: rgba(255, 255, 255, var(--tw-text-opacity));
}
.btn-lemmy:hover {
--tw-bg-opacity: 1;
background-color: rgba(4, 120, 87, var(--tw-bg-opacity));
--tw-text-opacity: 1;
color: rgba(255, 255, 255, var(--tw-text-opacity));
}
.btn-socialhome:hover {
--tw-bg-opacity: 1;
background-color: rgba(55, 65, 81, var(--tw-bg-opacity));
--tw-text-opacity: 1;
color: rgba(110, 231, 183, var(--tw-text-opacity));
}
.btn-gnusocial:hover {
--tw-bg-opacity: 1;
background-color: rgba(254, 202, 202, var(--tw-bg-opacity));
--tw-text-opacity: 1;
color: rgba(153, 27, 27, var(--tw-text-opacity));
}
.btn-xmpp:hover {
--tw-bg-opacity: 1;
background-color: rgba(30, 58, 138, var(--tw-bg-opacity));
--tw-text-opacity: 1;
color: rgba(16, 185, 129, var(--tw-text-opacity));
}
.btn-options:hover {
--tw-bg-opacity: 1;
background-color: rgba(243, 244, 246, var(--tw-bg-opacity));
}
.btn-options {
cursor: pointer;
}
.btn-options:hover {
--tw-text-opacity: 1;
color: rgba(0, 0, 0, var(--tw-text-opacity));
}
/* options */
.span-custom {
--tw-bg-opacity: 1;
background-color: rgba(255, 255, 255, var(--tw-bg-opacity));
border-top-left-radius: 0.25rem;
border-bottom-left-radius: 0.25rem;
border-width: 2px;
border-width: 1px;
font-weight: 700;
font-size: 1.25rem;
line-height: 1.75rem;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
padding-left: 1rem;
padding-right: 1rem;
--tw-text-opacity: 1;
color: rgba(29, 78, 216, var(--tw-text-opacity));
}
.text-custom {
border-width: 2px;
border-width: 1px;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
padding-left: 1rem;
padding-right: 1rem;
width: 100%;
}
.checkbox-custom {
margin: 0.75rem;
}
.btn-save {
--tw-bg-opacity: 1;
background-color: rgba(59, 130, 246, var(--tw-bg-opacity));
}
.btn-save:hover {
--tw-bg-opacity: 1;
background-color: rgba(29, 78, 216, var(--tw-bg-opacity));
}
.btn-save {
border-radius: 9999px;
font-weight: 700;
font-size: 1.25rem;
line-height: 1.75rem;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
padding-left: 1rem;
padding-right: 1rem;
text-align: center;
--tw-text-opacity: 1;
color: rgba(255, 255, 255, var(--tw-text-opacity));
width: 11rem;
}
.bg-fixed {
background-attachment: fixed;
}
.bg-gray-500 {
--tw-bg-opacity: 1;
background-color: rgba(107, 114, 128, var(--tw-bg-opacity));
}
.flex {
display: flex;
}
.inline-flex {
display: inline-flex;
}
.table {
display: table;
}
.grid {
display: grid;
}
.hidden {
display: none;
}
.text-5xl {
font-size: 3rem;
line-height: 1;
}
.px-2 {
padding-left: 0.5rem;
padding-right: 0.5rem;
}
.py-3 {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
}
.py-4 {
padding-top: 1rem;
padding-bottom: 1rem;
}
* {
--tw-shadow: 0 0 #0000;
}
* {
--tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgba(59, 130, 246, 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.text-blue-400 {
--tw-text-opacity: 1;
color: rgba(96, 165, 250, var(--tw-text-opacity));
}
.gap-5 {
gap: 1.25rem;
}
@-webkit-keyframes spin {
to {
transform: rotate(360deg);
}
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
@-webkit-keyframes ping {
75%, 100% {
transform: scale(2);
opacity: 0;
}
}
@keyframes ping {
75%, 100% {
transform: scale(2);
opacity: 0;
}
}
@-webkit-keyframes pulse {
50% {
opacity: .5;
}
}
@keyframes pulse {
50% {
opacity: .5;
}
}
@-webkit-keyframes bounce {
0%, 100% {
transform: translateY(-25%);
-webkit-animation-timing-function: cubic-bezier(0.8,0,1,1);
animation-timing-function: cubic-bezier(0.8,0,1,1);
}
50% {
transform: none;
-webkit-animation-timing-function: cubic-bezier(0,0,0.2,1);
animation-timing-function: cubic-bezier(0,0,0.2,1);
}
}
@keyframes bounce {
0%, 100% {
transform: translateY(-25%);
-webkit-animation-timing-function: cubic-bezier(0.8,0,1,1);
animation-timing-function: cubic-bezier(0.8,0,1,1);
}
50% {
transform: none;
-webkit-animation-timing-function: cubic-bezier(0,0,0.2,1);
animation-timing-function: cubic-bezier(0,0,0.2,1);
}
}
@media (min-width: 640px) {
}
@media (min-width: 768px) {
}
@media (min-width: 1024px) {
}
@media (min-width: 1280px) {
}
@media (min-width: 1536px) {
}

View File

@ -1,58 +0,0 @@
@tailwind base;
@tailwind components;
/* index */
.button {
@apply bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-0.5 px-4;
}
.icon {
@apply text-3xl;
}
.btn-mastodon {
@apply hover:bg-blue-200 hover:text-blue-700;
}
.btn-pleroma {
@apply hover:bg-yellow-400 hover:text-white;
}
.btn-diaspora {
@apply hover:bg-gray-900 hover:text-white;
}
.btn-friendica {
@apply hover:bg-blue-700 hover:text-yellow-300;
}
.btn-hubzilla {
@apply hover:bg-indigo-800 hover:text-white;
}
.btn-lemmy {
@apply hover:bg-green-700 hover:text-white;
}
.btn-socialhome {
@apply hover:bg-gray-700 hover:text-green-300;
}
.btn-gnusocial {
@apply hover:bg-red-200 hover:text-red-800;
}
.btn-xmpp {
@apply hover:bg-blue-900 hover:text-green-500;
}
.btn-options {
@apply cursor-pointer hover:bg-gray-100 hover:text-black;
}
/* options */
.span-custom {
@apply text-xl text-blue-700 border border-2 font-bold rounded-l px-4 py-2 bg-white;
}
.text-custom {
@apply border border-2 px-4 py-2 w-full;
}
.checkbox-custom {
@apply m-3;
}
.btn-save {
@apply bg-blue-500 text-xl hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full w-44 text-center;
}
@tailwind utilities;

View File

@ -1,76 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="../css/fork-awesome.css" rel="stylesheet">
<link href="../css/main.css" rel="stylesheet">
</head>
<body>
<div class="inline-flex">
<a class="button btn-pleroma" id="url-pleroma" title="Share on Pleroma" hidden>
<span>
<i class="fa fa-pleroma icon"></i>
</span>
<span>Pleroma</span>
</a>
<a class="button btn-mastodon" id="url-mastodon" title="Share on Mastodon / Misskey" hidden>
<span>
<i class="fa fa-mastodon icon"></i>
</span>
<span>Mastodon</span>
</a>
<a class="button btn-gnusocial" id="url-gnusocial" title="Share on GNU Social" hidden>
<span>
<i class="fa fa-gnu-social icon"></i>
</span>
<span>GNUsocial</span>
</a>
<a class="button btn-diaspora" id="url-diaspora" title="Share on Diaspora" hidden>
<span>
<i class="fa fa-diaspora icon"></i>
</span>
<span>Diaspora</span>
</a>
<a class="button btn-friendica" id="url-friendica" title="Share on Friendica" hidden>
<span>
<i class="fa fa-friendica icon"></i>
</span>
<span>Friendica</span>
</a>
<a class="button btn-hubzilla" id="url-hubzilla" title="Share on Hubzilla" hidden>
<span>
<i class="fa fa-hubzilla icon"></i>
</span>
<span>Hubzilla</span>
</a>
<a class="button btn-socialhome" id="url-socialhome" title="Share on Socialhome" hidden>
<span>
<i class="fa fa-social-home icon"></i>
</span>
<span>Socialhome</span>
</a>
<a class="button btn-lemmy" id="url-lemmy" title="Share on Lemmy" hidden>
<span>
<i class="fa fa-activitypub icon"></i>
</span>
<span>Lemmy</span>
</a>
<a class="button btn-xmpp" id="url-xmpp" title="Share on XMPP/Jabber" hidden>
<span>
<i class="fa fa-xmpp icon"></i>
</span>
<span>XMPP</span>
</a>
<a class="button btn-options" id="options" title="Options">
<span>
<i class="fa fa-cog icon"></i>
</span>
<span>Options</span>
</a>
</div>
</body>
<script src="../js/index.js" type="module"></script>
<script src="../js/background.js" type="module"></script>
</html>

View File

@ -1,90 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="../css/fork-awesome.css" rel="stylesheet">
<link href="../css/main.css" rel="stylesheet">
</head>
<body class="bg-fixed px-2 py-3" style="background-image: url('../img/wallpaper.png')">
<!-- <div class="container-fluid py-3">
<div class="row">
<div class="col-8 text-left"><h2>Settings</h2></div>
<div class="col-4 text-right credits">Wallpaper by:
<a href="https://fosstodon.org/@yarmo/101907879701964911">Yarmo</a>
</div>
</div> -->
<div class="text-5xl px-2 py-4 text-blue-400">Set your instance(s)</div>
<form class="grid gap-5">
<div class="flex">
<span class="span-custom">Pleroma:</span>
<input id="pleroma-host" class="text-custom" type="text">
<div class="bg-gray-500">
<input class="checkbox-custom" type="checkbox" id="pleroma-check">
</div>
</div>
<div class="flex">
<span class="span-custom">Mastodon:</span>
<input id="mastodon-host" class="text-custom" type="text">
<div class="bg-gray-500">
<input class="checkbox-custom" type="checkbox" id="mastodon-check">
</div>
</div>
<div class="flex">
<span class="span-custom">GNUsocial:</span>
<input id="gnusocial-host" class="text-custom" type="text">
<div class="bg-gray-500">
<input class="checkbox-custom" type="checkbox" id="gnusocial-check">
</div>
</div>
<div class="flex">
<span class="span-custom">Diaspora:</span>
<input id="diaspora-host" class="text-custom" type="text">
<div class="bg-gray-500">
<input class="checkbox-custom" type="checkbox" id="diaspora-check">
</div>
</div>
<div class="flex">
<span class="span-custom">Friendica:</span>
<input id="friendica-host" class="text-custom" type="text">
<div class="bg-gray-500">
<input class="checkbox-custom" type="checkbox" id="friendica-check">
</div>
</div>
<div class="flex">
<span class="span-custom">Hubzilla:</span>
<input id="hubzilla-host" class="text-custom" type="text">
<div class="bg-gray-500">
<input class="checkbox-custom" type="checkbox" id="hubzilla-check">
</div>
</div>
<div class="flex">
<span class="span-custom">Socialhome</span>
<input id="socialhome-host" class="text-custom" type="text">
<div class="bg-gray-500">
<input class="checkbox-custom" type="checkbox" id="socialhome-check">
</div>
</div>
<div class="flex">
<span class="span-custom">Lemmy:</span>
<input id="lemmy-host" class="text-custom" type="text">
<div class="bg-gray-500">
<input class="checkbox-custom" type="checkbox" id="lemmy-check">
</div>
</div>
<div class="flex">
<span class="span-custom">XMPP:</span>
<input id="xmpp-host" class="text-custom" type="text">
<div class="bg-gray-500">
<input class="checkbox-custom" type="checkbox" id="xmpp-check">
</div>
</div>
<button class="btn-save" type="submit">Save changes</button>
</form>
<script src="../js/options.js" type="module"></script>
<script src="../js/background.js" type="module"></script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 929 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

View File

@ -1,14 +0,0 @@
const host = {
diasporaDefault: `https://joindiaspora.com`,
friendicaDefault: `https://libranet.de`,
gnusocialDefault: `https://gnusocial.net`,
hubzillaDefault: `https://demo.hubzilla.org`,
lemmyDefault: `https://dev.lemmy.ml`,
mastodonDefault: `https://mastodon.social`,
pleromaDefault: `https://blob.cat`,
socialhomeDefault: `https://socialhome.network`,
xmppDefault: `https://suchat.org`,
}
export {host}

View File

@ -1,148 +0,0 @@
/*
Copyleft (ɔ) 2021 Mickie
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { host } from './background.js'
window.onload = () => {
/*
* Assign and get URLs To Respective Element
*/
const urlAssigner = (btn = {}) => {
const { id, href } = btn
const a = document.getElementById(id)
a.href = href
a.target = '_blank'
a.addEventListener('click', e => {
window.setTimeout(() => window.close(), 10)
})
}
(function getCurrentTabUrl() {
const queryInfo = {
active: true,
currentWindow: true,
}
chrome.tabs.query(queryInfo, (tabs = []) => {
if (tabs.length === 0) {
return
}
const tab = (tabs[0] || {});
const tabUrL = encodeURIComponent(tab.url)
const tabTitle = encodeURIComponent(tab.title)
mkBtns(tabUrL, tabTitle)
})
})()
/*
* Make Social Button Objects
*/
const mkBtns = (tabUrl = '', tabTitle = '') => {
// Set post items
const diasporaPost = `/bookmarklet?url=${tabUrl}&title=${tabTitle}&jump-doclose`
const friendicaPost = `/bookmarklet?url=${tabUrl}&title=${tabTitle}&jump-doclose`
const gnusocialPost = `/?action=newnotice&status_textarea=${tabTitle} ${tabUrl}`
const hubzillaPost = `/rpost?body=${tabTitle} &url=${tabUrl}`
const lemmyPost = `/create_post?url=${tabUrl}&title=${tabTitle}`
const mastodonPost = `/share?text=${tabTitle}&url=${tabUrl}`
const pleromaPost = `/share?message=${tabTitle} ${tabUrl}`
const socialhomePost = `/bookmarklet?url=${tabUrl}&title=${tabTitle}&jump-doclose`
const xmppPost = `?message=${tabTitle} ${tabUrl}`
// Set social Buttons
const socialBtns = []
const diaspora = {}
const friendica = {}
const gnusocial = {}
const hubzilla = {}
const lemmy = {}
const mastodon = {}
const pleroma = {}
const socialhome = {}
const xmpp = {}
const itemBtn = (item, hostId, hostKey, hostDefault, hostPost) => {
let itemHost = browser.storage.sync.get(`${hostKey}`)
itemHost.then((res) => {
document.querySelector(`#${hostId}`)
.href = [res[hostKey] || hostDefault] + hostPost
})
item.href = itemHost
item.id = hostId
socialBtns.push(item)
}
itemBtn(diaspora, 'url-diaspora', 'diasporaHost', host.diasporaDefault, diasporaPost)
itemBtn(friendica, 'url-friendica', 'friendicaHost', host.friendicaDefault, friendicaPost)
itemBtn(gnusocial, 'url-gnusocial', 'gnusocialHost', host.gnusocialDefault, gnusocialPost)
itemBtn(hubzilla, 'url-hubzilla', 'hubzillaHost', host.hubzillaDefault, hubzillaPost)
itemBtn(lemmy, 'url-lemmy', 'lemmyHost', host.lemmyDefault, lemmyPost)
itemBtn(mastodon, 'url-mastodon', 'mastodonHost', host.mastodonDefault, mastodonPost)
itemBtn(pleroma, 'url-pleroma', 'pleromaHost', host.pleromaDefault, pleromaPost)
itemBtn(socialhome, 'url-socialhome', 'socialhomeHost', host.socialhomeDefault, socialhomePost)
itemBtn(xmpp, 'url-xmpp', 'xmppHost', host.xmppDefault, xmppPost)
socialBtns.forEach(urlAssigner)
}
/*
* hide/show buttons
*/
const enableItem = (hostKey, hostId) => {
const item = chrome.storage.sync.get(`${hostKey}`, value => {
if (value[hostKey]) {
document.getElementById(`${hostId}`).removeAttribute('hidden')
}
})
}
enableItem('diasporaCheck', 'url-diaspora')
enableItem('friendicaCheck', 'url-friendica')
enableItem('gnusocialCheck', 'url-gnusocial')
enableItem('hubzillaCheck', 'url-hubzilla')
enableItem('lemmyCheck', 'url-lemmy')
enableItem('mastodonCheck', 'url-mastodon')
enableItem('pleromaCheck', 'url-pleroma')
enableItem('socialhomeCheck', 'url-socialhome')
enableItem('xmppCheck', 'url-xmpp')
/*
* Open options page
*/
function openOptions() {
browser.runtime.openOptionsPage()
}
const el = document.getElementById('options')
el.addEventListener('click', function() {openOptions()}, false)
}

View File

@ -1,89 +0,0 @@
import { host } from './background.js'
const saveOptions = (e) => {
saveHost('diaspora-host', 'diasporaHost')
saveHost('friendica-host', 'friendicaHost')
saveHost('gnusocial-host', 'gnusocialHost')
saveHost('hubzilla-host', 'hubzillaHost')
saveHost('lemmy-host', 'lemmyHost')
saveHost('mastodon-host', 'mastodonHost')
saveHost('pleroma-host', 'pleromaHost')
saveHost('socialhome-host', 'socialhomeHost')
saveHost('xmpp-host', 'xmppHost')
saveCheckbox('diaspora-check', 'diasporaCheck')
saveCheckbox('friendica-check', 'friendicaCheck')
saveCheckbox('gnusocial-check', 'gnusocialCheck')
saveCheckbox('hubzilla-check', 'hubzillaCheck')
saveCheckbox('lemmy-check', 'lemmyCheck')
saveCheckbox('mastodon-check', 'mastodonCheck')
saveCheckbox('pleroma-check', 'pleromaCheck')
saveCheckbox('socialhome-check', 'socialhomeCheck')
saveCheckbox('xmpp-check', 'xmppCheck')
e.preventDefault()
}
const saveHost = (hostId, hostKey) => {
browser.storage.sync.set({
[hostKey] : document.querySelector(`#${hostId}`).value
})
}
const saveCheckbox = (checkId, checkKey) => {
let checkbox = document.getElementById(`${checkId}`)
if (checkbox.checked) {
browser.storage.sync.set({
[checkKey] : document.querySelector(`#${checkId}`).checked = true
})
} else {
browser.storage.sync.set({
[checkKey] : document.querySelector(`#${checkId}`).checked = false
})
}
}
const restoreOptions = () => {
restoreHost('diasporaHost', 'diaspora-host', host.diasporaDefault)
restoreHost('friendicaHost', 'friendica-host', host.friendicaDefault)
restoreHost('gnusocialHost', 'gnusocial-host', host.gnusocialDefault)
restoreHost('hubzillaHost', 'hubzilla-host', host.hubzillaDefault)
restoreHost('lemmyHost', 'lemmy-host', host.lemmyDefault)
restoreHost('mastodonHost', 'mastodon-host', host.mastodonDefault)
restoreHost('pleromaHost', 'pleroma-host', host.pleromaDefault)
restoreHost('socialhomeHost', 'socialhome-host', host.socialhomeDefault)
restoreHost('xmppHost', 'xmpp-host', host.xmppDefault)
restoreCheckbox('diasporaCheck', 'diaspora-check')
restoreCheckbox('friendicaCheck', 'friendica-check')
restoreCheckbox('gnusocialCheck', 'gnusocial-check')
restoreCheckbox('hubzillaCheck', 'hubzilla-check')
restoreCheckbox('lemmyCheck', 'lemmy-check')
restoreCheckbox('mastodonCheck', 'mastodon-check')
restoreCheckbox('pleromaCheck', 'pleroma-check')
restoreCheckbox('socialhomeCheck', 'socialhome-check')
restoreCheckbox('xmppCheck', 'xmpp-check')
}
const restoreHost = (hostKey, hostId, hostDefault) => {
let gettingItem = browser.storage.sync.get(`${hostKey}`)
gettingItem.then((res) => {
document.querySelector(`#${hostId}`).value = res[hostKey] || hostDefault
})
}
const restoreCheckbox = (checkKey, checkId) => {
const checkbox = chrome.storage.sync.get(`${checkKey}`, value => {
if (value[checkKey]) {
document.getElementById(`${checkId}`).checked = true
}
})
}
document.addEventListener('DOMContentLoaded', restoreOptions, saveCheckbox)
document.querySelector("form").addEventListener("submit", saveOptions)

7
src/lib/app.ts Normal file
View File

@ -0,0 +1,7 @@
import { renderItems } from './dom';
export class App {
public render() {
renderItems();
}
}

40
src/lib/dom.ts Normal file
View File

@ -0,0 +1,40 @@
import { getCurrentTabInfo, enableItem, generateArray } from './utils';
import * as instance from './instances';
const items = generateArray(instance);
export function renderItems() {
const containerItems = document.getElementById('root');
containerItems.innerHTML = '';
items.forEach((value) => {
const name = value.name;
const html = `
<a class="button btn-${name.toLowerCase()}" id="url-${name.toLowerCase()}" hidden>
<span><i class="fa fa-${value.icon} icon"></i></span>
<span>${name}</span>
</a>`;
containerItems.insertAdjacentHTML('afterbegin', html);
getCurrentTabInfo();
});
items.map((value) => enableItem(value));
// Options button
const htmlOptions = `
<a class="button btn-options" id="options">
<span><i class="fa fa-cog icon"></i></span>
<span>Options</span>
</a>`;
containerItems.insertAdjacentHTML('beforeend', htmlOptions);
// Open options page
const optionsBtn = document.getElementById('options');
function openOptions() {
browser.runtime.openOptionsPage();
}
optionsBtn.addEventListener('click', openOptions);
}

80
src/lib/instances.ts Normal file
View File

@ -0,0 +1,80 @@
/*
* ---------------------- The Fediverse -----------------------
* Properties:
* - name -
* + The name of the social network / service (instance).
* NO whitespaces!
* - post -
* + The HTTP POST request method. Important to include the
* Title and Url.
* - icon -
* + The icon to be displayed in the popup (main) window.
* Taken from Fork Awesome.
* - host -
* + The default host.
*
*/
import { Instance } from './interface';
export const diaspora: Instance = {
name: 'Diaspora',
post: '/bookmarklet?url=Url&title=Title',
icon: 'diaspora',
host: 'https://diasp.org',
};
export const friendica: Instance = {
name: 'Friendica',
post: '/bookmarklet?url=Url&title=Title',
icon: 'friendica',
host: 'https://libranet.de',
};
export const gnusocial: Instance = {
name: 'GNUsocial',
post: '/?action=newnotice&status_textarea=Title Url',
icon: 'gnu-social',
host: 'https://gnusocial.net',
};
export const hubzilla: Instance = {
name: 'Hubzilla',
post: '/rpost?body=Title &url=Url',
icon: 'hubzilla',
host: 'https://demo.hubzilla.org',
};
export const lemmy: Instance = {
name: 'Lemmy',
post: '/create_post?url=Url&title=Title',
icon: 'comments',
host: 'https://lemmy.glasgow.social',
};
export const mastodon: Instance = {
name: 'Mastodon',
post: '/share?text=Title&url=Url',
icon: 'mastodon',
host: 'https://mastodon.social',
};
export const pleroma: Instance = {
name: 'Pleroma',
post: '/share?message=Title Url',
icon: 'pleroma',
host: 'https://blob.cat',
};
export const socialhome: Instance = {
name: 'Socialhome',
post: '/bookmarklet?url=Url&title=Title',
icon: 'social-home',
host: 'https://socialhome.network',
};
export const xmpp: Instance = {
name: 'XMPP',
post: '?message=Title Url',
icon: 'xmpp',
host: 'https://suchat.org',
};

19
src/lib/interface.ts Normal file
View File

@ -0,0 +1,19 @@
export interface Button {
id?: string;
href?: string;
}
export interface Query {
active?: boolean;
currentWindow?: boolean;
url?: string;
title?: string;
}
export interface Instance {
name: string;
post: string;
icon: string;
host: string;
button?: Button;
}

30
src/lib/options.ts Normal file
View File

@ -0,0 +1,30 @@
import { generateArray, gettingItems, saveItems } from './utils';
import * as instance from './instances';
const items = generateArray(instance);
const containerItems = document.getElementById('root');
containerItems.innerHTML = '';
items.forEach((value) => {
const name = value.name;
const html = `
<div class="flex">
<span class="span-custom">${name}:</span>
<input id="${name.toLowerCase()}-host" class="text-custom" type="text" >
<div class="bg-gray-500" >
<input class="checkbox-custom" type="checkbox" id="${name.toLowerCase()}-check">
</div>
</div>`;
containerItems.insertAdjacentHTML('beforeend', html);
});
function saveOptions() {
items.forEach(saveItems);
}
function recoverOptions() {
items.forEach(gettingItems);
}
document.addEventListener('DOMContentLoaded', recoverOptions);
document.querySelector('form').addEventListener('submit', saveOptions);

102
src/lib/utils.ts Normal file
View File

@ -0,0 +1,102 @@
import { Query, Instance } from './interface';
import * as instance from './instances';
// ---------- Commons
export function generateArray(obj: Object): Instance[] {
const item = [];
Object.keys(obj).map((index) => item.push(obj[index]));
return item;
}
// ----------------------- Main section -----------------------
export function getCurrentTabInfo() {
const queryInfo: Query = {
active: true,
currentWindow: true,
};
chrome.tabs.query(queryInfo, (tabs: Query[] = []) => {
if (tabs.length === 0) return;
const tab = tabs[0] || {};
makeBtns(tab);
});
}
function urlAssigner(instance: Instance) {
const { id, href } = instance.button;
const element = <HTMLAnchorElement>document.getElementById(id);
element.href = href;
}
function makeBtns(tabQuery: Query) {
const socialBtns = generateArray(instance);
function itemBtn(instance: Instance) {
const { name, host, post } = instance;
const element = <HTMLAnchorElement>document.getElementById(`url-${name.toLowerCase()}`);
const itemHost: any = browser.storage.sync.get(`${name.toLowerCase()}Host`); // fix this
// TODO improve regex
const str = post.replace(/Title/, tabQuery.title).replace(/Url/, tabQuery.url);
itemHost.then((res: string) => {
element.href = [res[`${name.toLowerCase()}Host`] || host] + str;
});
instance.button = { id: name, href: itemHost };
}
socialBtns.map((item) => itemBtn(item));
socialBtns.forEach(urlAssigner);
}
// Hide-Show items
export function enableItem(instance: Instance) {
const name = instance.name.toLowerCase();
chrome.storage.sync.get(`${name}Check`, (value) => {
if (value[`${name}Check`]) {
document.getElementById(`url-${name}`).removeAttribute('hidden');
}
});
}
// ----------------------- Options section -----------------------
export function saveItems(instance: Instance) {
const name = instance.name.toLowerCase();
const checkbox = <HTMLInputElement>document.getElementById(`${name}-check`);
const container = <HTMLInputElement>document.getElementById(`${name}-host`);
browser.storage.sync.set({
[`${name}Host`]: container.value,
});
if (checkbox.checked) {
browser.storage.sync.set({
[`${name}Check`]: (checkbox.checked = true),
});
} else {
browser.storage.sync.set({
[`${name}Check`]: (checkbox.checked = false),
});
}
}
export function gettingItems(instance: Instance) {
const name = instance.name.toLowerCase();
const containerCheck = <HTMLInputElement>document.getElementById(`${name}-check`);
const containerHost: any = document.getElementById(`${name}-host`); // fix this
const gettingItem = browser.storage.sync.get(`${name}Host`);
gettingItem.then((res) => {
containerHost.value = res[`${name}Host`] || instance.host;
});
chrome.storage.sync.get(`${name}Check`, (value) => {
if (value[`${name}Check`]) {
containerCheck.checked = true;
}
});
}

3
src/popup.ts Normal file
View File

@ -0,0 +1,3 @@
import { App } from './lib/app';
new App().render();

25
src/test/app.spec.ts Normal file
View File

@ -0,0 +1,25 @@
// import sinon from 'sinon';
// import { App } from '../lib/app';
// import * as Dom from '../lib/dom';
// describe('testing App', () => {
// let sandboxes;
// let renderDateTime;
// beforeEach(() => {
// sandboxes = sinon.createSandbox();
// renderDateTime = sandboxes.stub(Dom, 'renderDateTime');
// });
// afterEach(() => {
// sandboxes.restore();
// });
// describe('testing App', () => {
// it('should return Thu Nov 19 23:00', () => {
// const app = new App();
// app.render();
// expect(renderDateTime.called).toBeTruthy();
// });
// });
// });

101
src/test/utils.spec.ts Normal file
View File

@ -0,0 +1,101 @@
// import sinon from 'sinon';
// import { getDisplayDateTime, getPeriod, getPalette } from '../lib/utils';
// describe('testing utils', () => {
// let sandboxes;
// beforeEach(() => {
// sandboxes = sinon.createSandbox();
// sandboxes.useFakeTimers({
// now: new Date(2020, 10, 19, 23, 0),
// });
// });
// afterEach(() => {
// sandboxes.restore();
// });
// describe('testing getDisplayDateTime', () => {
// it('should return Thu Nov 19 23:00', () => {
// const actual = getDisplayDateTime();
// const expected = { date: 'Thu Nov 19', time: '23:00', period: 'night' };
// expect(actual).toEqual(expected);
// });
// it('should return Thu Nov 19 01:00', () => {
// sinon.useFakeTimers({
// now: new Date(2020, 10, 19, 1, 0),
// });
// const actual = getDisplayDateTime();
// const expected = { date: 'Thu Nov 19', time: '01:00', period: 'night' };
// expect(actual).toEqual(expected);
// });
// it('should return Thu Nov 19 23:23', () => {
// sinon.useFakeTimers({
// now: new Date(2020, 10, 19, 23, 23),
// });
// const actual = getDisplayDateTime();
// const expected = { date: 'Thu Nov 19', time: '23:23', period: 'night' };
// expect(actual).toEqual(expected);
// });
// });
// describe('testing getPeriod', () => {
// it('should return morning - 05:00 AM', () => {
// const actual = getPeriod(new Date(2020, 10, 19, 5, 0));
// const expected = 'morning';
// expect(actual).toEqual(expected);
// });
// it('should return morning - 11:59 AM', () => {
// const actual = getPeriod(new Date(2020, 10, 19, 11, 59));
// const expected = 'morning';
// expect(actual).toEqual(expected);
// });
// it('should return afternoon - 12:00 PM', () => {
// const actual = getPeriod(new Date(2020, 10, 19, 12, 0));
// const expected = 'afternoon';
// expect(actual).toEqual(expected);
// });
// it('should return afternoon - 04:59 PM', () => {
// const actual = getPeriod(new Date(2020, 10, 19, 16, 59));
// const expected = 'afternoon';
// expect(actual).toEqual(expected);
// });
// it('should return night - 05:00 PM', () => {
// const actual = getPeriod(new Date(2020, 10, 19, 17, 0));
// const expected = 'night';
// expect(actual).toEqual(expected);
// });
// it('should return night - 04:59 AM', () => {
// const actual = getPeriod(new Date(2020, 10, 19, 4, 59));
// const expected = 'night';
// expect(actual).toEqual(expected);
// });
// });
// describe('testing getPalette', () => {
// it('should return morning color code - #282e54', () => {
// const actual = getPalette('morning');
// const expected = '#282e54';
// expect(actual).toEqual(expected);
// });
// it('should return afternoon color code - #000000', () => {
// const actual = getPalette('afternoon');
// const expected = '#000000';
// expect(actual).toEqual(expected);
// });
// it('should return morning color code - #ffdd91', () => {
// const actual = getPalette('night');
// const expected = '#ffdd91';
// expect(actual).toEqual(expected);
// });
// });
// });

View File

@ -1,13 +1,14 @@
// tailwind.config.js // tailwind.config.js
module.exports = { module.exports = {
purge: ['./public/*.html'],
purge: [ darkMode: false, // or 'media' or 'class'
'./src/**/*.html', theme: {
], extend: {},
darkMode: false, // or 'media' or 'class' },
theme: { variants: {
extend: {}, extend: {
backgroundColor: ['active'],
}, },
variants: {}, },
plugins: [], plugins: [],
} };

21
tsconfig.json Normal file
View File

@ -0,0 +1,21 @@
{
"compilerOptions": {
"module": "ES6",
"target": "es6",
"moduleResolution": "node",
"esModuleInterop": true,
"noImplicitAny": false,
"sourceMap": false,
"rootDir": "src",
"outDir": "dist/js",
"noEmitOnError": true,
"typeRoots": [
"node_modules/@types",
"node_modules/web-ext-types"
],
"types": [
"jest",
"node"
]
}
}

View File

@ -1,7 +0,0 @@
module.exports = {
ignoreFiles: [
"src/img/screenshot-*.png",
"src/img/ice-cream.png",
"src/img/badge-amo.png"
],
};

47
webpack/webpack.common.js Normal file
View File

@ -0,0 +1,47 @@
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
const browser = process.env.BROWSER;
const BUILD_DIR_NAME = 'dist';
const SRC_DIR_NAME = 'src';
module.exports = {
entry: {
popup: path.join(__dirname, `../${SRC_DIR_NAME}/popup.ts`),
options: path.join(__dirname, `../${SRC_DIR_NAME}/lib/options.ts`),
},
output: {
path: path.join(__dirname, `../${BUILD_DIR_NAME}`),
filename: '[name].js',
},
optimization: {
splitChunks: {
name: 'vendor',
chunks: 'initial',
},
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
},
plugins: [
new CopyPlugin({
patterns: [
{ from: './images', to: `../${BUILD_DIR_NAME}/images`, context: 'public' },
{ from: './fonts', to: `../${BUILD_DIR_NAME}/fonts`, context: 'public' },
{ from: './css', to: `../${BUILD_DIR_NAME}/css`, context: 'public' },
{ from: './popup.html', to: `../${BUILD_DIR_NAME}/popup.html`, context: 'public' },
{ from: './options.html', to: `../${BUILD_DIR_NAME}/options.html`, context: 'public' },
{ from: `${browser}_manifest.json`, to: `../${BUILD_DIR_NAME}/manifest.json`, context: 'public' },
],
}),
],
};

7
webpack/webpack.dev.js Normal file
View File

@ -0,0 +1,7 @@
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
devtool: 'inline-source-map',
mode: 'development',
});

24
webpack/webpack.prod.js Normal file
View File

@ -0,0 +1,24 @@
const { merge } = require('webpack-merge');
const TerserPlugin = require('terser-webpack-plugin');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'production',
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
/*
* Google requires some conditions:
* - Removal of whitespace, newlines, code comments, and block delimiters
* - Shortening of variable and function names
* - Collapsing the number of JavaScript files
*/
terserOptions: {
compress: true, // To rename variables & function names
mangle: true, // Note `mangle.properties` is `false` by default.
},
}),
],
},
});