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.
- package/dist/browser.js +22 -0
- 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.
|