Firefox WebExtension (Desktop and Mobile) that lets you share the current tab to Margit.at, frontpage.fyi, etc. with minimal effort.

Added icons, metadata and GH action for distribution

+135 -4
+55
.github/workflows/package-extension.yml
··· 1 + name: package-extension 2 + 3 + on: 4 + workflow_dispatch: 5 + push: 6 + branches: 7 + - main 8 + paths: 9 + - "extension/**" 10 + - ".github/workflows/package-extension.yml" 11 + 12 + jobs: 13 + build: 14 + name: Build unsigned bundle 15 + runs-on: ubuntu-latest 16 + 17 + steps: 18 + - name: Checkout repository 19 + uses: actions/checkout@v4 20 + 21 + - name: Setup Node.js 22 + uses: actions/setup-node@v4 23 + with: 24 + node-version: "20" 25 + 26 + - name: Install web-ext 27 + run: npm install --global web-ext 28 + 29 + - name: Build unsigned archive 30 + run: web-ext build --source-dir ./extension --artifacts-dir ./web-ext-artifacts 31 + 32 + - name: Upload unsigned artifact 33 + uses: actions/upload-artifact@v4 34 + with: 35 + name: frontpage-extension-unsigned 36 + path: web-ext-artifacts/** 37 + 38 + - name: Sign using AMO (optional) 39 + if: ${{ secrets.AMO_JWT_ISSUER && secrets.AMO_JWT_SECRET }} 40 + env: 41 + WEB_EXT_API_KEY: ${{ secrets.AMO_JWT_ISSUER }} 42 + WEB_EXT_API_SECRET: ${{ secrets.AMO_JWT_SECRET }} 43 + WEB_EXT_ID: frontpage-submitter@example.com 44 + run: | 45 + web-ext sign \ 46 + --channel=unlisted \ 47 + --source-dir ./extension \ 48 + --artifacts-dir ./web-ext-artifacts 49 + 50 + - name: Upload signed artifact (optional) 51 + if: ${{ secrets.AMO_JWT_ISSUER && secrets.AMO_JWT_SECRET }} 52 + uses: actions/upload-artifact@v4 53 + with: 54 + name: frontpage-extension-signed 55 + path: web-ext-artifacts/*.xpi
+21 -1
README.md
··· 60 60 61 61 - Inspect background/service-worker logs from `about:debugging` → **Inspect**. 62 62 - The UI scripts (`popup.js` and `options.js`) log to the DevTools console attached to their respective documents. 63 - - When packaging for distribution, zip the contents of the `extension/` directory. 63 + - When packaging for distribution, zip the contents of the `extension/` directory (see workflow below). 64 + 65 + ### Ship it on AMO 66 + 67 + - Provide the bundled icons from `extension/icons/` (16, 32, 48 and 128 px SVGs). 68 + - Zip the `extension/` directory (e.g. `cd extension && zip -r ../frontpage-submitter.zip .`). 69 + - Upload the archive to <https://addons.mozilla.org/developers/> and fill in the listing copy/screenshots. 70 + - AMO reviewers expect a concise summary; you can adapt the “Features” bullets above. 71 + 72 + ### Self-distribution pipeline 73 + 74 + This repository includes `.github/workflows/package-extension.yml` which builds (and optionally signs) the add-on using [`web-ext`](https://extensionworkshop.com/documentation/develop/web-ext-command-reference/). 75 + 76 + 1. Configure `AMO_JWT_ISSUER` and `AMO_JWT_SECRET` repository secrets with your AMO API credentials if you want automatic signing. 77 + Without the secrets, the workflow still produces an unsigned ZIP you can download. 78 + 2. Trigger the workflow manually (`Actions` → **package-extension** → **Run workflow**) or push changes to `main`. 79 + 3. Download the artifacts: 80 + - `frontpage-extension-unsigned` contains the ZIP that `web-ext build` generates. 81 + - `frontpage-extension-signed` (only when secrets are present) contains the signed `.xpi` from AMO for self-hosting. 82 + 83 + These artifacts can be hosted directly for self-distribution as described in the [Mozilla documentation](https://extensionworkshop.com/documentation/publish/self-distribution/).
+1
extension/background.js
··· 1 + const browser = globalThis.browser ?? globalThis.chrome; 1 2 const STORAGE_KEY = "frontpageAuth"; 2 3 const FRONTPAGE_COLLECTION = "fyi.unravel.frontpage.post"; 3 4 const RECORD_TYPE = "fyi.unravel.frontpage.post";
+10
extension/icons/icon-128.svg
··· 1 + <svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128"> 2 + <defs> 3 + <linearGradient id="fp-gradient-128" x1="0%" y1="0%" x2="100%" y2="100%"> 4 + <stop offset="0%" stop-color="#2563eb"/> 5 + <stop offset="100%" stop-color="#1d4ed8"/> 6 + </linearGradient> 7 + </defs> 8 + <rect width="128" height="128" rx="28" fill="url(#fp-gradient-128)"/> 9 + <path fill="#ffffff" d="M38 36c-4.4 0-8 3.6-8 8v40c0 4.4 3.6 8 8 8h24c4.4 0 8-3.6 8-8s-3.6-8-8-8H46V44h42c4.4 0 8-3.6 8-8s-3.6-8-8-8H38z"/> 10 + </svg>
+10
extension/icons/icon-16.svg
··· 1 + <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 128 128"> 2 + <defs> 3 + <linearGradient id="fp-gradient" x1="0%" y1="0%" x2="100%" y2="100%"> 4 + <stop offset="0%" stop-color="#2563eb"/> 5 + <stop offset="100%" stop-color="#1d4ed8"/> 6 + </linearGradient> 7 + </defs> 8 + <rect width="128" height="128" rx="28" fill="url(#fp-gradient)"/> 9 + <path fill="#ffffff" d="M38 36c-4.4 0-8 3.6-8 8v40c0 4.4 3.6 8 8 8h24c4.4 0 8-3.6 8-8s-3.6-8-8-8H46V44h42c4.4 0 8-3.6 8-8s-3.6-8-8-8H38z"/> 10 + </svg>
+10
extension/icons/icon-32.svg
··· 1 + <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 128 128"> 2 + <defs> 3 + <linearGradient id="fp-gradient-32" x1="0%" y1="0%" x2="100%" y2="100%"> 4 + <stop offset="0%" stop-color="#2563eb"/> 5 + <stop offset="100%" stop-color="#1d4ed8"/> 6 + </linearGradient> 7 + </defs> 8 + <rect width="128" height="128" rx="28" fill="url(#fp-gradient-32)"/> 9 + <path fill="#ffffff" d="M38 36c-4.4 0-8 3.6-8 8v40c0 4.4 3.6 8 8 8h24c4.4 0 8-3.6 8-8s-3.6-8-8-8H46V44h42c4.4 0 8-3.6 8-8s-3.6-8-8-8H38z"/> 10 + </svg>
+10
extension/icons/icon-48.svg
··· 1 + <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 128 128"> 2 + <defs> 3 + <linearGradient id="fp-gradient-48" x1="0%" y1="0%" x2="100%" y2="100%"> 4 + <stop offset="0%" stop-color="#2563eb"/> 5 + <stop offset="100%" stop-color="#1d4ed8"/> 6 + </linearGradient> 7 + </defs> 8 + <rect width="128" height="128" rx="28" fill="url(#fp-gradient-48)"/> 9 + <path fill="#ffffff" d="M38 36c-4.4 0-8 3.6-8 8v40c0 4.4 3.6 8 8 8h24c4.4 0 8-3.6 8-8s-3.6-8-8-8H46V44h42c4.4 0 8-3.6 8-8s-3.6-8-8-8H38z"/> 10 + </svg>
+18 -3
extension/manifest.json
··· 3 3 "name": "Frontpage Submitter", 4 4 "description": "Quickly share the current tab to frontpage.fyi via ATProto.", 5 5 "version": "0.1.0", 6 + "author": "Frontpage Submitter Contributors", 7 + "homepage_url": "https://frontpage.fyi", 8 + "icons": { 9 + "16": "icons/icon-16.svg", 10 + "32": "icons/icon-32.svg", 11 + "48": "icons/icon-48.svg", 12 + "128": "icons/icon-128.svg" 13 + }, 6 14 "permissions": [ 7 15 "storage", 8 16 "tabs", ··· 12 20 "https://*/*" 13 21 ], 14 22 "action": { 15 - "default_popup": "popup.html" 23 + "default_popup": "popup.html", 24 + "default_icon": { 25 + "16": "icons/icon-16.svg", 26 + "32": "icons/icon-32.svg" 27 + }, 28 + "default_title": "Post to Frontpage" 16 29 }, 17 30 "options_ui": { 18 31 "page": "options.html", 19 - "open_in_tab": true 32 + "open_in_tab": true, 33 + "browser_style": true 20 34 }, 21 35 "background": { 22 36 "scripts": [ ··· 26 40 }, 27 41 "browser_specific_settings": { 28 42 "gecko": { 29 - "id": "frontpage-submitter@example.com" 43 + "id": "frontpage-submitter@example.com", 44 + "strict_min_version": "109.0" 30 45 } 31 46 } 32 47 }