nnw-theme 2.0.0 → 2.0.1

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.
Files changed (2) hide show
  1. package/dist/browser.js +22 -0
  2. package/package.json +1 -1
package/dist/browser.js CHANGED
@@ -154,6 +154,8 @@ export function failures(state) {
154
154
  found.push(`broken images: ${pyReprList(state.brokenImages)}`);
155
155
  if (state.collapsedImages.length)
156
156
  found.push(`images drawn at zero size: ${pyReprList(state.collapsedImages)}`);
157
+ if (state.unloadedImages.length)
158
+ found.push(`images still loading: ${pyReprList(state.unloadedImages)}`);
157
159
  found.push(...(state.footnotes ?? []));
158
160
  if (state.blocked.length)
159
161
  found.push(`external requests: ${pyReprList(state.blocked)}`);
@@ -161,6 +163,21 @@ export function failures(state) {
161
163
  found.push(`page errors: ${pyReprList(state.pageErrors)}`);
162
164
  return found;
163
165
  }
166
+ // Runs in the page before its screenshot. A loading="lazy" image outside the viewport
167
+ // never starts loading in a full-page screenshot, so it would draw as blank space and
168
+ // escape the image checks; NetNewsWire loads it as the reader scrolls, so load every
169
+ // image now and wait (up to timeout ms) for each to finish or fail.
170
+ async function loadImages(timeout) {
171
+ const images = [...document.images];
172
+ for (const image of images)
173
+ if (image.loading === "lazy")
174
+ image.loading = "eager";
175
+ const settled = images.map((image) => image.decode().catch(() => { }));
176
+ await Promise.race([
177
+ Promise.all(settled),
178
+ new Promise((resolve) => setTimeout(resolve, timeout)),
179
+ ]);
180
+ }
164
181
  // Runs in the page after its screenshot.
165
182
  function pageState() {
166
183
  const article = document.querySelector(".articleBody");
@@ -194,6 +211,10 @@ function pageState() {
194
211
  return box.width < 1 || box.height < 1;
195
212
  })
196
213
  .map((image) => image.currentSrc || image.src),
214
+ // Still loading after loadImages: neither drawn nor covered by the checks above.
215
+ unloadedImages: [...document.images]
216
+ .filter((image) => !image.complete)
217
+ .map((image) => image.currentSrc || image.src),
197
218
  };
198
219
  }
199
220
  /**
@@ -260,6 +281,7 @@ async function checkPage(browser, origin, url, target, screenshot, footnotes) {
260
281
  const page = await context.newPage();
261
282
  page.on("pageerror", (error) => pageErrors.push(String(error)));
262
283
  await page.goto(url, { waitUntil: "networkidle" });
284
+ await page.evaluate(loadImages, 10_000);
263
285
  await page.screenshot({ path: screenshot, fullPage: true });
264
286
  const state = await page.evaluate(pageState);
265
287
  // Last: it clicks footnotes open, so it must not disturb the screenshot.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nnw-theme",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Create, preview, check, and publish a NetNewsWire theme.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Dave Marquard",