Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define custom renderer #197

Closed
tbo opened this issue Mar 5, 2021 · 4 comments · Fixed by #431
Closed

Define custom renderer #197

tbo opened this issue Mar 5, 2021 · 4 comments · Fixed by #431

Comments

@tbo
Copy link

tbo commented Mar 5, 2021

Turbo drive doesn't offer any option to define custom rendering logic AFAIK. The current implementation simply replaces an old node with a new one. This can lead to unwanted side-effects (e.g. flickering content or losing dirty input states). I want to be able to define a renderer that uses a DOM diffing library like morphdom.
The easiest way would have been to use inheritance to create a custom PageView with a custom Renderer, but the necessary classes are not being exported (probably for good reasons).

Is there any clean way to implement a DOM diffing renderer?

@ghost
Copy link

ghost commented Mar 18, 2021

@tbo , awesome idea! This will allow transition to turbo frames in a lot of places where previously JS was required.
Looks like someone should try to implement such behavior in separated PR, which will add ability to "register" custom renderer.

@tbo
Copy link
Author

tbo commented Mar 18, 2021

@kirin121 I could do that. But I'd like to know from a core developer upfront, if this has any chance to be merged and how they want it to be implemented.

@sstephenson
Copy link
Contributor

Yes, this is something we'd like to support, but not in the form of custom renderer classes that plug into Turbo core. We'd rather support something like preventDefault() on turbo:before-render events with a mechanism to call back into Turbo when you've finished rendering.

@tbo
Copy link
Author

tbo commented Mar 26, 2021

@sstephenson I created a PR for it.

seanpdoyle added a commit to seanpdoyle/turbo that referenced this issue Oct 31, 2021
The problem
---

The rendering process during a page-wide navigation is opaque, and
cannot be extended. Proposals have been made to use third-party
rendering tools like [morphdom][], or other animation libraries.

Outside of the HTML manipulation, Turbo is also responsible for loading
script, transposing permanent elements, etc.

How might these tools integrate with Turbo in a way that's compliant
with permanent elements.

The solution
---

When publishing a `turbo:before-render` event, dispatch it with a
`render()` function property in addition to the `resume()`.

This way, consumer applications can override rendering:

```html
import morphdom from "morphdom"

addEventListener("turbo:before-render", ({ detail }) => {
  detail.render = (currentElement, newElement) => {
    morphdom(currentElement, newElement)
  }

  // or, more tersely
  detail.render = morphdom
})
```

