{"id":50144598,"url":"https://github.com/thelinuxer/bitbucket-rich-diffs","last_synced_at":"2026-05-24T03:08:26.813Z","repository":{"id":354850627,"uuid":"1225565615","full_name":"thelinuxer/bitbucket-rich-diffs","owner":"thelinuxer","description":"Firefox extension that adds rendered views to Bitbucket Cloud pull-request diffs for file types Bitbucket doesn't preview well -- Markdown today, with more formats planned.","archived":false,"fork":false,"pushed_at":"2026-04-30T13:35:42.000Z","size":4071,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-30T14:20:47.797Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thelinuxer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-30T12:10:57.000Z","updated_at":"2026-04-30T13:37:31.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/thelinuxer/bitbucket-rich-diffs","commit_stats":null,"previous_names":["thelinuxer/bitbucket-rich-diffs"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/thelinuxer/bitbucket-rich-diffs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thelinuxer%2Fbitbucket-rich-diffs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thelinuxer%2Fbitbucket-rich-diffs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thelinuxer%2Fbitbucket-rich-diffs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thelinuxer%2Fbitbucket-rich-diffs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thelinuxer","download_url":"https://codeload.github.com/thelinuxer/bitbucket-rich-diffs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thelinuxer%2Fbitbucket-rich-diffs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33419589,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T22:14:44.296Z","status":"online","status_checked_at":"2026-05-24T02:00:06.296Z","response_time":57,"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":[],"created_at":"2026-05-24T03:08:26.161Z","updated_at":"2026-05-24T03:08:26.805Z","avatar_url":"https://github.com/thelinuxer.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bitbucket Rich Diffs\n\nA browser extension that renders **Markdown** and **ODS spreadsheet** files in Bitbucket Cloud pull-request diffs as proper formatted views — so reviewing prose, READMEs, design docs, and Tryton/Genshi report templates stops feeling like reading a `+`/`-` log (or a \"Binary file\" placeholder).\n\nWorks in **Firefox** and **Chrome** (and any Chromium-based browser that supports Chrome Web Store extensions).\n\n## Install\n\n[![Get the Add-on for Firefox](https://img.shields.io/badge/Firefox-Get%20the%20Add--on-FF7139?style=for-the-badge\u0026logo=firefox-browser\u0026logoColor=white)](https://addons.mozilla.org/en-US/firefox/addon/bitbucket-rich-diffs/)\n[![Available in the Chrome Web Store](https://img.shields.io/badge/Chrome-Available%20in%20the%20Web%20Store-4285F4?style=for-the-badge\u0026logo=googlechrome\u0026logoColor=white)](https://chromewebstore.google.com/detail/iblibjooindpmlpgagplcnmjkcpoaecm)\n\n\u003e **Firefox**: [addons.mozilla.org](https://addons.mozilla.org/en-US/firefox/addon/bitbucket-rich-diffs/)\n\u003e\n\u003e **Chrome**: [chromewebstore.google.com](https://chromewebstore.google.com/detail/iblibjooindpmlpgagplcnmjkcpoaecm)\n\nAfter installing, open any Bitbucket Cloud pull request that touches a `.md`, `.markdown`, `.mdx`, `.mkd`, or `.ods` file. A small toolbar appears above each supported file with three view modes:\n\n| Mode | Markdown | ODS |\n|---|---|---|\n| **Original diff** | Bitbucket's default `+`/`-` view | Bitbucket's \"Binary file\" placeholder |\n| **Rendered (unified)** | Rendered Markdown with added blocks tinted green and removed blocks tinted red | Spreadsheet grid with per-cell add/remove/change highlights |\n| **Rendered (side-by-side)** | Before / After columns of fully rendered Markdown | Before / After grids |\n\nODS files default to **Rendered (unified)** on open, since Bitbucket's Original view shows nothing useful for binary files.\n\n## See it in action\n\n### Markdown\n\n**Original diff** — Bitbucket's default view, untouched:\n\n![Original diff with the per-file toolbar](screens/01-original-diff.png)\n\n**Rendered (unified)** — the file rendered as actual Markdown, with added blocks tinted green and removed blocks tinted red and struck through, in document order:\n\n![Rendered unified view](screens/02-rendered-unified.png)\n\n**Rendered (side-by-side)** — two columns: Before on the left, After on the right, both fully rendered:\n\n![Rendered side-by-side view](screens/03-rendered-side-by-side.png)\n\n### ODS spreadsheets\n\nFor Tryton/Genshi `.ods` report templates the rendered grid shows each cell with its visible text plus the embedded `relatorio://` expression as a small chip. Cells changed between revisions are highlighted (green added, red removed, yellow changed with old → new shown in place, blue dotted border for format-only changes). Multi-sheet templates get a tab strip with per-sheet change counts.\n\nThe chevron and \"Viewed\" checkbox above the file card stay functional in every mode.\n\n## Load locally for development\n\nThe repo's source layout is browser-agnostic; a small build script assembles per-browser loadable directories into `dist/`.\n\n```bash\nscripts/build.sh                            # builds dist/firefox and dist/chrome\nscripts/build.sh --zip                      # also produces dist/\u003cbrowser\u003e.zip for stores\nscripts/build.sh --version 0.2.0 --zip      # explicit version override\nscripts/build.sh --browser firefox          # build only one\n```\n\nThen:\n\n- **Firefox** — go to `about:debugging#/runtime/this-firefox`, click **Load Temporary Add-on…**, pick `dist/firefox/manifest.json`.\n- **Chrome** — go to `chrome://extensions/`, enable **Developer mode**, click **Load unpacked**, select `dist/chrome/`.\n\nAfter editing `src/`, re-run `scripts/build.sh` and reload in the browser.\n\n## How it works\n\n1. The content script runs on `*://bitbucket.org/*/pull-requests/*` pages.\n2. It detects each file card on the diff page by looking for Bitbucket's per-file \"Viewed\" label, then walks up to find the enclosing card (an ancestor that also contains the diff hunks or the \"Binary file\" notice).\n3. Filters to supported file extensions (`.md`, `.markdown`, `.mdx`, `.mkd`, `.ods`) and injects a toolbar.\n4. On mode switch, it resolves the PR's source/destination commit hashes from Bitbucket and fetches the raw before/after content from `/raw/{commit}/{path}` using your existing browser session. ODS files are fetched as binary `ArrayBuffer`; markdown as text.\n5. Markdown is rendered with [`marked`](https://github.com/markedjs/marked), sanitized with [`DOMPurify`](https://github.com/cure53/DOMPurify), and diffed with [`jsdiff`](https://github.com/kpdecker/jsdiff). ODS files are unzipped with [`JSZip`](https://github.com/Stuk/jszip), parsed via DOMParser into a structured cell + style + hyperlink model, then rendered as an HTML grid with per-cell diff annotations.\n6. The rendered view is appended inside Bitbucket's body region, so the chevron expand/collapse naturally controls our preview alongside the original content.\n\nNo data leaves your browser other than the file fetches that go to Bitbucket directly. No tracking, no analytics, no separate authentication. The same code runs in both Firefox and Chrome — only the manifest differs. See [`PRIVACY.md`](PRIVACY.md) for the full privacy policy.\n\n## Files\n\n```\nmanifests/firefox.json   Firefox-specific MV3 manifest (background.scripts, gecko id)\nmanifests/chrome.json    Chrome-specific MV3 manifest (background.service_worker)\namo-metadata.json        AMO listing metadata used by the release pipeline\nscripts/build.sh         Assembles dist/firefox and dist/chrome from shared sources\nsrc/content.js           Page detection, toolbar, fetch, mode switching, dispatch\nsrc/renderer.js          Markdown + diff rendering helpers\nsrc/ods-parser.js        ODS unzip + cell/style/hyperlink extraction\nsrc/ods-renderer.js      ODS grid rendering with diff annotations\nsrc/background.js        Privileged fetch handler (cross-browser onMessage)\nsrc/styles.css           Toolbar, spinner, rendered Markdown, and ODS grid styling\nlib/marked.min.js        Markdown parser (MIT, vendored)\nlib/diff.min.js          Line-level diff (BSD-3, vendored, jsdiff)\nlib/purify.min.js        HTML sanitizer (Apache-2.0/MPL-2.0, vendored, DOMPurify)\nlib/jszip.min.js         ZIP reader for ODS unzipping (MIT, vendored)\nicons/                   Extension icons in 16, 32, 48, 96, 128 px sizes\nscreens/                 Screenshots used in this README and the store listings\n```\n\n## Releases\n\nTagging `v*` triggers a GitHub Actions workflow that builds per-browser packages (`scripts/build.sh --zip`), lints the Firefox build with `web-ext`, submits the Firefox build to AMO, and conditionally submits the Chrome build to the Chrome Web Store (gated on a `CWS_ENABLED` repo variable). It also creates a GitHub release with both zips attached. See [`RELEASING.md`](RELEASING.md), and the per-store listing copy in [`AMO_LISTING.md`](AMO_LISTING.md) and [`CHROME_LISTING.md`](CHROME_LISTING.md).\n\n## Known limitations\n\n- **Side-by-side Markdown** renders the two columns independently rather than line-aligned — aligning rendered HTML to source lines reliably is more trouble than it's worth.\n- **Unified Markdown** renders each diff hunk separately, so a list item or fenced code block split across hunks may render slightly differently than the full document would.\n- **ODS row alignment** is naive: if a row is inserted at the top of a sheet, every cell below shifts and the diff highlights everything. Smarter row-fingerprint alignment is on the roadmap.\n- **ODS cells with mid-stream changes** (e.g., a small change in a long sentence inside a cell) currently show old → new as block-level, not character-level.\n- **More file formats** (CSV, JSON tree, etc.) are planned.\n\n## License\n\nMIT — see [`LICENSE`](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthelinuxer%2Fbitbucket-rich-diffs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthelinuxer%2Fbitbucket-rich-diffs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthelinuxer%2Fbitbucket-rich-diffs/lists"}