Implemented the scripts' deferral on the Page protocol in the Infrastructure package.
This commit is contained in:
@@ -5,7 +5,7 @@ import Foundation
|
||||
///
|
||||
/// A conforming page supplies its locale, its title, the stylesheets and scripts it needs, its head metadata, and its content; the protocol assembles the
|
||||
/// rest of the document around them: the viewport declaration, the summary, canonical, and social card tags, the structured data script, the analytics
|
||||
/// tracker script, and the metadata followed by the stylesheet links in the head, and the content followed by the script tags in the body.
|
||||
/// tracker script, and the metadata followed by the stylesheet links and the deferred script tags in the head, and the content as the body.
|
||||
public protocol Page: HTMLDocument, Sendable {
|
||||
|
||||
// MARK: Associated types
|
||||
@@ -27,7 +27,7 @@ public protocol Page: HTMLDocument, Sendable {
|
||||
/// The canonical URL the page is served at, rendered as a `link rel="canonical"` tag in the document head, or `nil` (the default) to omit the tag.
|
||||
var canonicalURL: String? { get }
|
||||
|
||||
/// The page's markup, rendered before the ``scripts``.
|
||||
/// The page's markup, rendered as the document body.
|
||||
@HTMLBuilder
|
||||
var content: Content { get }
|
||||
|
||||
@@ -38,7 +38,10 @@ public protocol Page: HTMLDocument, Sendable {
|
||||
@HTMLBuilder
|
||||
var metadata: Metadata { get }
|
||||
|
||||
/// The scripts loaded at the end of the document body, in order.
|
||||
/// The scripts loaded from the document head, in order.
|
||||
///
|
||||
/// Rendered as `defer`red tags: the downloads start while the head is parsed, and the scripts still execute in order only after the
|
||||
/// document is fully parsed — the same semantics end-of-body tags would give, minus the late download start.
|
||||
var scripts: [any Asset] { get }
|
||||
|
||||
/// The card controlling the page's link previews, rendered as Open Graph and Twitter meta tags in the document head, or `nil` (the default)
|
||||
@@ -67,21 +70,15 @@ public extension Page {
|
||||
nil
|
||||
}
|
||||
|
||||
/// The page ``content`` followed by its ``scripts``.
|
||||
/// The page ``content``; the ``scripts`` load deferred from the ``head``.
|
||||
@HTMLBuilder
|
||||
var body: some HTML {
|
||||
content
|
||||
|
||||
for file in scripts {
|
||||
script(.src(file.urlPath(
|
||||
for: .js,
|
||||
version: assetVersion
|
||||
))) {}
|
||||
}
|
||||
}
|
||||
|
||||
/// The viewport declaration, the ``summary``, ``canonicalURL``, and ``socialCard`` tags, the ``structuredData`` script and the
|
||||
/// ``analytics`` tracker script (when provided), and the ``metadata`` followed by the ``stylesheets`` links, placed in the document head.
|
||||
/// ``analytics`` tracker script (when provided), and the ``metadata`` followed by the ``stylesheets`` links and the deferred
|
||||
/// ``scripts`` tags, placed in the document head.
|
||||
///
|
||||
/// The charset declaration is omitted: Elementary's `HTMLDocument` scaffolding already emits `<meta charset="UTF-8">` before this markup,
|
||||
/// and HTML5 allows only one.
|
||||
@@ -155,6 +152,16 @@ public extension Page {
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
for file in scripts {
|
||||
script(
|
||||
.defer,
|
||||
.src(file.urlPath(
|
||||
for: .js,
|
||||
version: assetVersion
|
||||
))
|
||||
) {}
|
||||
}
|
||||
}
|
||||
|
||||
/// The analytics tracker is omitted unless the page provides one.
|
||||
|
||||
Reference in New Issue
Block a user