koishi-plugin-fimtale-api 1.0.1 → 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.
Files changed (2) hide show
  1. package/lib/index.js +39 -8
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -85,15 +85,18 @@ function apply(ctx, config) {
85
85
  processed = processed.replace(/<script\b[^>]*>([\s\S]*?)<\/script>/gmi, "");
86
86
  processed = processed.replace(/<style\b[^>]*>([\s\S]*?)<\/style>/gmi, "");
87
87
  processed = processed.replace(/<iframe[^>]*>.*?<\/iframe>/gmi, '<p class="align-center" style="color:#999;font-size:0.8em;">[多媒体内容]</p>');
88
+ processed = processed.replace(
89
+ /<div class="material-placeholder">([\s\S]*?)<\/div>/gi,
90
+ (match, content) => {
91
+ const cleanImg = content.replace(/loading="lazy"/gi, "");
92
+ return `<figure class="img-box">${cleanImg}</figure>`;
93
+ }
94
+ );
88
95
  processed = processed.replace(/<p[^>]*style="[^"]*text-align:\s*right[^"]*"[^>]*>/gi, '<p class="align-right">');
89
96
  processed = processed.replace(/<p[^>]*style="[^"]*text-align:\s*center[^"]*"[^>]*>/gi, '<p class="align-center">');
90
97
  processed = processed.replace(/<p[^>]*style="[^"]*text-indent:\s*0[^"]*"[^>]*>/gi, '<p class="no-indent">');
91
- processed = processed.replace(/<div class="material-placeholder">/gi, '<div class="img-box">');
98
+ processed = processed.replace(/<\/?div[^>]*>/gi, "");
92
99
  processed = processed.replace(/<blockquote[^>]*>/gi, "<blockquote>");
93
- processed = processed.replace(/<div(?![^>]*class=["']img-box["'])[^>]*>/gi, "<p>");
94
- processed = processed.replace(/<\/div>/gi, (match, offset, string) => {
95
- return "</div>";
96
- });
97
100
  processed = processed.replace(/class=(["'])(?!(align-center|align-right|no-indent|img-box)\1)[^"']*\1/gi, "");
98
101
  processed = processed.replace(/style\s*=\s*['"][^'"]*['"]/gi, "");
99
102
  processed = processed.replace(/<\/?(span|font|o:p)[^>]*>/gi, "");
@@ -292,7 +295,15 @@ function apply(ctx, config) {
292
295
  .fixed-header { position: absolute; top: 0; left: 0; width: 100%; height: ${headerHeight}px; border-bottom: 1px solid #d7ccc8; box-sizing: border-box; padding: 0 20px; display: flex; align-items: center; justify-content: space-between; font-size: 12px; color: #8d6e63; background: #f6f4ec; z-index: 5; font-weight: bold; }
293
296
  .fixed-footer { position: absolute; bottom: 0; left: 0; width: 100%; height: ${footerHeight}px; display: flex; align-items: center; justify-content: center; font-size: 12px; color: #aaa; background: #f6f4ec; z-index: 5; }
294
297
  #viewport { position: absolute; top: ${marginTop}px; left: ${paddingX}px; width: ${contentWidth}px; height: ${optimalContentHeight}px; overflow: hidden; }
295
- #content-scroller { height: 100%; width: 100%; column-width: ${contentWidth}px; column-gap: ${columnGap}px; column-fill: auto; padding: ${paddingY}px 0; box-sizing: border-box; font-size: ${config.fontSize}px; line-height: ${lineHeightRatio}; text-align: left; transform: translateX(0); transition: none; }
298
+
299
+ #content-scroller {
300
+ height: 100%; width: 100%;
301
+ column-width: ${contentWidth}px; column-gap: ${columnGap}px; column-fill: auto;
302
+ padding: ${paddingY}px 0; box-sizing: border-box;
303
+ font-size: ${config.fontSize}px; line-height: ${lineHeightRatio};
304
+ text-align: left; /* 修正:左对齐防止空格拉伸 */
305
+ transform: translateX(0); transition: none;
306
+ }
296
307
 
297
308
  /* 基础文本 */
298
309
  p, div { margin: 0 0 0.2em 0; text-indent: 2em; word-wrap: break-word; overflow-wrap: break-word; }
@@ -326,8 +337,8 @@ function apply(ctx, config) {
326
337
 
327
338
  a { color: #0277bd; text-decoration: none; }
328
339
 
329
- /* 图片 */
330
- .img-box { display: flex; justify-content: center; align-items: center; margin: 0.5em 0; width: 100%; }
340
+ /* 图片 (使用 figure 替代 div) */
341
+ figure.img-box { display: flex; justify-content: center; align-items: center; margin: 0.5em 0; width: 100%; }
331
342
  img { max-width: 100%; height: auto; display: block; border-radius: 6px; box-shadow: 0 2px 6px rgba(0,0,0,0.1); }
332
343
 
333
344
  /* 标题 */
@@ -346,6 +357,26 @@ function apply(ctx, config) {
346
357
  await injectCookies(page);
347
358
  await page.setContent(html);
348
359
  await page.setViewport({ width: config.deviceWidth, height: config.deviceHeight, deviceScaleFactor: 2 });
360
+ await page.evaluate(async () => {
361
+ await document.fonts.ready;
362
+ await new Promise((resolve) => {
363
+ const imgs2 = Array.from(document.images);
364
+ if (!imgs2.length) return resolve(true);
365
+ let loaded = 0;
366
+ imgs2.forEach((img) => {
367
+ if (img.complete) {
368
+ loaded++;
369
+ if (loaded === imgs2.length) resolve(true);
370
+ } else {
371
+ img.onload = img.onerror = () => {
372
+ loaded++;
373
+ if (loaded === imgs2.length) resolve(true);
374
+ };
375
+ }
376
+ });
377
+ setTimeout(resolve, 3e3);
378
+ });
379
+ });
349
380
  const scrollWidth = await page.$eval("#content-scroller", (el) => el.scrollWidth);
350
381
  const step = contentWidth + columnGap;
351
382
  const totalPages = Math.floor((scrollWidth + columnGap - 10) / step) + 1;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-fimtale-api",
3
3
  "description": "Koishi插件,从fimtale搜索/订阅/随机获取小说/解析链接等",
4
- "version": "1.0.1",
4
+ "version": "1.0.2",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [