pandorga 1.6.6 → 1.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ea34cfd7c17d2af28fcbd6a14c791f47b62fcf3a0c1c27b453f2467e6e4e101e
4
- data.tar.gz: 7935fd040c610ffd52cab6587ecbcf31368a6097e21010f41b36ea92df013332
3
+ metadata.gz: 28483b04968177f92f86ee26292b1bca873db8515dcb0d1735b72be27a564fb8
4
+ data.tar.gz: d2d20eb68479f49655c122a3948398e8e2719a27be458e27bc6f60aa002729da
5
5
  SHA512:
6
- metadata.gz: 03e056b64de07a581a1b6293dd8a4db3aa40872219f170adfeaf25efe948317a62c04444db0cfe36cf67d8138ed003f9f832fc5c1150a0d84d174abc48232cdc
7
- data.tar.gz: cd7dec364ba9a21e18c0ec05e60bd7eed94ca99a217b99a5cd2a67498c9778e51a78267ba4cad58bab5098020e7c75f8be2e8a5df3b84b4d23c37b07313ed16f
6
+ metadata.gz: 89dd79f11d075413daac4ebcda740dc4f36a426a8b11aa608570551a446c79b09fc2223a74d703a36c2cae2fdaf0a14f41b6e3cf0048261c336a3a2a082e0100
7
+ data.tar.gz: efeaa1c9b49c5884e19b0e778e1a7205eec1dd000dc3c8875fa62747cf3a5df813202310f2cd2092d4d71847d629e6e8d1fedbf63e6bff8c99245f568f1a73f2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.6.7] — 2026-10-10
4
+
5
+ ### Fixed
6
+
7
+ - Text faces are requested after the first paint and before the load
8
+ event. A blocking sheet held first paint on the font host. The load
9
+ event held the hero summary until images finished, so the live home
10
+ scored about 50 while the example, which has no summary, scored 98.
11
+ - The icon face names the icons it needs. The full variable file is about
12
+ a megabyte, and decoding it blocked the main thread on the live home.
13
+ - The project inventory region has a role to match its accessible name.
14
+ - Lighthouse measures `examples/full`, whose home includes a static hero
15
+ summary, the element a real site paints largest.
16
+
17
+ No `pandorga:` config keys were added or renamed.
18
+
3
19
  ## [1.6.6] — 2026-10-10
4
20
 
5
21
  ### Fixed
@@ -54,7 +54,7 @@
54
54
  data-tag-base="{{ _path }}"
55
55
  >
56
56
  <div class="home-project-specimen-slot" data-home-specimen></div>
57
- <div class="home-project-inventory" data-home-inventory aria-label="Project inventory"></div>
57
+ <div class="home-project-inventory" data-home-inventory role="region" aria-label="Project inventory"></div>
58
58
  </div>
59
59
  {%- else -%}
60
60
  <div
@@ -52,16 +52,12 @@
52
52
  {% endif %}
53
53
  {% assign fonts_href = fonts_href | append: "&display=swap" %}
54
54
  {% comment %}
55
- Not a head link. A preload or a print sheet is discovered immediately.
56
- On a fast connection the faces finish before the largest paint, and the
57
- simulator then waits on them. Add the sheet after load. display=swap stays.
55
+ Not a render-blocking head link, and not the load event. A blocking
56
+ sheet holds first paint on the font host. The load event holds the hero
57
+ summary until images finish. The shell inserts this sheet after the
58
+ first paint. display=swap stays.
58
59
  {% endcomment %}
59
60
  <script>
60
- window.addEventListener('load', function () {
61
- var link = document.createElement('link');
62
- link.rel = 'stylesheet';
63
- link.href = {{ fonts_href | jsonify }};
64
- document.head.appendChild(link);
65
- });
61
+ window.__pandorgaFontsHref = {{ fonts_href | jsonify }};
66
62
  </script>
67
63
  <noscript><link rel="stylesheet" href="{{ fonts_href }}" /></noscript>
data/_layouts/shell.html CHANGED
@@ -62,7 +62,7 @@
62
62
  Preconnect only. The preload script below is parser-blocking. A
63
63
  stylesheet before that script holds the parser until the font host
64
64
  answers, so the ledger sheets and the hero cannot paint. The text-face
65
- loader sits with the local sheets and adds its stylesheet after load.
65
+ loader sits with the local sheets.
66
66
  {%- endcomment -%}
67
67
  <link href="https://fonts.googleapis.com" rel="preconnect" />
68
68
  <link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect" />
@@ -117,20 +117,65 @@
117
117
  {%- endfor -%}
118
118
  {% include theme/font-loader.html %}
119
119
  {%- comment -%}
120
- Icons are not first paint. The face is about a megabyte. A link in the
121
- head, even with print media, is discovered immediately and the simulator
122
- then waits on that face for the largest paint. Add the sheet after load.
120
+ Named icons only. The full variable face is about a megabyte, and a
121
+ late request for it becomes the largest paint on a real hero. Nav icons
122
+ from the registry join the shell set.
123
123
  {%- endcomment -%}
