@riebeckite/plugin-hover-preview 0.0.14 → 0.0.16

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/README.md CHANGED
@@ -76,4 +76,5 @@ hoverPreviewPlugin({
76
76
 
77
77
  ## See also
78
78
 
79
- - [Plugin guide](../../../docs/en/reference/plugin-api.md)
79
+ - [Plugin guide](../../../docs/en/docs/reference/plugin-api.md)
80
+
package/README_ja.md CHANGED
@@ -59,4 +59,5 @@ hoverPreviewPlugin({
59
59
 
60
60
  ## 関連資料
61
61
 
62
- - [プラグインシステム](../../../docs/ja/reference/plugin-api.md)
62
+ - [プラグインシステム](../../../docs/ja/docs/reference/plugin-api.md)
63
+
package/dist/client.js CHANGED
@@ -15,14 +15,14 @@ function initHoverPreview() {
15
15
  );
16
16
  if (!payload) return () => {
17
17
  };
18
- const index = parsePayload(payload.textContent);
19
- if (!index) return () => {
20
- };
21
18
  const config = {
22
19
  selector: normalizeSelector(payload.dataset.selector),
23
20
  className: normalizeClassName(payload.dataset.className),
24
21
  includeTitles: payload.dataset.includeTitles !== "false",
25
- delay: normalizeDelay(payload.dataset.delay)
22
+ delay: normalizeDelay(payload.dataset.delay),
23
+ indexSrc: normalizeIndexSrc(payload.dataset.indexSrc)
24
+ };
25
+ if (!config.indexSrc) return () => {
26
26
  };
27
27
  const anchors = Array.from(
28
28
  document.querySelectorAll(config.selector)
@@ -38,20 +38,31 @@ function initHoverPreview() {
38
38
  document.body.appendChild(popover);
39
39
  let showTimer = 0;
40
40
  let activeAnchor = null;
41
+ let indexPromise = null;
41
42
  const hide = () => {
42
43
  window.clearTimeout(showTimer);
43
44
  showTimer = 0;
44
45
  activeAnchor = null;
45
46
  popover.hidden = true;
46
47
  };
48
+ const loadIndex = () => {
49
+ indexPromise ??= fetch(config.indexSrc, {
50
+ headers: { Accept: "application/json" }
51
+ }).then((response) => response.ok ? response.text() : null).then(parsePayload).catch(() => null);
52
+ return indexPromise;
53
+ };
47
54
  const show = (anchor) => {
48
55
  window.clearTimeout(showTimer);
49
56
  showTimer = 0;
50
- const entry = resolveEntry(index, anchor.getAttribute("href"));
51
- if (!entry) return;
52
- renderPopover(popover, entry, config);
53
- popover.hidden = false;
54
- positionPopover(popover, anchor);
57
+ const href = anchor.getAttribute("href");
58
+ void loadIndex().then((index) => {
59
+ if (!index || activeAnchor !== anchor) return;
60
+ const entry = resolveEntry(index, href);
61
+ if (!entry) return;
62
+ renderPopover(popover, entry, config);
63
+ popover.hidden = false;
64
+ positionPopover(popover, anchor);
65
+ });
55
66
  activeAnchor = anchor;
56
67
  };
57
68
  const schedule = (anchor, delay) => {
@@ -168,6 +179,9 @@ function normalizeDelay(value) {
168
179
  const delay = Number(value ?? DEFAULT_DELAY);
169
180
  return Number.isFinite(delay) && delay >= 0 ? delay : DEFAULT_DELAY;
170
181
  }
182
+ function normalizeIndexSrc(value) {
183
+ return value && value.trim() !== "" ? value.trim() : "";
184
+ }
171
185
  export {
172
186
  initHoverPreview
173
187
  };
package/dist/index.js CHANGED
@@ -2,8 +2,7 @@
2
2
  import {
3
3
  createClientEntry,
4
4
  createStyleAsset,
5
- definePlugin,
6
- isPublishable
5
+ definePlugin
7
6
  } from "@riebeckite/core";
8
7
 
9
8
  // src/options.ts
@@ -66,20 +65,22 @@ function decodeHtmlEntities(value) {
66
65
  }
67
66
 
68
67
  // src/render.ts
69
- import { escapeHtmlAttribute, escapeScriptJson } from "@riebeckite/core";
68
+ import { escapeHtmlAttribute } from "@riebeckite/core";
70
69
  var HOVER_PREVIEW_SCRIPT_ID = "rb-hover-preview-data";
71
70
  var HOVER_PREVIEW_ATTRIBUTE = "data-rb-hover-preview";
72
- function renderHoverPreviewPayload(index, options) {
71
+ var HOVER_PREVIEW_INDEX_PATH = "_riebeckite/hover-preview/index.json";
72
+ function renderHoverPreviewPayload(options, indexUrl) {
73
73
  const attributes = [
74
74
  'type="application/json"',
75
75
  `id="${escapeHtmlAttribute(HOVER_PREVIEW_SCRIPT_ID)}"`,
76
76
  HOVER_PREVIEW_ATTRIBUTE,
77
+ `data-index-src="${escapeHtmlAttribute(indexUrl)}"`,
77
78
  `data-selector="${escapeHtmlAttribute(options.selector)}"`,
78
79
  `data-delay="${escapeHtmlAttribute(String(options.delay))}"`,
79
80
  `data-class-name="${escapeHtmlAttribute(options.className)}"`,
80
81
  `data-include-titles="${escapeHtmlAttribute(String(options.includeTitles))}"`
81
82
  ].join(" ");
82
- return `<script ${attributes}>${escapeScriptJson(JSON.stringify(index))}</script>`;
83
+ return `<script ${attributes}></script>`;
83
84
  }
84
85
  function hasInternalLink(html) {
85
86
  return /href\s*=\s*["']?\//.test(html);
@@ -87,26 +88,27 @@ function hasInternalLink(html) {
87
88
 
88
89
  // src/runtime.ts
89
90
  function createHoverPreviewRuntime(options) {
90
- const tracked = /* @__PURE__ */ new Map();
91
91
  return {
92
- track(slug, content) {
93
- tracked.set(slug, content);
94
- },
95
- inject(manifest, shouldInclude) {
92
+ inject(manifest, output, shouldInclude) {
96
93
  const entries = shouldInclude ? manifest.entries.filter(shouldInclude) : manifest.entries;
97
94
  const index = buildPreviewIndex(entries, {
98
95
  excerptLength: options.excerptLength,
99
96
  ...options.maxEntries === void 0 ? {} : { maxEntries: options.maxEntries }
100
97
  });
101
98
  if (Object.keys(index).length === 0) return;
102
- const payload = renderHoverPreviewPayload(index, options);
99
+ output.emit({
100
+ path: HOVER_PREVIEW_INDEX_PATH,
101
+ content: JSON.stringify(index),
102
+ dependencies: [{ type: "global" }]
103
+ });
104
+ const payload = renderHoverPreviewPayload(
105
+ options,
106
+ `/${HOVER_PREVIEW_INDEX_PATH}`
107
+ );
103
108
  for (const entry of entries) {
104
109
  if (!hasInternalLink(entry.html)) continue;
105
110
  if (entry.html.includes(HOVER_PREVIEW_ATTRIBUTE)) continue;
106
- const html = `${entry.html}${payload}`;
107
- entry.html = html;
108
- const content = tracked.get(entry.slug);
109
- if (content) content.html = html;
111
+ entry.html = `${entry.html}${payload}`;
110
112
  }
111
113
  }
112
114
  };
@@ -129,14 +131,14 @@ function initHoverPreview() {
129
131
  );
130
132
  if (!payload) return () => {
131
133
  };
132
- const index = parsePayload(payload.textContent);
133
- if (!index) return () => {
134
- };
135
134
  const config = {
136
135
  selector: normalizeSelector(payload.dataset.selector),
137
136
  className: normalizeClassName(payload.dataset.className),
138
137
  includeTitles: payload.dataset.includeTitles !== "false",
139
- delay: normalizeDelay(payload.dataset.delay)
138
+ delay: normalizeDelay(payload.dataset.delay),
139
+ indexSrc: normalizeIndexSrc(payload.dataset.indexSrc)
140
+ };
141
+ if (!config.indexSrc) return () => {
140
142
  };
141
143
  const anchors = Array.from(
142
144
  document.querySelectorAll(config.selector)
@@ -152,20 +154,31 @@ function initHoverPreview() {
152
154
  document.body.appendChild(popover);
153
155
  let showTimer = 0;
154
156
  let activeAnchor = null;
157
+ let indexPromise = null;
155
158
  const hide = () => {
156
159
  window.clearTimeout(showTimer);
157
160
  showTimer = 0;
158
161
  activeAnchor = null;
159
162
  popover.hidden = true;
160
163
  };
164
+ const loadIndex = () => {
165
+ indexPromise ??= fetch(config.indexSrc, {
166
+ headers: { Accept: "application/json" }
167
+ }).then((response) => response.ok ? response.text() : null).then(parsePayload).catch(() => null);
168
+ return indexPromise;
169
+ };
161
170
  const show = (anchor) => {
162
171
  window.clearTimeout(showTimer);
163
172
  showTimer = 0;
164
- const entry = resolveEntry(index, anchor.getAttribute("href"));
165
- if (!entry) return;
166
- renderPopover(popover, entry, config);
167
- popover.hidden = false;
168
- positionPopover(popover, anchor);
173
+ const href = anchor.getAttribute("href");
174
+ void loadIndex().then((index) => {
175
+ if (!index || activeAnchor !== anchor) return;
176
+ const entry = resolveEntry(index, href);
177
+ if (!entry) return;
178
+ renderPopover(popover, entry, config);
179
+ popover.hidden = false;
180
+ positionPopover(popover, anchor);
181
+ });
169
182
  activeAnchor = anchor;
170
183
  };
171
184
  const schedule = (anchor, delay) => {
@@ -282,6 +295,9 @@ function normalizeDelay(value) {
282
295
  const delay = Number(value ?? DEFAULT_DELAY);
283
296
  return Number.isFinite(delay) && delay >= 0 ? delay : DEFAULT_DELAY;
284
297
  }
298
+ function normalizeIndexSrc(value) {
299
+ return value && value.trim() !== "" ? value.trim() : "";
300
+ }
285
301
 
286
302
  // index.ts
287
303
  function hoverPreviewPlugin(options = {}) {
@@ -289,16 +305,19 @@ function hoverPreviewPlugin(options = {}) {
289
305
  const runtime = createHoverPreviewRuntime(resolved);
290
306
  return definePlugin({
291
307
  name: "hover-preview",
308
+ processedContentCache: {
309
+ version: "hover-preview-v1",
310
+ dependencyMode: "none"
311
+ },
312
+ outputDependencies: [{ type: "global" }],
292
313
  options,
293
314
  validateOptions: validateHoverPreviewOptions,
294
- onPostProcessed: (context) => {
295
- runtime.track(context.slug, context.content);
296
- },
297
315
  onManifestCreated: (context) => {
298
- const strategy = context.config?.content.filters.publishStrategy ?? "explicit";
316
+ const publicEntries = new Set(context.manifest.publicEntries);
299
317
  runtime.inject(
300
318
  context.manifest,
301
- (entry) => isPublishable(strategy, entry.frontmatter)
319
+ context.output,
320
+ (entry) => publicEntries.has(entry)
302
321
  );
303
322
  },
304
323
  assets: [createStyleAsset("hover-preview")],
@@ -1,5 +1,6 @@
1
- import type { HoverPreviewIndex, ResolvedHoverPreviewOptions } from "./types.js";
1
+ import type { ResolvedHoverPreviewOptions } from "./types.js";
2
2
  export declare const HOVER_PREVIEW_SCRIPT_ID = "rb-hover-preview-data";
3
3
  export declare const HOVER_PREVIEW_ATTRIBUTE = "data-rb-hover-preview";
4
- export declare function renderHoverPreviewPayload(index: HoverPreviewIndex, options: ResolvedHoverPreviewOptions): string;
4
+ export declare const HOVER_PREVIEW_INDEX_PATH = "_riebeckite/hover-preview/index.json";
5
+ export declare function renderHoverPreviewPayload(options: ResolvedHoverPreviewOptions, indexUrl: string): string;
5
6
  export declare function hasInternalLink(html: string): boolean;
@@ -1,7 +1,6 @@
1
- import type { ContentManifest, ContentManifestEntry, PostContent } from "@riebeckite/core";
1
+ import type { ContentManifest, ContentManifestEntry, GeneratedOutputSink } from "@riebeckite/core";
2
2
  import type { ResolvedHoverPreviewOptions } from "./types.js";
3
3
  export type HoverPreviewRuntime = {
4
- track(slug: string, content: PostContent): void;
5
- inject(manifest: ContentManifest, shouldInclude?: (entry: ContentManifestEntry) => boolean): void;
4
+ inject(manifest: ContentManifest, output: GeneratedOutputSink, shouldInclude?: (entry: ContentManifestEntry) => boolean): void;
6
5
  };
7
6
  export declare function createHoverPreviewRuntime(options: ResolvedHoverPreviewOptions): HoverPreviewRuntime;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riebeckite/plugin-hover-preview",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,7 +21,7 @@
21
21
  "./style.css": "./style.css"
22
22
  },
23
23
  "dependencies": {
24
- "@riebeckite/core": "0.0.14"
24
+ "@riebeckite/core": "0.0.16"
25
25
  },
26
26
  "publishConfig": {
27
27
  "access": "public"