Initial commit: AutoTrader Marker Firefox extension
Mark AutoTrader listings as 'not wanted' on both search results and detail pages. Includes the unlisted signing / auto-update pipeline (web-ext + dist/updates.json polled by Firefox). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
# AutoTrader Marker
|
||||
|
||||
Firefox extension to mark AutoTrader (autotrader.co.uk) listings as "not wanted"
|
||||
so the ones you haven't reviewed yet stand out.
|
||||
|
||||
## What it does
|
||||
|
||||
- **Search results**: adds a `✗ Not wanted` button to the top-left of every
|
||||
listing card. Click and the card fades to ~30 % opacity with a red dashed
|
||||
outline.
|
||||
- **Detail page** (`/car-details/{id}`): adds a floating `✗ Not wanted` button
|
||||
in the bottom-right corner. If you land on a page you've already dismissed,
|
||||
a red banner appears at the top with an **Undo** action.
|
||||
- Browser-action popup shows the count, lets you toggle **Hide dismissed
|
||||
listings** (fully collapse them on search results instead of fade),
|
||||
export/import the list as JSON, or clear everything.
|
||||
- State persists in `browser.storage.local` and syncs across open tabs via
|
||||
`storage.onChanged`.
|
||||
|
||||
## Temporary install (for development)
|
||||
|
||||
1. `about:debugging#/runtime/this-firefox` → **Load Temporary Add-on…**
|
||||
2. Select `manifest.json`. Changes require clicking **Reload** on that page.
|
||||
3. Temporary add-ons vanish on Firefox restart.
|
||||
|
||||
## Persistent install via unlisted signing (auto-updates)
|
||||
|
||||
Once signed and installed this way, Firefox auto-updates installed copies by
|
||||
polling `dist/updates.json` in the Gitea repo roughly once a day.
|
||||
|
||||
### One-time setup
|
||||
|
||||
1. **Create the Gitea repo** at <https://git.nocker.cloud/tony/autotrader-marker>
|
||||
(must be pullable over HTTPS without auth so Firefox can fetch
|
||||
`dist/updates.json` and the XPIs).
|
||||
2. **Initial commit and push**:
|
||||
```bash
|
||||
cd autotrader-marker
|
||||
git init && git branch -m main
|
||||
git remote add origin https://git.nocker.cloud/tony/autotrader-marker.git
|
||||
npm install
|
||||
git add .
|
||||
git commit -m "Initial commit"
|
||||
git push -u origin main
|
||||
```
|
||||
3. **Get AMO JWT credentials** at
|
||||
<https://addons.mozilla.org/en-US/developers/addon/api/key/>. Save them
|
||||
somewhere safe (macOS Keychain or Infisical `/autotrader-marker`).
|
||||
4. **Export** the creds before running any release:
|
||||
```bash
|
||||
export WEB_EXT_API_KEY='user:12345:67'
|
||||
export WEB_EXT_API_SECRET='abcdef0123456789...'
|
||||
```
|
||||
5. **Cut the first signed release** (from the repo root, on your Mac):
|
||||
```bash
|
||||
bin/release.sh 0.1.0 # or: bin/release.sh patch
|
||||
git add manifest.json package.json dist/
|
||||
git commit -m "Release v0.1.0"
|
||||
git push origin main
|
||||
```
|
||||
6. **Install the signed XPI once** on your host Firefox:
|
||||
- Open `about:addons` → ⚙ (gear) → **Install Add-on From File…**
|
||||
- Select `dist/autotrader-marker-0.1.0.xpi`
|
||||
- Firefox keeps it installed and checks for updates automatically.
|
||||
|
||||
### Subsequent releases
|
||||
|
||||
```bash
|
||||
# Edit code, then:
|
||||
bin/release.sh patch # 0.1.0 → 0.1.1
|
||||
# (or 'minor' / 'major' / an explicit version like '1.2.3')
|
||||
|
||||
git add manifest.json package.json dist/
|
||||
git commit -m "Release v$(node -p "require('./manifest.json').version")"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
Firefox polls for updates on its own schedule (~daily). To trigger immediately:
|
||||
`about:addons` → ⚙ → **Check for Updates**.
|
||||
|
||||
### What `bin/release.sh` does
|
||||
|
||||
1. Bumps the version in `manifest.json` and `package.json`.
|
||||
2. Runs `web-ext sign --channel=unlisted` against AMO. Mozilla validates and
|
||||
signs the XPI (usually seconds for an unlisted submission).
|
||||
3. Copies the signed XPI to `dist/autotrader-marker-<version>.xpi`.
|
||||
4. Appends the new version to `dist/updates.json` so Firefox can discover it.
|
||||
5. Prints next-step git commands — it does **not** push automatically.
|
||||
|
||||
If `web-ext sign` prints a lint ERROR about `MANIFEST_UPDATE_URL`, that's
|
||||
expected and doesn't block signing: the rule only applies to AMO-listed
|
||||
add-ons, and `--channel=unlisted` proceeds past it.
|
||||
|
||||
## Package a static zip (for `about:debugging` without signing)
|
||||
|
||||
```bash
|
||||
python3 -c "
|
||||
import zipfile
|
||||
with zipfile.ZipFile('../autotrader-marker.zip', 'w', zipfile.ZIP_DEFLATED) as z:
|
||||
for f in ['manifest.json','content.js','content.css','popup.html','popup.css','popup.js','icon.svg']:
|
||||
z.write(f)
|
||||
"
|
||||
```
|
||||
|
||||
## DOM contract (verified 2026-04)
|
||||
|
||||
The content script relies on these AutoTrader selectors. If they change, update
|
||||
`content.js`:
|
||||
|
||||
| What | Selector |
|
||||
|------|----------|
|
||||
| Listing card | `li[data-testid^="id-"]` (id is `id-{listingId}`) |
|
||||
| Search result title | `[data-testid="search-listing-title"]` |
|
||||
| Detail page id | URL path `/car-details/{digits}` |
|
||||
| Detail page title | `h1` (falls back to `document.title`) |
|
||||
|
||||
The primary id sources are the `data-testid` on the `<li>` for search results
|
||||
and the URL path for detail pages — no href parsing needed in the happy path.
|
||||
The detail-page UI uses a fixed-position FAB, so it doesn't depend on the
|
||||
page's layout at all.
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `manifest.json` | MV3 manifest, Firefox-specific settings, `update_url` → Gitea |
|
||||
| `content.js` | Injects buttons, manages dismissal state, MutationObserver for infinite scroll, SPA-nav aware |
|
||||
| `content.css` | Button styling + dismissed-card fade/hide rules |
|
||||
| `popup.html` / `popup.css` / `popup.js` | Toolbar popup UI |
|
||||
| `icon.svg` | Single SVG used for toolbar + addon listing |
|
||||
| `bin/release.sh` | Version bump + sign + updates.json refresh |
|
||||
| `dist/updates.json` | Served to Firefox for update polling |
|
||||
| `dist/*.xpi` | Signed extension bundles referenced by `updates.json` |
|
||||
Reference in New Issue
Block a user