Skip to content

MyHeritage new-page-design support + Firefox/MV3 compatibility - #179

Closed
stbodie wants to merge 11 commits into
eljeffeg:masterfrom
stbodie:myheritage-and-firefox-support
Closed

MyHeritage new-page-design support + Firefox/MV3 compatibility#179
stbodie wants to merge 11 commits into
eljeffeg:masterfrom
stbodie:myheritage-and-firefox-support

Conversation

@stbodie

@stbodie stbodie commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

Three independent pieces of work, kept as separate commits:

  1. MyHeritage new-page-design collection (collections/myheritagenew.js) - MyHeritage's redesigned profile pages (profile-<site>-<id> URLs) previously fell through to "This website is not yet supported by SmartCopy." This adds a new, separate collection rather than touching the existing collections/myheritage.js, so the working legacy path is untouched. Includes full family linking (spouse, children, parents, siblings) - solved by reading the live rendered DOM (the new page is 100% client-rendered) and, for parents/siblings specifically, walking React's internal fiber tree via a MAIN-world content script to recover a link that never reaches the DOM at all. Fixes MyHeritage Redesign - need to adjust code #110, supersedes the abandoned Fix MyHeritage with new design #115. Also fixes MyHeritage [old design] marriage dates missing #85 (marriage date/place wasn't being captured at all, on either the focus person's or the spouse's own record).

  2. Firefox/MV3 compatibility (manifest.json, background.js, popup.js) - Firefox doesn't support background.service_worker (needs background.scripts) and has no chrome.offscreen API at all, so the extension was completely non-functional on Firefox. Fixes Firefox/Opera: extension likely non-functional - background.service_worker and chrome.offscreen aren't supported #178. Testing this as a temporary Firefox add-on surfaced and fixed two more Firefox-only bugs: an unconditional navigator.serviceWorker call in popup.js that doesn't exist in Firefox's popup context (threw uncaught, halting the rest of popup.js's top-level execution and cascading into every collection failing to register), and declarativeNetRequest's initiatorDomains rejecting Firefox's gecko id format (an email-like string, not a Chrome-style extension id) on every load.

  3. Location field duplication fix (buildform.js, popup.js) - found while testing Add children to a valid spouse #1 above, but a general bug affecting every collection's location fields, not anything MyHeritage-specific. Every location (birth/death/marriage/etc, for the focus profile and every family member) offers two alternative representations - a flat "Place:" string, and a geocoded place/city/county/state/country breakdown - meant to be mutually exclusive, but both could get auto-submitted together since the "was this flagged as changed" logic never checked which one was actually active. Worse, submitting the flat place name alone left the rest of Geni's location schema (city/county/state/country, plus street_address1, per Geni's own API docs) untouched, so stale values there kept showing up concatenated with the new place name. Fixed both: only the active representation auto-submits, and submitting the flat place name now explicitly blanks the rest of the schema.

Also: a small doc commit addressing #163 (Chrome "Load unpacked" instructions), version bumped to 4.14.0.0, credits updated.

Test plan

  • MyHeritage: verified against real profile pages (both raw pre-render source and live rendered DOM) with a jsdom harness reproducing the actual markup; confirmed live in Chrome and Firefox - focus person data, spouse, children, both parents, marriage date, and a sibling all resolve correctly with real profile ids and vitals from a single page load
  • Firefox: loaded as a temporary add-on - popup loads, collections register, no console errors on install/reload
  • Firefox manifest: 0 errors from Mozilla's own web-ext lint
  • Chrome: confirmed no regressions - popup, login, and existing collections all verified working live throughout
  • Location fix: confirmed via code tracing through the full path (form rendering -> field extraction -> submission), and via live testing against a real profile - street_address1 field name confirmed correct per Geni's API docs after an earlier guess (address_line_1/2/3, postal_code) caused a 500

🤖 Generated with Claude Code

authentifydan and others added 11 commits July 30, 2026 14:06
…ecko settings)