124
- {%- assign _symbols_href = "https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" -%}
124
+ {%- assign _icon_names = "arrow_left_alt,arrow_right_alt,architecture,article,chat,chevron_left,chevron_right,close,code,dark_mode,expand_more,filter_list,format_quote,format_size,info,light_mode,menu,picture_as_pdf,public,routine,search,share,shuffle,sync" -%}
125
+ {%- for _group in site.data.nav -%}
126
+ {%- for _item in _group.pages -%}
127
+ {%- if _item.icon -%}
128
+ {%- assign _icon_hay = "," | append: _icon_names | append: "," -%}
129
+ {%- assign _icon_needle = "," | append: _item.icon | append: "," -%}
130
+ {%- unless _icon_hay contains _icon_needle -%}
131
+ {%- assign _icon_names = _icon_names | append: "," | append: _item.icon -%}
132
+ {%- endunless -%}
133
+ {%- endif -%}
134
+ {%- endfor -%}
135
+ {%- endfor -%}
136
+ {%- assign _symbols_href = "https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&icon_names=" | append: _icon_names | append: "&display=swap" -%}
125
137
  <script>
126
- window.addEventListener('load', function () {
127
- var link = document.createElement('link');
128
- link.rel = 'stylesheet';
129
- link.href = {{ _symbols_href | jsonify }};
130
- document.head.appendChild(link);
131
- });
138
+ window.__pandorgaIconsHref = {{ _symbols_href | jsonify }};
139
+ </script>
140
+ <noscript><link id="pandorga-icons" rel="stylesheet" href="{{ _symbols_href }}" /></noscript>
141
+ <script>
142
+ (function () {
143
+ var known = {{ _icon_names | split: "," | jsonify }};
144
+ var seen = {};
145
+ known.forEach(function (name) { seen[name] = true; });
146
+ var dirty = false;
147
+ var timer = 0;
148
+ window.__pandorgaFlushIcons = function () {
149
+ var link = document.getElementById('pandorga-icons');
150
+ if (!link || !dirty) return;
151
+ dirty = false;
152
+ link.href = 'https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&icon_names=' + known.join(',') + '&display=swap';
153
+ };
154
+ function consider(root) {
155
+ if (!root || !root.querySelectorAll) return;
156
+ var nodes = root.querySelectorAll('.material-symbols-outlined');
157
+ var extra = false;
158
+ for (var i = 0; i < nodes.length; i++) {
159
+ var name = (nodes[i].textContent || '').trim();
160
+ if (!name || seen[name] || !/^[a-z0-9_]+$/.test(name)) continue;
161
+ seen[name] = true;
162
+ known.push(name);
163
+ extra = true;
164
+ }
165
+ if (!extra) return;
166
+ dirty = true;
167
+ clearTimeout(timer);
168
+ timer = setTimeout(window.__pandorgaFlushIcons, 50);
169
+ }
170
+ function start() {
171
+ consider(document);
172
+ var obs = new MutationObserver(function () { consider(document); });
173
+ obs.observe(document.body, { childList: true, subtree: true, characterData: true });
174
+ }
175
+ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start);
176
+ else start();
177
+ })();
132
178
  </script>
133
- <noscript><link rel="stylesheet" href="{{ _symbols_href }}" /></noscript>
134
179
  {%- assign _flags_href = "https://cdn.jsdelivr.net/gh/lipis/flag-icons@7.2.3/css/flag-icons.min.css" -%}
135
180
  <script>
