docs: fix relative path images not appearing#2167
docs: fix relative path images not appearing#2167lucbic wants to merge 14 commits intosuperdoc-dev:mainfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: db54c3bb42
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
packages/super-editor/src/extensions/image/imageHelpers/imageRegistrationPlugin.js
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
thanks for the contribution, @lucbic! the approach is solid and the code is clean. left one inline comment — it's a blocking bug since the tests contradict the current behavior at line 526.
|
p.s. also rebase with main looks like all tests are failing here |
ed83de7 to
1763e56
Compare
caio-pizzol
left a comment
There was a problem hiding this comment.
@lucbic dot-relative fix looks good. left one inline note about a bare-path edge case — not blocking.
packages/super-editor/src/extensions/image/imageHelpers/imageRegistrationPlugin.js
Show resolved
Hide resolved
02b2314 to
816a368
Compare
caio-pizzol
left a comment
There was a problem hiding this comment.
@lucbic approach looks good, clean structure.
one thing to check — relative paths like ./photo.png resolve from the site root instead of the current page. small fix inline.
also a question about whether skipping relative images in the browser path affects export.
one minor cleanup on the origin comparison. test coverage looks solid.
left inline comments.
packages/super-editor/src/extensions/image/imageHelpers/imageRegistrationPlugin.js
Show resolved
Hide resolved
caio-pizzol
left a comment
There was a problem hiding this comment.
@lucbic prior feedback addressed, nice. tested locally on the docs site — images show up and export works.
two small things inline. nothing blocking. feel free to merge after addressing those last comments.
on tests: we only have unit tests for this. would be good to also have:
- a behavior test: open a doc with relative image paths, export to DOCX, check images are in the file
- more unit tests: (1) inserting the same image twice while the first is still loading, (2) what happens when the image can't be fetched, (3) checking exact fallback size values instead of just "truthy"
packages/super-editor/src/extensions/image/imageHelpers/imageRegistrationPlugin.js
Outdated
Show resolved
Hide resolved
packages/super-editor/src/extensions/image/imageHelpers/imageRegistrationPlugin.js
Outdated
Show resolved
Hide resolved
sanitizeHref previously rejected all relative paths, which broke image rendering in docs widgets that use paths like /public/images/photo.png. Instead of rejecting, relative paths are now resolved against the page origin with security enforcement: control character rejection, same-origin gate, and redirect blocklist support. This also skips the destructive image registration pipeline for relative-path images since the browser resolves them directly.
…zeHref Extend relative path detection to include paths starting with '.' (e.g., './image.png') in addition to '/' to properly handle relative imports in document processors.
…e paths - Add isRelativeUrl() helper using negation-based scheme detection for robustness - Support bare relative paths (e.g., images/photo.png) in sanitizeHref - Add comprehensive tests for isRelativeUrl() covering all path types - Add tests for bare path resolution in browser context
- Replace inline isRelativePath with imported isRelativeUrl from @superdoc/url-validation - Ensures consistent relative URL detection across codebase - Supports bare paths like images/photo.png
…directory Use window.location.href instead of window.location.origin so that relative paths like ./images/chart.jpg resolve against the current page directory rather than the site root.
Add registerRelativeImages to fetch binary data in the background for relative-path images (./photo.png, /public/images/img.png) so they can be included in DOCX exports. Skip re-registration for relative URLs that already have an rId.
Images with an empty attrs.size object (e.g. from HTML imports) caused pixelsToEmu(undefined) producing invalid wp:extent elements, which corrupted the exported DOCX. Check for explicit width/height values and fall back to default dimensions when missing.
Migrate the module-scoped Set to editor.storage.image to scope it per editor instance. Prevents duplicate relative URL registration when multiple editors exist on the same page.
Verifies that relative-URL images are fetched asynchronously and embedded in DOCX exports via registerRelativeImages. The test validates: - Image node receives rId after async registration - Exported DOCX contains image in word/media/ - PNG binary integrity is preserved - Relationships XML and document XML reference the image correctly Adds jszip dev dependency to parse and inspect exported DOCX.
Add three test cases for relative URL image registration: - Duplicate relative URLs: Verify that when two images with the same relative src arrive during loading, urlToFile is only called once due to pendingRelativeRegistrations deduplication guard. - Fetch failure: Verify that when urlToFile returns null (network error, 404, etc.), no media store entry or rId is created, and no transaction is dispatched. - Exact fallback size values: Update the existing fallback size test to assert exact EMU values (300×200 px fallback) instead of just truthy, catching regressions if defaults are changed. Follows Conventional Commits style per CONTRIBUTING.md guidelines.
2a9986b to
71430ed
Compare
|
@caio-pizzol all done! I have changed the approach for registering the pendingRelativeRegistrations, now it's using the instance storage, so I guess it would be nice if you could take a look again. I have also rebased from main and solved a few conflicts. A Few tests are failing, but they are unrelated to the changes in this branch |
caio-pizzol
left a comment
There was a problem hiding this comment.
@lucbic previous feedback all addressed, nice. two small inline comments — an edge case with duplicate images missing from export, and a helper reuse. tests look good.
| for (const { node } of images) { | ||
| const src = node.attrs.src; | ||
|
|
||
| if (pendingRelativeRegistrations.has(src)) continue; |
There was a problem hiding this comment.
if the same image gets inserted twice quickly, the second copy can end up without export data — it'll be missing from the DOCX. editing near it fixes it, but that's easy to miss. worth a fix or TODO?
| pendingRelativeRegistrations.add(src); | ||
|
|
||
| try { | ||
| const filename = src.split('/').pop()?.split(/[?#]/)[0] || 'image.bin'; |
There was a problem hiding this comment.
derivePreferredFileName (line 125) already does this.
| const filename = src.split('/').pop()?.split(/[?#]/)[0] || 'image.bin'; | |
| const filename = derivePreferredFileName(src); |
sanitizeHref previously rejected all relative paths, which broke image rendering in docs widgets that use paths like /public/images/photo.png.
Instead of rejecting, relative paths are now resolved against the page origin with security enforcement: control character rejection, same-origin gate, and redirect blocklist support. This also skips the destructive image registration pipeline for relative-path images since the browser resolves them directly.
Refs: #2155