Firefox's MV3 implementation doesn't support background.service_worker
(it uses background.scripts instead) and has no chrome.offscreen API at
all, so the extension was previously non-functional on Firefox despite
declaring manifest_version 3. Fixes eljeffeg#178.

- manifest.json: declare both background.scripts and
  background.service_worker so each browser picks up what it supports
  (modern Chrome ignores scripts, modern Firefox ignores
  service_worker); add browser_specific_settings.gecko with an
  extension id, minimum version, and the data_collection_permissions
  Mozilla now requires for submission.
- background.js: evalObject() (used by Ancestry's legacy PersonCard
  eval fallback) now branches on chrome.offscreen - Firefox's MV3
  background is a real event page with its own document, so it hosts
  the sandboxed eval iframe directly instead of going through the
  Chrome-only offscreen document indirection.
- popup.js: guard the navigator.serviceWorker re-registration check,
  which doesn't exist in Firefox's popup context and was throwing
  uncaught, halting the rest of popup.js's top-level execution -
  including the `collections` array initialization, which cascaded
  into every single collection failing to register.

Verified by loading as a temporary add-on in Firefox: the popup now
loads and collections register correctly (previously every collection
threw "collections is undefined"). Confirmed 0 errors from Mozilla's
own web-ext lint, down from the warnings the unfixed manifest produced.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
MyHeritage rolled out a redesigned profile page under a new URL shape
(profile-<site>-<id>) that the existing collections/myheritage.js
doesn't match, so visiting one fell through to "This website is not
yet supported by SmartCopy." Adds a separate collection rather than
modifying the existing one, so the working legacy path stays untouched
while this is iterated on. Fixes eljeffeg#110, supersedes the abandoned eljeffeg#115.

The new page is fully client-rendered (the server response is an empty
shell), so this reads the live tab DOM after React has rendered it
(same mechanism as every other parseProfileData collection), not a
background fetch - a recursive fetch of any linked relative's own page
also comes back empty for the same reason, which the family-linking
code below accounts for.

Family linking, solved in three layers, each covering what the others
can't:
- Spouse/children: the Facts section has real <a href> links, and
  "Birth of son/daughter:" facts already carry the child's own full
  birth date+place, used directly instead of needing a second fetch.