136
181
  window.addEventListener('load', function () {
@@ -265,6 +310,28 @@
265
310
  {% include page/site-footer.html nav_active=nav_active %}
266
311
 
267
312
  {% include page/content-runtime.html %}
313
+ <script>
314
+ (function () {
315
+ var fonts = window.__pandorgaFontsHref;
316
+ var icons = window.__pandorgaIconsHref;
317
+ if (!fonts && !icons) return;
318
+ requestAnimationFrame(function () {
319
+ requestAnimationFrame(function () {
320
+ function sheet(href, id) {
321
+ if (!href) return;
322
+ var link = document.createElement('link');
323
+ link.rel = 'stylesheet';
324
+ link.href = href;
325
+ if (id) link.id = id;
326
+ document.head.appendChild(link);
327
+ }
328
+ sheet(fonts);
329
+ sheet(icons, 'pandorga-icons');
330
+ if (window.__pandorgaFlushIcons) window.__pandorgaFlushIcons();
331
+ });
332
+ });
333
+ })();
334
+ </script>
268
335
 
269
336
  </body>
270
337
 
@@ -1 +1 @@
1
- Ada Example designs publishing frames. This summary is fictional.
1
+ Ada Example designs publishing frames. This summary is fictional. The home hero includes it as HTML, so the largest paint is this paragraph, the same element a real site measures.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pandorga
4
- VERSION = "1.6.6"
4
+ VERSION = "1.6.7"
5
5
  end
@@ -6,7 +6,7 @@
6
6
  set -euo pipefail
7
7
 
8
8
  ROOT="$(cd "$(dirname "$0")/.." && pwd)"
9
- SITE="${ROOT}/examples/minimal/_site"
9
+ SITE="${ROOT}/examples/full/_site"
10
10
  PORT="${LIGHTHOUSE_PORT:-4173}"
11
11
  OUT="${LIGHTHOUSE_REPORT:-/tmp/lighthouse-home.json}"
12
12
  FAIL_BELOW=75
@@ -26,6 +26,8 @@ if [[ "${MODE}" != "enforce" && "${MODE}" != "warn" ]]; then
26
26
  fi
27
27
 
28
28
  [[ -f "${SITE}/index.html" ]] || fail "missing ${SITE}/index.html (run scripts/validate.sh first)"
29
+ grep -q 'id="home-cv-summary"[^>]*data-content-static' "${SITE}/index.html" \
30
+ || fail "example home has no static hero summary (data-content-static)"
29
31
 
30
32
  if [[ -n "${CHROME_PATH:-}" && -x "${CHROME_PATH}" ]]; then
31
33
  CHROME="${CHROME_PATH}"
@@ -64,22 +64,28 @@ fail!("icon face is preloaded") if shell.include?("rel=\"preload\" as=\"style\"
64
64
 
65
65
  screen = shell.sub(%r{<noscript>.*?</noscript>}m, "")
66
66
  fail!("Material Symbols sheet is missing") unless shell.include?("Material+Symbols+Outlined")
67
- fail!("icon sheet is not deferred until load") unless screen.include?("addEventListener('load'")
68
- fail!("screen still has a Material Symbols stylesheet link") if screen.match?(/<link\b[^>]*Material\+Symbols/)
69
67
  fail!("screen still has a flag stylesheet link") if screen.match?(/<link\b[^>]*flag-icons/)
70
68
  fail!("flag sheet is not deferred until load") unless screen.include?("flag-icons@7.2.3")
69
+ fail!("icon face is the full variable font") if shell.include?("0..1&display=swap")
70
+ fail!("icon face is not a named subset") unless shell.include?("icon_names=")
71
+ fail!("icon subset link has no id") unless screen.include?("pandorga-icons")
71
72
 
72
73
  fonts = ROOT.join("_includes/theme/font-loader.html").read
73
- font_screen = fonts.sub(%r{<noscript>.*?</noscript>}m, "")
74
74
  fail!("text faces are preloaded") if fonts.include?('rel="preload"')
75
- fail!("text face sheet is not deferred until load") unless font_screen.include?("addEventListener('load'")
76
- fail!("screen still has a text-face stylesheet link") if font_screen.match?(/<link\b/)
75
+ fail!("text face still waits for the load event") if fonts.include?("addEventListener('load'")
76
+ fail!("text face href is not handed to the shell") unless fonts.include?("__pandorgaFontsHref")
77
+ fail!("text face is not requested after first paint") unless screen.scan("requestAnimationFrame").length >= 2
77
78
 
78
79
  marked = ROOT.join("_includes/content-runtime/00-config.html").read
79
80
  fail!("markdown library still blocks parsing") unless marked.include?("<script defer ")
80
81
  fail!("markdown library source changed") unless marked.include?("marked@15.0.7/marked.min.js")
81
82
 
82
- fail!("spec still discovers text faces from the head") unless spec.include?("text-face stylesheet is not a head link")
83
+ fail!("spec still withholds the text face until load") unless spec.include?("after the first paint and before the load event")
84
+ fail!("lighthouse example is not the full site") unless script.include?("examples/full")
85
+ fail!("lighthouse example can ship without a static summary") unless script.include?("data-content-static")
86
+ summary = ROOT.join("examples/full/content/pages/cv/summary.md").read
87
+ fail!("full summary dropped the fixture sentence") unless summary.include?("Ada Example designs publishing frames")
88
+ fail!("full summary is too short to be the hero paint") unless summary.scan(".").length >= 3
83
89
  fail!("spec still lets the markdown library block parsing") unless spec.include?("markdown library loads with `defer`")
84
90
  fail!("lighthouse script hides the metric breakdown") unless script.include?("largest-contentful-paint")
85
91
 
@@ -92,6 +98,7 @@ fail!("content runtime still precedes the page") unless shell.index("{{ content
92
98
  band = File.read(File.expand_path("../../_includes/home/band-listing.html", __dir__))
93
99
  fail!("band title is still painted by script") unless band.include?('data-content-section-title>{{ _title }}')
94
100
  fail!("band note is still painted by script") unless band.include?("page_headers")
101
+ fail!("project inventory has a name and no role") unless band.include?('role="region"') && band.include?('aria-label="Project inventory"')
95
102
  headers = File.read(File.expand_path("../../_plugins/content_headers.rb", __dir__))
96
103
  fail!("page headers are not loaded at build time") unless headers.include?('site.data["page_headers"]')
97
104
  home = File.read(File.expand_path("../../_layouts/home.html", __dir__))
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pandorga
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.6
4
+ version: 1.6.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Pandorga contributors