{"id":15080118,"url":"https://github.com/mikaleb/hidepuretech","last_synced_at":"2026-04-09T19:21:33.753Z","repository":{"id":254886129,"uuid":"847852122","full_name":"Mikaleb/HidePuretech","owner":"Mikaleb","description":"🚘 Hide car ads with Puretech engine","archived":false,"fork":false,"pushed_at":"2025-12-03T23:28:31.000Z","size":3938,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-07T05:26:46.197Z","etag":null,"topics":["car","chrome","extension","firefox","hide-puretech","opera","productivity","puretech","react"],"latest_commit_sha":null,"homepage":"https://chromewebstore.google.com/detail/hide-puretech/jphlfplfmjdbbjnegonboddmfgdkdkgi?authuser=0\u0026hl=fr","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Mikaleb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["mikaleb"],"patreon":"mikaleb","open_collective":"hidepuretech","ko_fi":"mikaleb","liberapay":"Mikaleb","polar":"mikaleb","buy_me_a_coffee":"mikaleb","thanks_dev":"mikaleb"}},"created_at":"2024-08-26T17:06:46.000Z","updated_at":"2025-12-03T23:28:35.000Z","dependencies_parsed_at":"2025-04-10T20:02:57.813Z","dependency_job_id":null,"html_url":"https://github.com/Mikaleb/HidePuretech","commit_stats":{"total_commits":21,"total_committers":2,"mean_commits":10.5,"dds":0.09523809523809523,"last_synced_commit":"659aa74f4903f66142dffdb7e250c6eae7ad690f"},"previous_names":["mikaleb/hidepuretech"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/Mikaleb/HidePuretech","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mikaleb%2FHidePuretech","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mikaleb%2FHidePuretech/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mikaleb%2FHidePuretech/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mikaleb%2FHidePuretech/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Mikaleb","download_url":"https://codeload.github.com/Mikaleb/HidePuretech/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mikaleb%2FHidePuretech/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29360728,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-12T01:03:07.613Z","status":"online","status_checked_at":"2026-02-12T02:00:06.911Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["car","chrome","extension","firefox","hide-puretech","opera","productivity","puretech","react"],"created_at":"2024-09-25T05:01:39.430Z","updated_at":"2026-04-09T19:21:33.736Z","avatar_url":"https://github.com/Mikaleb.png","language":"TypeScript","funding_links":["https://github.com/sponsors/mikaleb","https://patreon.com/mikaleb","https://opencollective.com/hidepuretech","https://ko-fi.com/mikaleb","https://liberapay.com/Mikaleb","https://polar.sh/mikaleb","https://buymeacoffee.com/mikaleb","https://thanks.dev/mikaleb"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"https://github.com/Mikaleb/HidePuretech/blob/main/public/favicon-128.png?raw=true\" /\u003e\u003c/p\u003e\n\n# Le Cache Misère (LCM)\n\n\u003cdiv style=\"display: inline-flex;\n  flex-wrap: wrap;gap: 0.2em;\"\u003e\n\n\u003ca href=\"https://github.com/Mikaleb/HidePuretech\"\u003e\u003cimg alt=\"GitHub Release\" src=\"https://img.shields.io/github/v/release/Mikaleb/HidePuretech?style=flat-square\u0026logo=github\u0026logoColor=fff\"\u003e\u003c/a\u003e\n\u003ca href=\"https://chrome.google.com/webstore/detail/le-cache-misere/jphlfplfmjdbbjnegonboddmfgdkdkgi\"\u003e\u003cimg alt=\"Chrome Web Store Users\" src=\"https://img.shields.io/chrome-web-store/users/jphlfplfmjdbbjnegonboddmfgdkdkgi?style=flat-square\u0026logo=googlechrome\u0026logoColor=fff\u0026color=%234285F4\"\u003e\u003c/a\u003e\n\u003ca href=\"https://addons.mozilla.org/fr/firefox/addon/le-cache-misere/\"\u003e\u003cimg alt=\"Mozilla Add-on Users\" src=\"https://img.shields.io/amo/users/le-cache-misere?style=flat-square\u0026logo=firefox\u0026logoColor=%23FF7139\u0026color=%23FF7139\"\u003e\u003c/a\u003e\n![Static Badge](https://img.shields.io/badge/opera-awaiting-F78C40?style=flat-square\u0026logo=opera\u0026logoColor=red)\n\n\u003c/div\u003e\n\n## Features\n\n**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:\n\n- **Grey-out mode** — listings are dimmed, grayscaled, and struck through; still visible but clearly marked\n- **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\n\n### Supported websites\n\n- \u003cimg src=\"https://lacentrale.fr/static/fragment-head/media/favicon-32.cc0580c7.png\" style=\"width: 16px;\"\u003e[LaCentrale](https://www.lacentrale.fr/)\n- \u003cimg src=\"https://www.aramisauto.com/favicon.ico\" style=\"width: 16px;\"\u003e[AramisAuto](https://www.aramisauto.com/)\n- \u003cimg src=\"https://www.leboncoin.fr/_next/static/media/favicon.2b8b94c9.ico\" style=\"width: 16px;\"\u003e[LeBonCoin](https://www.leboncoin.fr/)\n- \u003cimg src=\"https://www.autosphere.fr/assets/ico/favicon.png?v=2\" style=\"width: 16px;\"\u003e[AutoSphere](https://www.autosphere.fr/)\n\n### Settings\n\n- Toggle filtering per website (on/off)\n- Toggle filtering per motor type independently (PureTech, BlueHDi 1.5, THP, etc.)\n- **Hide completely** — remove listings entirely and show a placeholder (default: on)\n- **Show placeholder icon** — display the extension icon inside the placeholder bar\n\n---\n\n## Architecture\n\nThis is a **Manifest V3 browser extension** built with Vite + `@crxjs/vite-plugin`, React 18, MUI v6, and SCSS.\n\n## Development\n\n### Prerequisites\n\n- Node.js 18+\n- npm\n\n### Setup\n\n```bash\nnpm install\n```\n\n### Dev commands\n\n| Command            | Description                                                      |\n| ------------------ | ---------------------------------------------------------------- |\n| `npm run dev`      | Chrome dev mode — Vite with HMR on port 5173                     |\n| `npm run start:ff` | Firefox dev mode — watch build + auto-launch Firefox with reload |\n| `npm run watch`    | Watch build → updates `dist/` on every save (no browser launch)  |\n| `npm run build`    | TypeScript check + Vite build → `dist/`                          |\n| `npm run lint`     | ESLint (TypeScript + React rules)                                |\n| `npm run deploy`   | Build + zip → `le-cache-misere.zip`                              |\n| `npm run release`  | Bump version, build, zip, push GitHub release                    |\n\n### Contexts\n\n| Context            | Entry point                | Purpose                                                                                  |\n| ------------------ | -------------------------- | ---------------------------------------------------------------------------------------- |\n| **Popup**          | `src/main.tsx` → `App.tsx` | Settings UI — reads/writes `chrome.storage.sync`, sends messages to content scripts      |\n| **Content script** | `src/content.tsx`          | Runs on supported sites — applies/removes `.lcm-disabled` CSS class on matched listings |\n\nThe 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.\n\n### Storage schema (`chrome.storage.sync`)\n\n```ts\n{\n  websites: {\n    title: string;\n    url: string;\n    active: boolean;\n  }\n  [];\n  motors: {\n    title: string;\n    active: boolean;\n    pattern: string;\n  }\n  [];\n  hideCompletely: boolean; // default: true\n  showPlaceholderIcon: boolean; // default: false\n}\n```\n\nAll keys are initialised on first load from `src/store/initialState.ts` if missing. `pattern` is a case-insensitive regex string compiled at runtime.\n\nDefault motors:\n\n- `PureTech` — pattern: `puretech|pure[- ]tech`\n- `BlueHDi 1.5` — pattern: `(?=.*1\\.5)(?=.*blue[- ]?hdi)` (matches any order)\n\n### How filtering works\n\n1. On page load, the content script reads all storage keys and uses `initialState.ts` defaults for any that are missing\n2. If the current URL matches an active website, active motor patterns are compiled into regexes\n3. Vendor-specific selectors identify listing card containers; each card's full text + ARIA attributes are tested against the regexes\n4. Matched cards either get `.lcm-disabled` (grey-out) or `.lcm-hide-completely` + a placeholder bar (hide mode), depending on the `hideCompletely` setting\n5. Clicking a placeholder sets `data-lcm-user-show=\"true\"` on the card — it reappears dimmed with a \"Re-hide\" button overlay\n6. 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\n7. A debounced `MutationObserver` re-runs filtering automatically when the page DOM changes (e.g. infinite scroll)\n\n---\n\n## Debugging\n\n### Load the unpacked extension (Chrome)\n\n1. Run `npm run build`\n2. Open `chrome://extensions/`\n3. Enable **Developer mode** (top right)\n4. Click **Load unpacked** → select the `dist/` folder\n5. After code changes, run `npm run build` again and click the refresh icon on the extension card\n\n### Load the unpacked extension (Firefox)\n\nRun `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.\n\n### Inspect the popup\n\n- **Chrome:** `chrome://extensions/` → click **Inspect views: popup.html** under the extension\n- **Firefox:** `about:debugging` → click **Inspect** next to the extension → open popup manually\n\n### Inspect the content script\n\nOpen DevTools on any supported site (F12) → **Console** tab. The content script runs in the page context, not the extension background.\n\n### Inspect storage\n\nIn the extension's DevTools console (popup inspector):\n\n```js\nchrome.storage.sync.get(null, console.log);\n```\n\nTo reset storage to defaults:\n\n```js\nchrome.storage.sync.clear();\n```\n\n---\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikaleb%2Fhidepuretech","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikaleb%2Fhidepuretech","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikaleb%2Fhidepuretech/lists"}