An open API service indexing awesome lists of open source software.

https://github.com/mikaleb/hidepuretech

🚘 Hide car ads with Puretech engine
https://github.com/mikaleb/hidepuretech

car chrome extension firefox hide-puretech opera productivity puretech react

Last synced: 3 months ago
JSON representation

🚘 Hide car ads with Puretech engine

Awesome Lists containing this project

README

          

# Le Cache Misère (LCM)

GitHub Release
Chrome Web Store Users
Mozilla Add-on Users
![Static Badge](https://img.shields.io/badge/opera-awaiting-F78C40?style=flat-square&logo=opera&logoColor=red)

## Features

**Le Cache Misère (LCM)** is a browser extension that filters car listings on supported websites containing problematic engines (PureTech, BlueHDi 1.5, etc.). Two hiding modes:

- **Grey-out mode** β€” listings are dimmed, grayscaled, and struck through; still visible but clearly marked
- **Hide completely** β€” listings are fully removed and replaced by a slim placeholder bar showing the vehicle title; clicking the bar reveals the listing in a faded "reviewed" state with a re-hide button

### Supported websites

- [LaCentrale](https://www.lacentrale.fr/)
- [AramisAuto](https://www.aramisauto.com/)
- [LeBonCoin](https://www.leboncoin.fr/)
- [AutoSphere](https://www.autosphere.fr/)

### Settings

- Toggle filtering per website (on/off)
- Toggle filtering per motor type independently (PureTech, BlueHDi 1.5, THP, etc.)
- **Hide completely** β€” remove listings entirely and show a placeholder (default: on)
- **Show placeholder icon** β€” display the extension icon inside the placeholder bar

---

## Architecture

This is a **Manifest V3 browser extension** built with Vite + `@crxjs/vite-plugin`, React 18, MUI v6, and SCSS.

## Development

### Prerequisites

- Node.js 18+
- npm

### Setup

```bash
npm install
```

### Dev commands

| Command | Description |
| ------------------ | ---------------------------------------------------------------- |
| `npm run dev` | Chrome dev mode β€” Vite with HMR on port 5173 |
| `npm run start:ff` | Firefox dev mode β€” watch build + auto-launch Firefox with reload |
| `npm run watch` | Watch build β†’ updates `dist/` on every save (no browser launch) |
| `npm run build` | TypeScript check + Vite build β†’ `dist/` |
| `npm run lint` | ESLint (TypeScript + React rules) |
| `npm run deploy` | Build + zip β†’ `le-cache-misere.zip` |
| `npm run release` | Bump version, build, zip, push GitHub release |

### Contexts

| Context | Entry point | Purpose |
| ------------------ | -------------------------- | ---------------------------------------------------------------------------------------- |
| **Popup** | `src/main.tsx` β†’ `App.tsx` | Settings UI β€” reads/writes `chrome.storage.sync`, sends messages to content scripts |
| **Content script** | `src/content.tsx` | Runs on supported sites β€” applies/removes `.lcm-disabled` CSS class on matched listings |

The popup communicates with live tabs via `browser.tabs.sendMessage`. The content script also reads `browser.storage.sync` directly on page load for its initial state.

### Storage schema (`chrome.storage.sync`)

```ts
{
websites: {
title: string;
url: string;
active: boolean;
}
[];
motors: {
title: string;
active: boolean;
pattern: string;
}
[];
hideCompletely: boolean; // default: true
showPlaceholderIcon: boolean; // default: false
}
```

All keys are initialised on first load from `src/store/initialState.ts` if missing. `pattern` is a case-insensitive regex string compiled at runtime.

Default motors:

- `PureTech` β€” pattern: `puretech|pure[- ]tech`
- `BlueHDi 1.5` β€” pattern: `(?=.*1\.5)(?=.*blue[- ]?hdi)` (matches any order)

### How filtering works

1. On page load, the content script reads all storage keys and uses `initialState.ts` defaults for any that are missing
2. If the current URL matches an active website, active motor patterns are compiled into regexes
3. Vendor-specific selectors identify listing card containers; each card's full text + ARIA attributes are tested against the regexes
4. Matched cards either get `.lcm-disabled` (grey-out) or `.lcm-hide-completely` + a placeholder bar (hide mode), depending on the `hideCompletely` setting
5. Clicking a placeholder sets `data-lcm-user-show="true"` on the card β€” it reappears dimmed with a "Re-hide" button overlay
6. The popup sends partial state updates via `browser.tabs.sendMessage`; the content script also stays in sync via `browser.storage.onChanged` for cross-tab reactivity
7. A debounced `MutationObserver` re-runs filtering automatically when the page DOM changes (e.g. infinite scroll)

---

## Debugging

### Load the unpacked extension (Chrome)

1. Run `npm run build`
2. Open `chrome://extensions/`
3. Enable **Developer mode** (top right)
4. Click **Load unpacked** β†’ select the `dist/` folder
5. After code changes, run `npm run build` again and click the refresh icon on the extension card

### Load the unpacked extension (Firefox)

Run `npm run start:ff` β€” this concurrently starts the watch build and launches Firefox with the extension auto-loaded and auto-reloaded on every `dist/` change.

### Inspect the popup

- **Chrome:** `chrome://extensions/` β†’ click **Inspect views: popup.html** under the extension
- **Firefox:** `about:debugging` β†’ click **Inspect** next to the extension β†’ open popup manually

### Inspect the content script

Open DevTools on any supported site (F12) β†’ **Console** tab. The content script runs in the page context, not the extension background.

### Inspect storage

In the extension's DevTools console (popup inspector):

```js
chrome.storage.sync.get(null, console.log);
```

To reset storage to defaults:

```js
chrome.storage.sync.clear();
```

---

## License

MIT