Skip to content

Commit

Permalink
Allow morphing between different URLs
Browse files Browse the repository at this point in the history
Allows morphing between similar types of pages that have different URLs.

A proof of concept fix for the problem descrubed here: hotwired#1177

For example, if you set this meta tag:

<meta name="turbo-morph-url-prefix" content="/images/">

Then morphing will be triggered for:

- `/images/1`
- `/images/12`
- `/images/123`

This solution has some downsides (e.g, won't work with nested
resources). A regex-based alternative could address that.

Please let me know if you'd be willing to consider this change and I'll
go ahead and add tests.
  • Loading branch information
pch committed Feb 8, 2024
1 parent e2e5782 commit ddeaf3e
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/core/drive/page_snapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ export class PageSnapshot extends Snapshot {
return this.getSetting("refresh-scroll") === "preserve"
}

get morphURLPrefix() {
return this.getSetting("morph-url-prefix") ?? ""
}

// Private

getSetting(name) {
Expand Down
15 changes: 13 additions & 2 deletions src/core/drive/page_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ export class PageView extends View {
}

renderPage(snapshot, isPreview = false, willRender = true, visit) {
const shouldMorphPage = this.isPageRefresh(visit) && this.snapshot.shouldMorphPage
const rendererClass = shouldMorphPage ? MorphRenderer : PageRenderer
const rendererClass = this.shouldMorphPage(visit) ? MorphRenderer : PageRenderer

const renderer = new rendererClass(this.snapshot, snapshot, PageRenderer.renderElement, isPreview, willRender)

Expand Down Expand Up @@ -63,6 +62,18 @@ export class PageView extends View {
return this.isPageRefresh(visit) && this.snapshot.shouldPreserveScrollPosition
}

shouldMorphPage(visit) {
return (this.isPageRefresh(visit) || this.isMorphableURL(visit)) && this.snapshot.shouldMorphPage
}

isMorphableURL(visit) {
return (
this.snapshot.morphURLPrefix != "" &&
this.lastRenderedLocation.pathname.startsWith(this.snapshot.morphURLPrefix) &&
visit.action === "advance"
)
}

get snapshot() {
return PageSnapshot.fromElement(this.element)
}
Expand Down

0 comments on commit ddeaf3e

Please sign in to comment.