@analogjs/content 3.0.0-alpha.10 → 3.0.0-alpha.12
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/fesm2022/analogjs-content-md4x.mjs +290 -0
- package/fesm2022/analogjs-content-mdc.mjs +170 -0
- package/fesm2022/analogjs-content.mjs +158 -281
- package/fesm2022/content-list-loader.mjs +284 -0
- package/md4x/package.json +4 -0
- package/mdc/package.json +4 -0
- package/package.json +16 -2
- package/src/lib/devtools/content-devtools-client.ts +215 -0
- package/src/lib/devtools/content-devtools.styles.css +194 -0
- package/types/md4x/src/index.d.ts +5 -0
- package/types/md4x/src/lib/md4x-content-renderer.service.d.ts +33 -0
- package/types/md4x/src/lib/md4x-wasm-content-renderer.service.d.ts +16 -0
- package/types/md4x/src/lib/provide-md4x.d.ts +26 -0
- package/types/md4x/src/lib/streaming-markdown-renderer.d.ts +21 -0
- package/types/mdc/src/index.d.ts +2 -0
- package/types/mdc/src/lib/mdc-component-registry.d.ts +25 -0
- package/types/mdc/src/lib/mdc-renderer.directive.d.ts +33 -0
- package/types/src/index.d.ts +2 -0
- package/types/src/lib/devtools/content-devtools-plugin.d.ts +23 -0
- package/types/src/lib/devtools/content-devtools-renderer.d.ts +23 -0
- package/types/src/lib/devtools/index.d.ts +23 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { a as injectContentFileLoader, c as injectContentFilesMap, d as ContentRenderer, f as NoopContentRenderer, i as CONTENT_FILE_LOADER, l as RenderTaskService, n as injectContentListLoader, o as withContentFileLoader, r as withContentListLoader, s as injectContentFiles, t as CONTENT_LIST_LOADER, u as CONTENT_FILES_TOKEN } from "./content-list-loader.mjs";
|
|
1
2
|
import * as i0 from "@angular/core";
|
|
2
|
-
import { Component, Directive, HostListener, Injectable, InjectionToken, Input, NgZone, PLATFORM_ID,
|
|
3
|
+
import { Component, Directive, HostListener, Injectable, InjectionToken, Input, NgZone, PLATFORM_ID, ViewEncapsulation, computed, inject, input } from "@angular/core";
|
|
3
4
|
import { DOCUMENT, Location, isPlatformBrowser } from "@angular/common";
|
|
4
5
|
import { ActivatedRoute, Router } from "@angular/router";
|
|
5
6
|
import { Observable, from, of } from "rxjs";
|
|
@@ -10,6 +11,10 @@ import { marked } from "marked";
|
|
|
10
11
|
import { mangle } from "marked-mangle";
|
|
11
12
|
import { DomSanitizer } from "@angular/platform-browser";
|
|
12
13
|
import { takeUntilDestroyed, toSignal } from "@angular/core/rxjs-interop";
|
|
14
|
+
import { transformWithOxc } from "vite";
|
|
15
|
+
//#region \0rolldown/runtime.js
|
|
16
|
+
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
17
|
+
//#endregion
|
|
13
18
|
//#region packages/content/src/lib/anchor-navigation.directive.ts
|
|
14
19
|
var AnchorNavigationDirective = class AnchorNavigationDirective {
|
|
15
20
|
constructor() {
|
|
@@ -75,207 +80,6 @@ function isInternalUrl(anchorElement, document) {
|
|
|
75
80
|
return anchorElement.host === document.location.host && anchorElement.protocol === document.location.protocol;
|
|
76
81
|
}
|
|
77
82
|
//#endregion
|
|
78
|
-
//#region packages/content/src/lib/content-renderer.ts
|
|
79
|
-
var ContentRenderer = class ContentRenderer {
|
|
80
|
-
async render(content) {
|
|
81
|
-
return {
|
|
82
|
-
content,
|
|
83
|
-
toc: []
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
getContentHeadings(_content) {
|
|
87
|
-
return [];
|
|
88
|
-
}
|
|
89
|
-
enhance() {}
|
|
90
|
-
static {
|
|
91
|
-
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
92
|
-
minVersion: "12.0.0",
|
|
93
|
-
version: "21.1.1",
|
|
94
|
-
ngImport: i0,
|
|
95
|
-
type: ContentRenderer,
|
|
96
|
-
deps: [],
|
|
97
|
-
target: i0.ɵɵFactoryTarget.Injectable
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
static {
|
|
101
|
-
this.ɵprov = i0.ɵɵngDeclareInjectable({
|
|
102
|
-
minVersion: "12.0.0",
|
|
103
|
-
version: "21.1.1",
|
|
104
|
-
ngImport: i0,
|
|
105
|
-
type: ContentRenderer
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
i0.ɵɵngDeclareClassMetadata({
|
|
110
|
-
minVersion: "12.0.0",
|
|
111
|
-
version: "21.1.1",
|
|
112
|
-
ngImport: i0,
|
|
113
|
-
type: ContentRenderer,
|
|
114
|
-
decorators: [{ type: Injectable }]
|
|
115
|
-
});
|
|
116
|
-
var NoopContentRenderer = class {
|
|
117
|
-
constructor() {
|
|
118
|
-
this.transferState = inject(TransferState);
|
|
119
|
-
this.contentId = 0;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Generates a hash from the content string
|
|
123
|
-
* to be used with the transfer state
|
|
124
|
-
*/
|
|
125
|
-
generateHash(str) {
|
|
126
|
-
let hash = 0;
|
|
127
|
-
for (let i = 0, len = str.length; i < len; i++) {
|
|
128
|
-
const chr = str.charCodeAt(i);
|
|
129
|
-
hash = (hash << 5) - hash + chr;
|
|
130
|
-
hash |= 0;
|
|
131
|
-
}
|
|
132
|
-
return hash;
|
|
133
|
-
}
|
|
134
|
-
async render(content) {
|
|
135
|
-
this.contentId = this.generateHash(content);
|
|
136
|
-
const toc = this.getContentHeadings(content);
|
|
137
|
-
const key = makeStateKey(`content-headings-${this.contentId}`);
|
|
138
|
-
return {
|
|
139
|
-
content,
|
|
140
|
-
toc: this.transferState.get(key, toc)
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
enhance() {}
|
|
144
|
-
getContentHeadings(content) {
|
|
145
|
-
return this.extractHeadings(content);
|
|
146
|
-
}
|
|
147
|
-
extractHeadings(content) {
|
|
148
|
-
const markdownHeadings = this.extractHeadingsFromMarkdown(content);
|
|
149
|
-
if (markdownHeadings.length > 0) return markdownHeadings;
|
|
150
|
-
return this.extractHeadingsFromHtml(content);
|
|
151
|
-
}
|
|
152
|
-
extractHeadingsFromMarkdown(content) {
|
|
153
|
-
const lines = content.split("\n");
|
|
154
|
-
const toc = [];
|
|
155
|
-
const slugCounts = /* @__PURE__ */ new Map();
|
|
156
|
-
for (const line of lines) {
|
|
157
|
-
const match = /^(#{1,6})\s+(.+?)\s*$/.exec(line);
|
|
158
|
-
if (!match) continue;
|
|
159
|
-
const level = match[1].length;
|
|
160
|
-
const text = match[2].trim();
|
|
161
|
-
if (!text) continue;
|
|
162
|
-
const baseSlug = text.toLowerCase().replace(/[^\w\s-]/g, "").trim().replace(/\s+/g, "-");
|
|
163
|
-
const count = slugCounts.get(baseSlug) ?? 0;
|
|
164
|
-
slugCounts.set(baseSlug, count + 1);
|
|
165
|
-
const id = count === 0 ? baseSlug : `${baseSlug}-${count}`;
|
|
166
|
-
toc.push({
|
|
167
|
-
id,
|
|
168
|
-
level,
|
|
169
|
-
text
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
return toc;
|
|
173
|
-
}
|
|
174
|
-
extractHeadingsFromHtml(content) {
|
|
175
|
-
const toc = [];
|
|
176
|
-
const slugCounts = /* @__PURE__ */ new Map();
|
|
177
|
-
for (const match of content.matchAll(/<h([1-6])([^>]*)>([\s\S]*?)<\/h\1>/gi)) {
|
|
178
|
-
const level = Number(match[1]);
|
|
179
|
-
const attrs = match[2] ?? "";
|
|
180
|
-
const text = (match[3] ?? "").replace(/<[^>]+>/g, "").trim();
|
|
181
|
-
if (!text) continue;
|
|
182
|
-
const idMatch = /\sid=(['"])(.*?)\1/i.exec(attrs) ?? /\sid=([^\s>]+)/i.exec(attrs);
|
|
183
|
-
let id = idMatch?.[2] ?? idMatch?.[1] ?? "";
|
|
184
|
-
if (!id) id = this.makeSlug(text, slugCounts);
|
|
185
|
-
toc.push({
|
|
186
|
-
id,
|
|
187
|
-
level,
|
|
188
|
-
text
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
return toc;
|
|
192
|
-
}
|
|
193
|
-
makeSlug(text, slugCounts) {
|
|
194
|
-
const baseSlug = text.toLowerCase().replace(/[^\w\s-]/g, "").trim().replace(/\s+/g, "-");
|
|
195
|
-
const count = slugCounts.get(baseSlug) ?? 0;
|
|
196
|
-
slugCounts.set(baseSlug, count + 1);
|
|
197
|
-
return count === 0 ? baseSlug : `${baseSlug}-${count}`;
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
//#endregion
|
|
201
|
-
//#region packages/content/src/lib/get-content-files.ts
|
|
202
|
-
/**
|
|
203
|
-
* Returns the list of content files by filename with ?analog-content-list=true.
|
|
204
|
-
* We use the query param to transform the return into an array of
|
|
205
|
-
* just front matter attributes.
|
|
206
|
-
*
|
|
207
|
-
* @returns
|
|
208
|
-
*/
|
|
209
|
-
var getContentFilesList = () => {
|
|
210
|
-
return {};
|
|
211
|
-
};
|
|
212
|
-
/**
|
|
213
|
-
* Returns the lazy loaded content files for lookups.
|
|
214
|
-
*
|
|
215
|
-
* @returns
|
|
216
|
-
*/
|
|
217
|
-
var getContentFiles = () => {
|
|
218
|
-
return {};
|
|
219
|
-
};
|
|
220
|
-
//#endregion
|
|
221
|
-
//#region packages/content/src/lib/content-files-list-token.ts
|
|
222
|
-
function getSlug(filename) {
|
|
223
|
-
const base = (filename.split(/[/\\]/).pop() || "").trim().replace(/\.[^./\\]+$/, "");
|
|
224
|
-
return base === "index" ? "" : base;
|
|
225
|
-
}
|
|
226
|
-
var CONTENT_FILES_LIST_TOKEN = new InjectionToken("@analogjs/content Content Files List", {
|
|
227
|
-
providedIn: "root",
|
|
228
|
-
factory() {
|
|
229
|
-
const contentFiles = getContentFilesList();
|
|
230
|
-
return Object.keys(contentFiles).map((filename) => {
|
|
231
|
-
const attributes = contentFiles[filename];
|
|
232
|
-
const slug = attributes["slug"];
|
|
233
|
-
return {
|
|
234
|
-
filename,
|
|
235
|
-
attributes,
|
|
236
|
-
slug: slug ? encodeURI(slug) : encodeURI(getSlug(filename))
|
|
237
|
-
};
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
//#endregion
|
|
242
|
-
//#region packages/content/src/lib/content-files-token.ts
|
|
243
|
-
var CONTENT_FILES_TOKEN = new InjectionToken("@analogjs/content Content Files", {
|
|
244
|
-
providedIn: "root",
|
|
245
|
-
factory() {
|
|
246
|
-
const allFiles = { ...getContentFiles() };
|
|
247
|
-
const contentFilesList = inject(CONTENT_FILES_LIST_TOKEN);
|
|
248
|
-
const lookup = {};
|
|
249
|
-
contentFilesList.forEach((item) => {
|
|
250
|
-
const contentFilename = item.filename.replace(/(.*?)\/content/, "/src/content");
|
|
251
|
-
const fileParts = contentFilename.split("/");
|
|
252
|
-
const filePath = fileParts.slice(0, fileParts.length - 1).join("/");
|
|
253
|
-
const fileNameParts = fileParts[fileParts.length - 1].split(".");
|
|
254
|
-
const ext = fileNameParts[fileNameParts.length - 1];
|
|
255
|
-
let slug = item.slug ?? "";
|
|
256
|
-
if (slug === "") slug = "index";
|
|
257
|
-
lookup[contentFilename] = `${slug.includes("/") ? `/src/content/${slug}` : `${filePath}/${slug}`}.${ext}`.replace(/\/{2,}/g, "/");
|
|
258
|
-
});
|
|
259
|
-
const objectUsingSlugAttribute = {};
|
|
260
|
-
Object.entries(allFiles).forEach((entry) => {
|
|
261
|
-
const filename = entry[0];
|
|
262
|
-
const value = entry[1];
|
|
263
|
-
const newFilename = lookup[filename.replace(/^\/(.*?)\/content/, "/src/content")];
|
|
264
|
-
if (newFilename !== void 0) {
|
|
265
|
-
const objectFilename = newFilename.replace(/^\/(.*?)\/content/, "/src/content");
|
|
266
|
-
objectUsingSlugAttribute[objectFilename] = value;
|
|
267
|
-
}
|
|
268
|
-
});
|
|
269
|
-
return objectUsingSlugAttribute;
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
new InjectionToken("@analogjs/content Content Files", {
|
|
273
|
-
providedIn: "root",
|
|
274
|
-
factory() {
|
|
275
|
-
return signal(inject(CONTENT_FILES_TOKEN));
|
|
276
|
-
}
|
|
277
|
-
});
|
|
278
|
-
//#endregion
|
|
279
83
|
//#region packages/content/src/lib/parse-raw-content-file.ts
|
|
280
84
|
var FrontmatterValidationError = class extends Error {
|
|
281
85
|
constructor(issues, filename) {
|
|
@@ -317,43 +121,6 @@ async function parseRawContentFileAsync(rawContentFile, schema, filename) {
|
|
|
317
121
|
};
|
|
318
122
|
}
|
|
319
123
|
//#endregion
|
|
320
|
-
//#region packages/content/src/lib/render-task.service.ts
|
|
321
|
-
var RenderTaskService = class RenderTaskService {
|
|
322
|
-
#pendingTasks = inject(ɵPendingTasksInternal);
|
|
323
|
-
addRenderTask() {
|
|
324
|
-
return this.#pendingTasks.add();
|
|
325
|
-
}
|
|
326
|
-
clearRenderTask(clear) {
|
|
327
|
-
if (typeof clear === "function") clear();
|
|
328
|
-
else if (typeof this.#pendingTasks.remove === "function") this.#pendingTasks.remove(clear);
|
|
329
|
-
}
|
|
330
|
-
static {
|
|
331
|
-
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
332
|
-
minVersion: "12.0.0",
|
|
333
|
-
version: "21.1.1",
|
|
334
|
-
ngImport: i0,
|
|
335
|
-
type: RenderTaskService,
|
|
336
|
-
deps: [],
|
|
337
|
-
target: i0.ɵɵFactoryTarget.Injectable
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
static {
|
|
341
|
-
this.ɵprov = i0.ɵɵngDeclareInjectable({
|
|
342
|
-
minVersion: "12.0.0",
|
|
343
|
-
version: "21.1.1",
|
|
344
|
-
ngImport: i0,
|
|
345
|
-
type: RenderTaskService
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
};
|
|
349
|
-
i0.ɵɵngDeclareClassMetadata({
|
|
350
|
-
minVersion: "12.0.0",
|
|
351
|
-
version: "21.1.1",
|
|
352
|
-
ngImport: i0,
|
|
353
|
-
type: RenderTaskService,
|
|
354
|
-
decorators: [{ type: Injectable }]
|
|
355
|
-
});
|
|
356
|
-
//#endregion
|
|
357
124
|
//#region packages/content/src/lib/content.ts
|
|
358
125
|
function getContentFile(contentFiles, prefix, slug, fallback, renderTaskService, contentRenderer) {
|
|
359
126
|
const normalizedFiles = {};
|
|
@@ -431,19 +198,6 @@ function injectContent(param = "slug", fallback = "No Content Found") {
|
|
|
431
198
|
} else return getContentFile(contentFiles, "", param.customFilename, fallback, renderTaskService, contentRenderer).pipe(tap(() => renderTaskService.clearRenderTask(task)));
|
|
432
199
|
}
|
|
433
200
|
//#endregion
|
|
434
|
-
//#region packages/content/src/lib/inject-content-files.ts
|
|
435
|
-
function injectContentFiles(filterFn) {
|
|
436
|
-
const renderTaskService = inject(RenderTaskService);
|
|
437
|
-
const task = renderTaskService.addRenderTask();
|
|
438
|
-
const allContentFiles = inject(CONTENT_FILES_LIST_TOKEN);
|
|
439
|
-
renderTaskService.clearRenderTask(task);
|
|
440
|
-
if (filterFn) return allContentFiles.filter(filterFn);
|
|
441
|
-
return allContentFiles;
|
|
442
|
-
}
|
|
443
|
-
function injectContentFilesMap() {
|
|
444
|
-
return inject(CONTENT_FILES_TOKEN);
|
|
445
|
-
}
|
|
446
|
-
//#endregion
|
|
447
201
|
//#region packages/content/src/lib/marked-content-highlighter.ts
|
|
448
202
|
var MarkedContentHighlighter = class MarkedContentHighlighter {
|
|
449
203
|
static {
|
|
@@ -579,34 +333,6 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
579
333
|
decorators: [{ type: Injectable }]
|
|
580
334
|
});
|
|
581
335
|
//#endregion
|
|
582
|
-
//#region packages/content/src/lib/content-file-loader.ts
|
|
583
|
-
var CONTENT_FILE_LOADER = new InjectionToken("@analogjs/content/resource File Loader");
|
|
584
|
-
function injectContentFileLoader() {
|
|
585
|
-
return inject(CONTENT_FILE_LOADER);
|
|
586
|
-
}
|
|
587
|
-
function withContentFileLoader() {
|
|
588
|
-
return {
|
|
589
|
-
provide: CONTENT_FILE_LOADER,
|
|
590
|
-
useFactory() {
|
|
591
|
-
return async () => injectContentFilesMap();
|
|
592
|
-
}
|
|
593
|
-
};
|
|
594
|
-
}
|
|
595
|
-
//#endregion
|
|
596
|
-
//#region packages/content/src/lib/content-list-loader.ts
|
|
597
|
-
var CONTENT_LIST_LOADER = new InjectionToken("@analogjs/content/resource List Loader");
|
|
598
|
-
function injectContentListLoader() {
|
|
599
|
-
return inject(CONTENT_LIST_LOADER);
|
|
600
|
-
}
|
|
601
|
-
function withContentListLoader() {
|
|
602
|
-
return {
|
|
603
|
-
provide: CONTENT_LIST_LOADER,
|
|
604
|
-
useFactory() {
|
|
605
|
-
return async () => injectContentFiles();
|
|
606
|
-
}
|
|
607
|
-
};
|
|
608
|
-
}
|
|
609
|
-
//#endregion
|
|
610
336
|
//#region packages/content/src/lib/provide-content.ts
|
|
611
337
|
var CONTENT_RENDERER_PROVIDERS = [
|
|
612
338
|
{
|
|
@@ -804,6 +530,157 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
804
530
|
}
|
|
805
531
|
});
|
|
806
532
|
//#endregion
|
|
807
|
-
|
|
533
|
+
//#region packages/content/src/lib/devtools/content-devtools-renderer.ts
|
|
534
|
+
/**
|
|
535
|
+
* Token for the wrapped renderer that DevTools delegates to.
|
|
536
|
+
* @internal
|
|
537
|
+
*/
|
|
538
|
+
var DEVTOOLS_INNER_RENDERER = new InjectionToken("devtools_inner_renderer");
|
|
539
|
+
/**
|
|
540
|
+
* Wraps an existing ContentRenderer to collect timing and metadata for the
|
|
541
|
+
* Content DevTools panel. Dispatches a custom event on the window after
|
|
542
|
+
* each render so the devtools client can update.
|
|
543
|
+
*
|
|
544
|
+
* @experimental Content DevTools is experimental and may change in future releases.
|
|
545
|
+
*/
|
|
546
|
+
var DevToolsContentRenderer = class DevToolsContentRenderer extends ContentRenderer {
|
|
547
|
+
constructor() {
|
|
548
|
+
super(...arguments);
|
|
549
|
+
this.inner = inject(DEVTOOLS_INNER_RENDERER);
|
|
550
|
+
}
|
|
551
|
+
async render(content) {
|
|
552
|
+
const start = performance.now();
|
|
553
|
+
const result = await this.inner.render(content);
|
|
554
|
+
const elapsed = performance.now() - start;
|
|
555
|
+
if (typeof window !== "undefined") window.dispatchEvent(new CustomEvent("analog-content-devtools-data", { detail: {
|
|
556
|
+
renderer: this.inner.constructor.name,
|
|
557
|
+
renderTimeMs: elapsed,
|
|
558
|
+
toc: result.toc,
|
|
559
|
+
contentLength: content.length,
|
|
560
|
+
headingCount: result.toc.length
|
|
561
|
+
} }));
|
|
562
|
+
return result;
|
|
563
|
+
}
|
|
564
|
+
getContentHeadings(content) {
|
|
565
|
+
return this.inner.getContentHeadings(content);
|
|
566
|
+
}
|
|
567
|
+
enhance() {
|
|
568
|
+
this.inner.enhance();
|
|
569
|
+
}
|
|
570
|
+
static {
|
|
571
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
572
|
+
minVersion: "12.0.0",
|
|
573
|
+
version: "21.1.1",
|
|
574
|
+
ngImport: i0,
|
|
575
|
+
type: DevToolsContentRenderer,
|
|
576
|
+
deps: null,
|
|
577
|
+
target: i0.ɵɵFactoryTarget.Injectable
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
static {
|
|
581
|
+
this.ɵprov = i0.ɵɵngDeclareInjectable({
|
|
582
|
+
minVersion: "12.0.0",
|
|
583
|
+
version: "21.1.1",
|
|
584
|
+
ngImport: i0,
|
|
585
|
+
type: DevToolsContentRenderer
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
590
|
+
minVersion: "12.0.0",
|
|
591
|
+
version: "21.1.1",
|
|
592
|
+
ngImport: i0,
|
|
593
|
+
type: DevToolsContentRenderer,
|
|
594
|
+
decorators: [{ type: Injectable }]
|
|
595
|
+
});
|
|
596
|
+
//#endregion
|
|
597
|
+
//#region packages/content/src/lib/devtools/content-devtools-plugin.ts
|
|
598
|
+
var import___vite_browser_external = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
599
|
+
module.exports = {};
|
|
600
|
+
})))();
|
|
601
|
+
/**
|
|
602
|
+
* Vite plugin that injects the Analog Content DevTools panel in dev mode.
|
|
603
|
+
*
|
|
604
|
+
* Shows render time, frontmatter data, TOC, and content stats in a floating
|
|
605
|
+
* panel. Dev-only — completely stripped from production builds.
|
|
606
|
+
*
|
|
607
|
+
* @experimental Content DevTools is experimental and may change in future releases.
|
|
608
|
+
*
|
|
609
|
+
* @example
|
|
610
|
+
* ```typescript
|
|
611
|
+
* // vite.config.ts
|
|
612
|
+
* import { contentDevToolsPlugin } from '@analogjs/content/devtools';
|
|
613
|
+
*
|
|
614
|
+
* export default defineConfig({
|
|
615
|
+
* plugins: [
|
|
616
|
+
* analog({ ... }),
|
|
617
|
+
* contentDevToolsPlugin(),
|
|
618
|
+
* ],
|
|
619
|
+
* });
|
|
620
|
+
* ```
|
|
621
|
+
*/
|
|
622
|
+
function contentDevToolsPlugin() {
|
|
623
|
+
let isDev = false;
|
|
624
|
+
return {
|
|
625
|
+
name: "analog-content-devtools",
|
|
626
|
+
apply: "serve",
|
|
627
|
+
configResolved(config) {
|
|
628
|
+
isDev = config.command === "serve";
|
|
629
|
+
},
|
|
630
|
+
transformIndexHtml: {
|
|
631
|
+
order: "post",
|
|
632
|
+
async handler(html) {
|
|
633
|
+
if (!isDev) return html;
|
|
634
|
+
const pluginDir = (0, import___vite_browser_external.dirname)((0, import___vite_browser_external.fileURLToPath)(import.meta.url));
|
|
635
|
+
const cssPath = (0, import___vite_browser_external.resolve)(pluginDir, "content-devtools.styles.css");
|
|
636
|
+
const clientPath = (0, import___vite_browser_external.resolve)(pluginDir, "content-devtools-client.ts");
|
|
637
|
+
let css;
|
|
638
|
+
let clientCode;
|
|
639
|
+
try {
|
|
640
|
+
css = (0, import___vite_browser_external.readFileSync)(cssPath, "utf-8");
|
|
641
|
+
clientCode = (0, import___vite_browser_external.readFileSync)(clientPath, "utf-8");
|
|
642
|
+
} catch {
|
|
643
|
+
return html;
|
|
644
|
+
}
|
|
645
|
+
const transformResult = await transformWithOxc(clientCode, "content-devtools-client.ts", { lang: "ts" });
|
|
646
|
+
const injection = `
|
|
647
|
+
<style>${css}</style>
|
|
648
|
+
<script type="module">${transformResult.code}<\/script>`;
|
|
649
|
+
return html.replace("</body>", `${injection}\n</body>`);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
//#endregion
|
|
655
|
+
//#region packages/content/src/lib/devtools/index.ts
|
|
656
|
+
/**
|
|
657
|
+
* Wraps the given ContentRenderer with DevTools instrumentation.
|
|
658
|
+
*
|
|
659
|
+
* The supplied renderer class is provided under DEVTOOLS_INNER_RENDERER and
|
|
660
|
+
* DevToolsContentRenderer becomes the new ContentRenderer, delegating
|
|
661
|
+
* all calls and collecting timing data.
|
|
662
|
+
*
|
|
663
|
+
* @param innerRenderer The renderer class to wrap with devtools instrumentation.
|
|
664
|
+
*
|
|
665
|
+
* @experimental Content DevTools is experimental and may change in future releases.
|
|
666
|
+
*
|
|
667
|
+
* @example
|
|
668
|
+
* ```typescript
|
|
669
|
+
* provideContent(
|
|
670
|
+
* withContentDevTools(NoopContentRenderer),
|
|
671
|
+
* );
|
|
672
|
+
* ```
|
|
673
|
+
*/
|
|
674
|
+
function withContentDevTools(innerRenderer) {
|
|
675
|
+
return [{
|
|
676
|
+
provide: DEVTOOLS_INNER_RENDERER,
|
|
677
|
+
useClass: innerRenderer
|
|
678
|
+
}, {
|
|
679
|
+
provide: ContentRenderer,
|
|
680
|
+
useClass: DevToolsContentRenderer
|
|
681
|
+
}];
|
|
682
|
+
}
|
|
683
|
+
//#endregion
|
|
684
|
+
export { AnchorNavigationDirective, CONTENT_FILE_LOADER, CONTENT_LIST_LOADER, ContentRenderer, DevToolsContentRenderer, FrontmatterValidationError, MERMAID_IMPORT_TOKEN, AnalogMarkdownComponent as MarkdownComponent, MarkdownContentRendererService, AnalogMarkdownRouteComponent as MarkdownRouteComponent, MarkedContentHighlighter, MarkedSetupService, NoopContentRenderer, contentDevToolsPlugin, injectContent, injectContentFileLoader, injectContentFiles, injectContentFilesMap, injectContentListLoader, parseRawContentFile, parseRawContentFileAsync, provideContent, withContentDevTools, withContentFileLoader, withContentListLoader, withHighlighter, withMarkdownRenderer };
|
|
808
685
|
|
|
809
686
|
//# sourceMappingURL=analogjs-content.mjs.map
|