Potentially Closes [hotwired#197][]
Potentially Closes [hotwired#378][]
Potentially Closes [hotwired#218][]

[morphdom]: https://github.com/patrick-steele-idem/morphdom
[hotwired#218]: hotwired#218
[hotwired#378]: hotwired#378
[hotwired#197]: hotwired#197
seanpdoyle added a commit to seanpdoyle/turbo that referenced this issue Nov 11, 2021
The problem
---

The rendering process during a page-wide navigation is opaque, and
cannot be extended. Proposals have been made to use third-party
rendering tools like [morphdom][], or other animation libraries.

Outside of the HTML manipulation, Turbo is also responsible for loading
script, transposing permanent elements, etc.

How might these tools integrate with Turbo in a way that's compliant
with permanent elements.

The solution
---

When publishing a `turbo:before-render` event, dispatch it with a
`render()` function property in addition to the `resume()`.

This way, consumer applications can override rendering:

```html
import morphdom from "morphdom"

addEventListener("turbo:before-render", ({ detail }) => {
  detail.render = (currentElement, newElement) => {
    morphdom(currentElement, newElement)
  }

  // or, more tersely
  detail.render = morphdom
})
```

Potentially Closes [hotwired#197][]
Potentially Closes [hotwired#378][]
Potentially Closes [hotwired#218][]

[morphdom]: https://github.com/patrick-steele-idem/morphdom
[hotwired#218]: hotwired#218
[hotwired#378]: hotwired#378
[hotwired#197]: hotwired#197
seanpdoyle added a commit to seanpdoyle/turbo that referenced this issue Jul 16, 2022
The problem
---

The rendering process during a page-wide navigation is opaque, and
cannot be extended. Proposals have been made to use third-party
rendering tools like [morphdom][], or other animation libraries.

Outside of the HTML manipulation, Turbo is also responsible for loading
script, transposing permanent elements, etc.

How might these tools integrate with Turbo in a way that's compliant
with permanent elements.

The solution
---

When publishing a `turbo:before-render` event, dispatch it with a
`render()` function property in addition to the `resume()`.

This way, consumer applications can override rendering:

```html
import morphdom from "morphdom"

addEventListener("turbo:before-render", ({ detail }) => {
  detail.render = (currentElement, newElement) => {
    morphdom(currentElement, newElement)
  }

  // or, more tersely
  detail.render = morphdom
})
```

Potentially Closes [hotwired#197][]
Potentially Closes [hotwired#378][]
Potentially Closes [hotwired#218][]

[morphdom]: https://github.com/patrick-steele-idem/morphdom
[hotwired#218]: hotwired#218
[hotwired#378]: hotwired#378
[hotwired#197]: hotwired#197
seanpdoyle added a commit to seanpdoyle/turbo that referenced this issue Jul 16, 2022
The problem
---

The rendering process during a page-wide navigation is opaque, and
cannot be extended. Proposals have been made to use third-party
rendering tools like [morphdom][], or other animation libraries.

Outside of the HTML manipulation, Turbo is also responsible for loading
script, transposing permanent elements, etc.

How might these tools integrate with Turbo in a way that's compliant
with permanent elements.

The solution
---

When publishing a `turbo:before-render` event, dispatch it with a
`render()` function property in addition to the `resume()`.

This way, consumer applications can override rendering:

```html
import morphdom from "morphdom"

addEventListener("turbo:before-render", ({ detail }) => {
  detail.render = (currentElement, newElement) => {
    morphdom(currentElement, newElement)
  }

  // or, more tersely
  detail.render = morphdom
})
```

Potentially Closes [hotwired#197][]
Potentially Closes [hotwired#378][]
Potentially Closes [hotwired#218][]

[morphdom]: https://github.com/patrick-steele-idem/morphdom
[hotwired#218]: hotwired#218
[hotwired#378]: hotwired#378
[hotwired#197]: hotwired#197
seanpdoyle added a commit to seanpdoyle/turbo that referenced this issue Jul 16, 2022
The problem
---

The rendering process during a page-wide navigation is opaque, and
cannot be extended. Proposals have been made to use third-party
rendering tools like [morphdom][], or other animation libraries.

Outside of the HTML manipulation, Turbo is also responsible for loading
script, transposing permanent elements, etc.

How might these tools integrate with Turbo in a way that's compliant
with permanent elements.

The solution
---

When publishing a `turbo:before-render` event, dispatch it with a
`render()` function property in addition to the `resume()`.

This way, consumer applications can override rendering:

```html
import morphdom from "morphdom"

addEventListener("turbo:before-render", ({ detail }) => {
  detail.render = (currentElement, newElement) => {
    morphdom(currentElement, newElement)
  }

  // or, more tersely
  detail.render = morphdom
})
```

Potentially Closes [hotwired#197][]
Potentially Closes [hotwired#378][]
Potentially Closes [hotwired#218][]

[morphdom]: https://github.com/patrick-steele-idem/morphdom
[hotwired#218]: hotwired#218
[hotwired#378]: hotwired#378
[hotwired#197]: hotwired#197
seanpdoyle added a commit to seanpdoyle/turbo that referenced this issue Jul 17, 2022
The problem
---

The rendering process during a page-wide navigation is opaque, and
cannot be extended. Proposals have been made to use third-party
rendering tools like [morphdom][], or other animation libraries.

Outside of the HTML manipulation, Turbo is also responsible for loading
script, transposing permanent elements, etc.

How might these tools integrate with Turbo in a way that's compliant
with permanent elements.

The solution
---

When publishing a `turbo:before-render` event, dispatch it with a
`render()` function property in addition to the `resume()`.

This way, consumer applications can override rendering:

```html
import morphdom from "morphdom"

addEventListener("turbo:before-render", ({ detail }) => {
  detail.render = (currentElement, newElement) => {
    morphdom(currentElement, newElement)
  }

  // or, more tersely
  detail.render = morphdom
})
```

Potentially Closes [hotwired#197][]
Potentially Closes [hotwired#378][]
Potentially Closes [hotwired#218][]

[morphdom]: https://github.com/patrick-steele-idem/morphdom
[hotwired#218]: hotwired#218
[hotwired#378]: hotwired#378
[hotwired#197]: hotwired#197
seanpdoyle added a commit to seanpdoyle/turbo that referenced this issue Jul 18, 2022
The problem
---

The rendering process during a page-wide navigation is opaque, and
cannot be extended. Proposals have been made to use third-party
rendering tools like [morphdom][], or other animation libraries.

Outside of the HTML manipulation, Turbo is also responsible for loading
script, transposing permanent elements, etc.

How might these tools integrate with Turbo in a way that's compliant
with permanent elements.

The solution
---

When publishing a `turbo:before-render` event, dispatch it with a
`render()` function property in addition to the `resume()`.

This way, consumer applications can override rendering:

```html
import morphdom from "morphdom"

addEventListener("turbo:before-render", ({ detail }) => {
  detail.render = (currentElement, newElement) => {
    morphdom(currentElement, newElement)
  }

  // or, more tersely
  detail.render = morphdom
})
```

Potentially Closes [hotwired#197][]
Potentially Closes [hotwired#378][]
Potentially Closes [hotwired#218][]

[morphdom]: https://github.com/patrick-steele-idem/morphdom
[hotwired#218]: hotwired#218
[hotwired#378]: hotwired#378
[hotwired#197]: hotwired#197
seanpdoyle added a commit to seanpdoyle/turbo that referenced this issue Jul 18, 2022
The problem
---

The rendering process during a page-wide navigation is opaque, and
cannot be extended. Proposals have been made to use third-party
rendering tools like [morphdom][], or other animation libraries.

Outside of the HTML manipulation, Turbo is also responsible for loading
script, transposing permanent elements, etc.

How might these tools integrate with Turbo in a way that's compliant
with permanent elements.

The solution
---

When publishing a `turbo:before-render` event, dispatch it with a
`render()` function property in addition to the `resume()`.

This way, consumer applications can override rendering:

```html
import morphdom from "morphdom"

addEventListener("turbo:before-render", ({ detail }) => {
  detail.render = (currentElement, newElement) => {
    morphdom(currentElement, newElement)
  }

  // or, more tersely
  detail.render = morphdom
})
```

Potentially Closes [hotwired#197][]
Potentially Closes [hotwired#378][]
Potentially Closes [hotwired#218][]

[morphdom]: https://github.com/patrick-steele-idem/morphdom
[hotwired#218]: hotwired#218
[hotwired#378]: hotwired#378
[hotwired#197]: hotwired#197
@dhh dhh closed this as completed in #431 Jul 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants