Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions great_docs/assets/great-docs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -889,13 +889,20 @@ dt a.doc-method-name::after {
General site styles (merged from great-docs.css)
============================================================================ */

/* Theme loading - hide page until theme is applied to prevent flash */
html.theme-loading {
/* Hide the page until theme-init.js has finished and after-body scripts have
painted. An inline <style> in metadata.html applies the same rules first
thing in <head>; they are repeated here for pages that don't use it.
`opacity` does the hiding: Quarto sets `visibility: visible !important` on
the sidebar sections, the TOC and the navbar offcanvas, which escapes an
inherited `visibility: hidden`. `visibility` stays to keep the hidden page
out of hit-testing. */
html:not(.theme-loaded) {
visibility: hidden;
}

html.theme-loading body {
html:not(.theme-loaded) body {
visibility: hidden;
opacity: 0;
}

/* General heading weight -- handled by SCSS @extend .fw-medium */
Expand Down
2 changes: 2 additions & 0 deletions great_docs/assets/metadata.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<meta charset="utf-8" />
<style>html:not(.theme-loaded){visibility:hidden}html:not(.theme-loaded) body{visibility:hidden;opacity:0}</style>
<noscript><style>html:not(.theme-loaded),html:not(.theme-loaded) body{visibility:visible!important;opacity:1!important}</style></noscript>
$if(quarto-version)$
<meta name="generator" content="quarto-$quarto-version$" />
$else$
Expand Down
16 changes: 9 additions & 7 deletions great_docs/assets/theme-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
var theme = stored || (darkModeDisabled ? 'light' : (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'));
var html = document.documentElement;

// Hide body until theme is fully applied to prevent flash
html.classList.add('theme-loading');

if (theme === 'dark') {
html.classList.add('quarto-dark');
html.setAttribute('data-bs-theme', 'dark');
Expand Down Expand Up @@ -61,13 +58,18 @@
}
}

// Reveal page once DOM is ready and styles are applied
// Reveal the page once the DOM is parsed and after-body scripts have run.
// The page is hidden by an inline <style> in the <head> (metadata.html)
// that targets html:not(.theme-loaded). A double requestAnimationFrame
// ensures the browser has painted the changes from after-body scripts
// (sidebar, dark-mode toggle, "On This Page", tags, etc.) before the
// page becomes visible.
function revealPage() {
setPageIdentifier();
// Small delay to ensure CSS is processed
requestAnimationFrame(function() {
html.classList.remove('theme-loading');
html.classList.add('theme-loaded');
requestAnimationFrame(function() {
html.classList.add('theme-loaded');
});
});
}

Expand Down
16 changes: 11 additions & 5 deletions tests/test_metadata_partial.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
HEAD_TAGS_LOOP = ["$for(gd-head-tags)$", "$gd-head-tags$", "$endfor$"]
# Removed as one block, since `$endif$` also closes Quarto's own conditionals.
ROBOTS_LINES = ["$if(robots)$", '<meta name="robots" content="$robots$" />', "$endif$"]
# Hide the page until theme-init.js reveals it (with a no-JS fallback).
PAGE_REVEAL_PREFIXES = ("<style>html:not(.theme-loaded)", "<noscript><style>html:not(.theme-loaded)")


def _quarto_partial() -> Path | None:
Expand Down Expand Up @@ -84,11 +86,15 @@ def _unmodified_lines(content: str) -> list[str]:
Returns
-------
:
Lines other than the title element, the robots tag and the
`gd-head-tags` loop.
Lines other than the title element, the robots tag, the page-reveal
styles and the `gd-head-tags` loop.
"""
content = content.replace("\n".join(ROBOTS_LINES) + "\n", "")
return [line for line in _without_title(content) if line not in HEAD_TAGS_LOOP]
return [
line
for line in _without_title(content)
if line not in HEAD_TAGS_LOOP and not line.startswith(PAGE_REVEAL_PREFIXES)
]


def test_bundled_partial_contains_title_element():
Expand All @@ -104,8 +110,8 @@ def test_bundled_partial_matches_quarto_except_for_title_and_head_tags() -> None
"""
Keep the bundled metadata tags aligned with Quarto

Exclude the title element, the robots tag and the `gd-head-tags` loop,
which great-docs replaces or adds.
Exclude the title element, the robots tag, the page-reveal styles and the
`gd-head-tags` loop, which great-docs replaces or adds.
"""
upstream = _quarto_partial()
assert upstream is not None
Expand Down
Loading