- Parents/siblings: the "Immediate Family" cards have no href at all -
  the click handler reads a link_in_profile_page value straight out of
  a React component's props, which never reaches the DOM. New file
  annotateMyHeritageLinks.js is injected into the page's MAIN world
  (not the isolated world getPagesSource.js runs in, which can't see
  JS properties the page's own React attached) to walk React's fiber
  tree and stamp that link onto the card as a data attribute before
  the page is serialized.
- Birth/death years for parents/spouse/siblings (full dates aren't
  rendered anywhere for them) come from the Immediate Family cards'
  coarse "1881 - 1968" / "Born: 1937" year-range text as a fallback.

Also fixes a real gender-detection bug in the process: the
gender_F/gender_M class lives on the photo wrapper itself, whether the
person has a real photo or a silhouette placeholder - checking only
the silhouette classes (as this file's first draft did) missed every
profile with an actual photo.

Bump version to 4.14.0.0, and update the credits box for this release
(Randy Schoenberg's Geni Curator role, and Dan Bodenheimer's Geni
Curator/Testing/Bug Triage credit).

Verified against real profile pages (both the raw pre-render source
and the live rendered DOM) with a jsdom harness reproducing the actual
markup, and confirmed live in Chrome: focus person data, spouse,
children, both parents, and a sibling all resolve correctly with real
profile ids and vitals from a single page load.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Requested in eljeffeg#163 by someone testing without an npm/build toolchain
available - a plain "Load unpacked" pointed at the repo folder is all
that's needed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The Facts loop already reads this fact's date+place to help build the
spouse family link, but never saved it onto profiledata itself -
every other event type (birth, death, burial, baptism) does. Fixes
eljeffeg#85, which - checking the old collections/myheritage.js - was never
actually implemented there either (just a `// marriage data - parse
event tab` stub that was never filled in).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
142.0 was only required for Firefox-for-Android compatibility with
browser_specific_settings.gecko.data_collection_permissions; desktop
Firefox only needs 140.0 for that field. Since this extension has no
Android-specific concerns, prefer the lower desktop floor and accept
the one Android-only lint warning that comes with it - better than
blocking everyone on desktop Firefox below 142 (confirmed this was a
real, hard install-blocking gate: "Add-on ... is not compatible with
application version" on Firefox 140).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The "Marriage to:" fact's date/place was already being saved onto the
focus person's own profiledata, but never onto the spouse's family-
link entry - unlike children, whose own birth date/place (from "Birth
of son/daughter:") was already wired through. Same fix, same pattern:
attach the marriage data to the husband/wife entry directly, and carry
it through the recursive-fetch fallback the same way birth/death
already are.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… at once

Every location (birth/death/marriage/etc, for the focus profile and
every family member) is offered two alternative representations in
the form: a flat "Place:" string, and a geocoded breakdown split into
place/city/county/state/country. Only one is meant to be active at a
time, toggled by the geo on/off switch (geoqueryCheck()) - but whether
a field actually gets *submitted* is controlled separately by
isEnabled(), which only checks if the value was auto-flagged as new/
different data ("scored"), never which representation is the active
one. Since both representations share the same "scored" flag, both
could end up enabled and submitted together even though only one was
visible, and Geni's own combined location summary would then show the
flat place name and the geocoded city/state/country stacked back to
back - e.g. copying "Grunewald, Berlin, Germany" over an existing
"Berlin, Germany" produced "Grunewald, Berlin, Germany, Berlin,
Germany" on Geni.

Fix: gate auto-enable on whichever representation is actually active
(placeScored/geoScored, derived from the same geoqueryCheck() the
visibility toggle already uses), so only one is ever auto-submitted.
The separate #forcegeoswitch manual override for the geo breakdown is
left untouched.

This lives in buildform.js, shared by every collection, so it affected
birth/death/marriage/etc for any site, not anything MyHeritage or
Ancestry-specific.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The previous fix (from the now-merged location-duplication branch)
only cleared city/county/state/country when submitting the flat
"Place:" field. Turns out Geni's location schema has more fields than
SmartCopy's UI exposes at all - address_line_1/2/3 and postal_code -
and stale values in any of those keep showing up concatenated with the
new place name for the same reason as before. Confirmed by reviewing
Geni's actual edit form field list. Clearing all of them now, so the
flat place name is unambiguously the only thing describing the
location afterward.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
On Firefox, chrome.runtime.id returns the browser_specific_settings.
gecko.id from the manifest (an email-like string), not a Chrome-style
extension id. declarativeNetRequest's initiatorDomains rejects that
outright ("Invalid domain"), which was throwing uncaught on every
extension load/reload in Firefox. Wrapped in try/catch plus a .catch()
on the update call, so a browser that can't set this specific rule
just skips it - this feature (stripping X-Frame-Options for this
extension's own Geni iframes) degrades gracefully rather than
blocking anything else from working.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Live testing showed Geni's update API returning a 500 with these
fields included. Their names were guessed from labels shown in Geni's
own UI, never confirmed against the actual API - unlike
city/county/state/country, which are already used successfully by the
existing geo-breakdown submission code elsewhere in this file. Rather
than keep guessing field names against live Geni data, dropping the
unverified four and keeping only the confirmed-safe ones.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Per Geni's actual API documentation: place_name, city, county, state,
country, street_address1, latitude, longitude - a single address
field (not address_line_1/2/3), and no postal_code field at all. Adds
street_address1 to the fields cleared when submitting a flat place
name, now that the real field name is confirmed rather than guessed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@stbodie
stbodie force-pushed the myheritage-and-firefox-support branch from 5f10c64 to c01835e Compare July 30, 2026 21:07
@stbodie

stbodie commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator Author

Closing in favor of #181 - same work, opened from a fresh branch.

@stbodie stbodie closed this Jul 30, 2026
@stbodie
stbodie deleted the myheritage-and-firefox-support branch July 30, 2026 21:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants