nnw-theme 1.0.0 → 1.0.2
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/assets/stubs/AGENTS.md +7 -0
- package/dist/browser.js +21 -0
- package/dist/commands/init.js +18 -1
- package/package.json +1 -1
package/assets/stubs/AGENTS.md
CHANGED
|
@@ -6,6 +6,13 @@ its `fixtures/`, and `screenshots/`. The tooling is the `nnw-theme` npm package;
|
|
|
6
6
|
run it as `npx nnw-theme@1 <command>`. Never install it globally and never add
|
|
7
7
|
it to this repository. Read `npx nnw-theme@1 guide` before theme work.
|
|
8
8
|
|
|
9
|
+
If this repository is `dave-atx/netnewswire-theme-template` itself (check
|
|
10
|
+
`git remote -v`), it is the GitHub template, not a theme: do not initialize,
|
|
11
|
+
fork, or design in it. Help the user create their own repository from it with
|
|
12
|
+
**Use this template** or `gh repo create NAME --template
|
|
13
|
+
dave-atx/netnewswire-theme-template --clone`, confirming before you create it,
|
|
14
|
+
then work in that copy.
|
|
15
|
+
|
|
9
16
|
If `.nnw-theme-uninitialized` exists, run `npx nnw-theme@1 init` first and let
|
|
10
17
|
the user confirm the permanent theme identifier. Prefer CSS changes; change
|
|
11
18
|
`template.html` only when the requested structure or behavior requires it.
|
package/dist/browser.js
CHANGED
|
@@ -128,6 +128,8 @@ export function failures(state) {
|
|
|
128
128
|
found.push("horizontal document overflow");
|
|
129
129
|
if (state.brokenImages.length)
|
|
130
130
|
found.push(`broken images: ${pyReprList(state.brokenImages)}`);
|
|
131
|
+
if (state.collapsedImages.length)
|
|
132
|
+
found.push(`images drawn at zero size: ${pyReprList(state.collapsedImages)}`);
|
|
131
133
|
found.push(...(state.footnotes ?? []));
|
|
132
134
|
if (state.blocked.length)
|
|
133
135
|
found.push(`external requests: ${pyReprList(state.blocked)}`);
|
|
@@ -149,6 +151,25 @@ function pageState() {
|
|
|
149
151
|
brokenImages: [...document.images]
|
|
150
152
|
.filter((image) => image.complete && image.naturalWidth === 0)
|
|
151
153
|
.map((image) => image.currentSrc || image.src),
|
|
154
|
+
// A loaded image the theme lays out at no size, such as a percentage width
|
|
155
|
+
// inside a shrink-to-fit float, which WebKit resolves to zero. Images that are
|
|
156
|
+
// not laid out at all (display: none, a closed <details>) are deliberate, and
|
|
157
|
+
// so is one the article itself sizes to zero, like a tracking pixel.
|
|
158
|
+
collapsedImages: [...document.images]
|
|
159
|
+
.filter((image) => {
|
|
160
|
+
if (!image.complete || image.naturalWidth < 2 || image.naturalHeight < 2)
|
|
161
|
+
return false;
|
|
162
|
+
if (!image.getClientRects().length)
|
|
163
|
+
return false;
|
|
164
|
+
const zero = (value) => value !== null && /^\s*0(px)?\s*$/i.test(value);
|
|
165
|
+
if ([image.getAttribute("width"), image.getAttribute("height")].some(zero))
|
|
166
|
+
return false;
|
|
167
|
+
if ([image.style.width, image.style.height].some(zero))
|
|
168
|
+
return false;
|
|
169
|
+
const box = image.getBoundingClientRect();
|
|
170
|
+
return box.width < 1 || box.height < 1;
|
|
171
|
+
})
|
|
172
|
+
.map((image) => image.currentSrc || image.src),
|
|
152
173
|
};
|
|
153
174
|
}
|
|
154
175
|
/**
|
package/dist/commands/init.js
CHANGED
|
@@ -61,6 +61,23 @@ function updateReadme(root, name, creator, homepage) {
|
|
|
61
61
|
`A NetNewsWire theme by [${creator}](${homepage}).\n${IDENTITY_END}`;
|
|
62
62
|
writeFileSync(path, text.slice(0, start) + replacement + text.slice(end + IDENTITY_END.length), "utf8");
|
|
63
63
|
}
|
|
64
|
+
const TEMPLATE = "dave-atx/netnewswire-theme-template";
|
|
65
|
+
/** The theme root, or directions to create one: init starts from the template. */
|
|
66
|
+
function templateRoot() {
|
|
67
|
+
try {
|
|
68
|
+
return findRoot();
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (!(error instanceof ThemeError))
|
|
72
|
+
throw error;
|
|
73
|
+
throw new ThemeError("no theme repository here; init personalizes a copy of the theme template.\n" +
|
|
74
|
+
`Create one with "Use this template" at https://github.com/${TEMPLATE}, ` +
|
|
75
|
+
"clone it, and run init inside it. With the GitHub CLI:\n" +
|
|
76
|
+
` gh repo create my-theme --template ${TEMPLATE} --public --clone\n` +
|
|
77
|
+
" cd my-theme\n" +
|
|
78
|
+
" npx nnw-theme@1 init");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
64
81
|
async function ask(value, flag, label, fallback) {
|
|
65
82
|
if (value)
|
|
66
83
|
return value;
|
|
@@ -69,7 +86,7 @@ async function ask(value, flag, label, fallback) {
|
|
|
69
86
|
return await promptText(label, fallback);
|
|
70
87
|
}
|
|
71
88
|
export default async function init({ values }) {
|
|
72
|
-
const root =
|
|
89
|
+
const root = templateRoot();
|
|
73
90
|
let theme = findTheme(root);
|
|
74
91
|
if (!existsSync(join(root, PLACEHOLDER_MARKER))) {
|
|
75
92
|
throw new ThemeError("this repository is already initialized; run `npx nnw-theme@1 setup` to install preview tools");
|