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

Expose Frame load state via [complete] attribute #487

Merged
merged 2 commits into from
Jun 19, 2022

Commits on Jun 19, 2022

  1. Expose Frame load state via [loaded] attribute

    Closes hotwired#429
    
    ---
    
    Introduce the `<turbo-frame loaded>` boolean attribute. The attribute's
    absence indicates that the frame has not yet been loaded, and is ready
    to be navigated. Its presence means that the contents of the frame have
    been fetch from its `[src]` attribute.
    
    Encoding the load state into the element's HTML aims to integrate with
    Snapshot caching. Once a frame is loaded, navigating away and then
    restoring a page's state from an Historical Snapshot should preserve the
    fact that the contents are already loaded.
    
    For both `eager` and `lazy` loaded frames, changing the element's
    `[src]` attribute (directly via JavaScript, or by clicking an `<a>`
    element or submitting a `<form>` element) will remove the `[loaded]`
    attribute. Eager-loaded frames will immediately initiate a request to
    fetch the contents, and Lazy-loaded frames will initiate the request
    once they enter the viewport, or are changed to be eager-loading.
    
    When the `[src]` attribute is changed, the `FrameController` will only
    remove the `[loaded]` attribute if the element [isConnected][] to the
    document, so that the `[loaded]` attribute is not modified prior to
    Snapshot Caching or when re-mounting a Cached Snapshot.
    
    The act of "reloading" involves the removal of the `[loaded]` attribute,
    which can be done either by `FrameElement.reload()` or
    `document.getElementById("frame-element").removeAttribute("loaded")`.
    
    A side-effect of introducing the `[loaded]` attribute is that the
    `FrameController` no longer needs to internally track:
    
    1. how the internal `currentURL` value compares to the external
      `sourceURL` value
    2. whether or not the frame is "reloadable"
    
    By no longer tracking the `sourceURL` and `currentURL` separately, the
    implementation for the private `loadSourceURL` method can be simplified.
    Since there is no longer a `currentURL` property to rollback, the `try {
    ... } catch (error) { ... }` can be omitted, and the `this.sourceURL`
    presence check can be incorporated into the rest of the guard
    conditional.
    
    Finally, this commit introduce the `isIgnoringChangesTo()` and
    `ignoringChangesToAttribute()` private methods to disable
    FrameController observations for a given period of time. For example,
    when setting the `<turbo-frame src="...">` attribute, previous
    implementation would set, then check the value of a
    `this.settingSourceURL` property to decide whether or not to fire
    attribute change callback code. This commit refines that pattern to
    support any property of the `FrameElement` that's returned from the
    `FrameElement.observedAttributes` static property, including the `"src"`
    or `"loaded"` value. When making internal modifications to those values,
    it's important to temporarily disable observation callbacks to avoid
    unnecessary requests and to limit the potential for infinitely recursing
    loops.
    
    [isConnected]: https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected
    seanpdoyle committed Jun 19, 2022
    Configuration menu
    Copy the full SHA
    bccbe40 View commit details
    Browse the repository at this point in the history
  2. Expose Frame load state via [complete] attribute

    Closes hotwired#429
    
    ---
    
    Introduce the `<turbo-frame complete>` boolean attribute. The
    attribute's absence indicates that the frame has not yet been loaded,
    and is ready to be navigated. Its presence means that the contents of
    the frame have been fetch from its `[src]` attribute.
    
    Encoding the load state into the element's HTML aims to integrate with
    Snapshot caching. Once a frame is loaded, navigating away and then
    restoring a page's state from an Historical Snapshot should preserve the
    fact that the contents are already loaded.
    
    For both `eager` and `lazy` loaded frames, changing the element's
    `[src]` attribute (directly via JavaScript, or by clicking an `<a>`
    element or submitting a `<form>` element) will remove the `[complete]`
    attribute. Eager-loaded frames will immediately initiate a request to
    fetch the contents, and Lazy-loaded frames will initiate the request
    once they enter the viewport, or are changed to be eager-loading.
    
    When the `[src]` attribute is changed, the `FrameController` will only
    remove the `[complete]` attribute if the element [isConnected][] to the
    document, so that the `[complete]` attribute is not modified prior to
    Snapshot Caching or when re-mounting a Cached Snapshot.
    
    The act of "reloading" involves the removal of the `[complete]`
    attribute, which can be done either by `FrameElement.reload()` or
    `document.getElementById("frame-element").removeAttribute("complete")`.
    
    A side-effect of introducing the `[complete]` attribute is that the
    `FrameController` no longer needs to internally track:
    
    1. how the internal `currentURL` value compares to the external
      `sourceURL` value
    2. whether or not the frame is "reloadable"
    
    By no longer tracking the `sourceURL` and `currentURL` separately, the
    implementation for the private `loadSourceURL` method can be simplified.
    Since there is no longer a `currentURL` property to rollback, the `try {
    ... } catch (error) { ... }` can be omitted, and the `this.sourceURL`
    presence check can be incorporated into the rest of the guard
    conditional.
    
    Finally, this commit introduce the `isIgnoringChangesTo()` and
    `ignoringChangesToAttribute()` private methods to disable
    FrameController observations for a given period of time. For example,
    when setting the `<turbo-frame src="...">` attribute, previous
    implementation would set, then check the value of a
    `this.settingSourceURL` property to decide whether or not to fire
    attribute change callback code. This commit refines that pattern to
    support any property of the `FrameController`, including the
    `"sourceURL"` or `"complete"` value. When making internal modifications
    to those values, it's important to temporarily disable observation
    callbacks to avoid unnecessary requests and to limit the potential for
    infinitely recursing loops.
    
    [isConnected]: https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected
    seanpdoyle committed Jun 19, 2022
    Configuration menu
    Copy the full SHA
    f80597c View commit details
    Browse the repository at this point in the history