docula 2.1.0 → 2.2.0
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/docula.d.ts +11 -0
- package/dist/docula.js +36 -2
- package/package.json +1 -1
- package/templates/classic/includes/body-scripts.hbs +1 -1
- package/templates/classic/includes/header.hbs +1 -1
- package/templates/modern/includes/body-scripts.hbs +1 -1
- package/templates/modern/includes/header.hbs +1 -1
- package/templates/modern/includes/scripts.hbs +28 -17
package/dist/docula.d.ts
CHANGED
|
@@ -202,6 +202,7 @@ type DoculaData = {
|
|
|
202
202
|
}>;
|
|
203
203
|
googleTagManager?: string;
|
|
204
204
|
isGtag?: boolean;
|
|
205
|
+
googleTagManagerParams?: string;
|
|
205
206
|
enableLlmsTxt?: boolean;
|
|
206
207
|
enableSearch?: boolean;
|
|
207
208
|
hasFeed?: boolean;
|
|
@@ -426,6 +427,16 @@ declare class DoculaOptions {
|
|
|
426
427
|
* When set, injects the appropriate tracking script on every page.
|
|
427
428
|
*/
|
|
428
429
|
googleTagManager?: string;
|
|
430
|
+
/**
|
|
431
|
+
* Google Tag Manager environment auth token (gtm_auth). Only applies to
|
|
432
|
+
* GTM container IDs; requires `googleTagManagerEnv` to also be set.
|
|
433
|
+
*/
|
|
434
|
+
googleTagManagerAuth?: string;
|
|
435
|
+
/**
|
|
436
|
+
* Google Tag Manager environment name (gtm_preview), e.g., "env-3". Only
|
|
437
|
+
* applies to GTM container IDs; requires `googleTagManagerAuth` to also be set.
|
|
438
|
+
*/
|
|
439
|
+
googleTagManagerEnv?: string;
|
|
429
440
|
/**
|
|
430
441
|
* AI-powered metadata enrichment configuration. When set, uses AI to fill
|
|
431
442
|
* missing OpenGraph and HTML meta tag fields during the build.
|
package/dist/docula.js
CHANGED
|
@@ -17,7 +17,7 @@ import { CacheableNet } from "@cacheable/net";
|
|
|
17
17
|
import os from "node:os";
|
|
18
18
|
import sea from "node:sea";
|
|
19
19
|
//#region package.json
|
|
20
|
-
var version = "2.
|
|
20
|
+
var version = "2.2.0";
|
|
21
21
|
var package_default = {
|
|
22
22
|
name: "docula",
|
|
23
23
|
version,
|
|
@@ -731,6 +731,25 @@ function summarizeMarkdown(markdown, maxLength = 240) {
|
|
|
731
731
|
function isRemoteUrl(url) {
|
|
732
732
|
return /^https?:\/\//i.test(url);
|
|
733
733
|
}
|
|
734
|
+
/**
|
|
735
|
+
* Encode a value for use in a URL query string. Unlike `encodeURIComponent`,
|
|
736
|
+
* this also escapes single quotes, so the result is safe to inject into a
|
|
737
|
+
* single-quoted JavaScript string literal (e.g., inline template scripts)
|
|
738
|
+
* where a raw quote would break the string.
|
|
739
|
+
*/
|
|
740
|
+
function encodeQueryStringValue(value) {
|
|
741
|
+
return encodeURIComponent(value).replace(/'/g, "%27");
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Build the extra query string appended to Google Tag Manager URLs when
|
|
745
|
+
* targeting a GTM environment. A GTM environment is identified by both an
|
|
746
|
+
* auth token and an environment name, so this returns `undefined` unless
|
|
747
|
+
* both are set.
|
|
748
|
+
*/
|
|
749
|
+
function buildGtmEnvironmentParams(auth, env) {
|
|
750
|
+
if (!auth || !env) return;
|
|
751
|
+
return `>m_auth=${encodeQueryStringValue(auth)}>m_preview=${encodeQueryStringValue(env)}>m_cookies_win=x`;
|
|
752
|
+
}
|
|
734
753
|
//#endregion
|
|
735
754
|
//#region src/builder-seo.ts
|
|
736
755
|
const writrOptions$5 = {
|
|
@@ -1437,7 +1456,9 @@ function hashOptions(hash, options) {
|
|
|
1437
1456
|
apiPath: options.apiPath,
|
|
1438
1457
|
changelogPath: options.changelogPath,
|
|
1439
1458
|
ai: options.ai,
|
|
1440
|
-
googleTagManager: options.googleTagManager
|
|
1459
|
+
googleTagManager: options.googleTagManager,
|
|
1460
|
+
googleTagManagerAuth: options.googleTagManagerAuth,
|
|
1461
|
+
googleTagManagerEnv: options.googleTagManagerEnv
|
|
1441
1462
|
};
|
|
1442
1463
|
const optionsHash = hash.toHashSync(JSON.stringify(relevant));
|
|
1443
1464
|
const configHash = hashConfigFile(hash, options.sitePath);
|
|
@@ -3041,6 +3062,16 @@ var DoculaOptions = class {
|
|
|
3041
3062
|
*/
|
|
3042
3063
|
googleTagManager;
|
|
3043
3064
|
/**
|
|
3065
|
+
* Google Tag Manager environment auth token (gtm_auth). Only applies to
|
|
3066
|
+
* GTM container IDs; requires `googleTagManagerEnv` to also be set.
|
|
3067
|
+
*/
|
|
3068
|
+
googleTagManagerAuth;
|
|
3069
|
+
/**
|
|
3070
|
+
* Google Tag Manager environment name (gtm_preview), e.g., "env-3". Only
|
|
3071
|
+
* applies to GTM container IDs; requires `googleTagManagerAuth` to also be set.
|
|
3072
|
+
*/
|
|
3073
|
+
googleTagManagerEnv;
|
|
3074
|
+
/**
|
|
3044
3075
|
* AI-powered metadata enrichment configuration. When set, uses AI to fill
|
|
3045
3076
|
* missing OpenGraph and HTML meta tag fields during the build.
|
|
3046
3077
|
* Requires provider name and API key. Omit to disable AI enrichment.
|
|
@@ -3131,6 +3162,8 @@ var DoculaOptions = class {
|
|
|
3131
3162
|
if (options.autoReadme !== void 0 && typeof options.autoReadme === "boolean") this.autoReadme = options.autoReadme;
|
|
3132
3163
|
if (options.quiet !== void 0 && typeof options.quiet === "boolean") this.quiet = options.quiet;
|
|
3133
3164
|
if (options.googleTagManager !== void 0 && typeof options.googleTagManager === "string" && /^G[A-Z]*-[A-Z0-9]+$/i.test(options.googleTagManager)) this.googleTagManager = options.googleTagManager;
|
|
3165
|
+
if (options.googleTagManagerAuth !== void 0 && typeof options.googleTagManagerAuth === "string" && options.googleTagManagerAuth.length > 0) this.googleTagManagerAuth = options.googleTagManagerAuth;
|
|
3166
|
+
if (options.googleTagManagerEnv !== void 0 && typeof options.googleTagManagerEnv === "string" && options.googleTagManagerEnv.length > 0) this.googleTagManagerEnv = options.googleTagManagerEnv;
|
|
3134
3167
|
if (options.ai && typeof options.ai === "object" && typeof options.ai.provider === "string" && typeof options.ai.apiKey === "string") this.ai = options.ai;
|
|
3135
3168
|
if (options.cache && typeof options.cache === "object" && options.cache.github !== null && typeof options.cache.github === "object" && typeof options.cache.github.ttl === "number") this.cache = options.cache;
|
|
3136
3169
|
if (options.homeUrl !== void 0 && typeof options.homeUrl === "string") this.homeUrl = options.homeUrl === "/" ? "/" : trimTrailingSlashes(options.homeUrl);
|
|
@@ -3272,6 +3305,7 @@ var DoculaBuilder = class {
|
|
|
3272
3305
|
headerLinks: this.options.headerLinks,
|
|
3273
3306
|
googleTagManager: this.options.googleTagManager,
|
|
3274
3307
|
isGtag: this.options.googleTagManager?.startsWith("G-") ?? false,
|
|
3308
|
+
googleTagManagerParams: buildGtmEnvironmentParams(this.options.googleTagManagerAuth, this.options.googleTagManagerEnv),
|
|
3275
3309
|
enableLlmsTxt: this.options.enableLlmsTxt,
|
|
3276
3310
|
homeUrl: this.options.homeUrl,
|
|
3277
3311
|
baseUrl: this.options.baseUrl,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{{#if googleTagManager}}
|
|
2
2
|
{{#unless isGtag}}
|
|
3
3
|
<!-- Google Tag Manager (noscript) -->
|
|
4
|
-
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{googleTagManager}}"
|
|
4
|
+
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{googleTagManager}}{{{googleTagManagerParams}}}"
|
|
5
5
|
height="0" width="0" style="display:none !important;visibility:hidden !important"></iframe></noscript>
|
|
6
6
|
<!-- End Google Tag Manager (noscript) -->
|
|
7
7
|
{{/unless}}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
|
9
9
|
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
|
10
10
|
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|
11
|
-
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
|
11
|
+
'https://www.googletagmanager.com/gtm.js?id='+i+dl+'{{{googleTagManagerParams}}}';f.parentNode.insertBefore(j,f);
|
|
12
12
|
})(window,document,'script','dataLayer','{{googleTagManager}}');</script>
|
|
13
13
|
<!-- End Google Tag Manager -->
|
|
14
14
|
{{/if}}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{{#if googleTagManager}}
|
|
2
2
|
{{#unless isGtag}}
|
|
3
3
|
<!-- Google Tag Manager (noscript) -->
|
|
4
|
-
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{googleTagManager}}"
|
|
4
|
+
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{googleTagManager}}{{{googleTagManagerParams}}}"
|
|
5
5
|
height="0" width="0" style="display:none !important;visibility:hidden !important"></iframe></noscript>
|
|
6
6
|
<!-- End Google Tag Manager (noscript) -->
|
|
7
7
|
{{/unless}}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
|
9
9
|
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
|
10
10
|
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|
11
|
-
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
|
11
|
+
'https://www.googletagmanager.com/gtm.js?id='+i+dl+'{{{googleTagManagerParams}}}';f.parentNode.insertBefore(j,f);
|
|
12
12
|
})(window,document,'script','dataLayer','{{googleTagManager}}');</script>
|
|
13
13
|
<!-- End Google Tag Manager -->
|
|
14
14
|
{{/if}}
|
|
@@ -265,23 +265,34 @@
|
|
|
265
265
|
});
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
-
// Active
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
//
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
268
|
+
// Active nav link highlighting (header + mobile). Highlight only the
|
|
269
|
+
// single most-specific link: the one whose path is the longest prefix of
|
|
270
|
+
// the current path. A plain startsWith() check lights up every link whose
|
|
271
|
+
// path merely prefixes the current one, so when the site is embedded under
|
|
272
|
+
// a base path (e.g. served at /developer with docs at that root) the
|
|
273
|
+
// Documentation link — whose path is a prefix of every page — would stay
|
|
274
|
+
// highlighted everywhere. Trailing slashes are normalized so matches stop
|
|
275
|
+
// at a path boundary. We read the anchor's resolved origin/pathname so
|
|
276
|
+
// absolute, relative, and same-origin hrefs all work, while cross-origin
|
|
277
|
+
// links and non-anchor items (e.g. the mobile logout button) are skipped.
|
|
278
|
+
const withTrailingSlash = (p) => (p.endsWith('/') ? p : p + '/');
|
|
279
|
+
const here = withTrailingSlash(currentPath);
|
|
280
|
+
const markActiveNav = (selector, activeClass) => {
|
|
281
|
+
let bestLink = null;
|
|
282
|
+
let bestLength = -1;
|
|
283
|
+
document.querySelectorAll(selector).forEach((link) => {
|
|
284
|
+
// Only same-origin anchors can match the current pathname.
|
|
285
|
+
if (!link.href || link.origin !== window.location.origin) return;
|
|
286
|
+
const base = withTrailingSlash(link.pathname);
|
|
287
|
+
if (here.startsWith(base) && base.length > bestLength) {
|
|
288
|
+
bestLink = link;
|
|
289
|
+
bestLength = base.length;
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
if (bestLink) bestLink.classList.add(activeClass);
|
|
293
|
+
};
|
|
294
|
+
markActiveNav('.header-bottom__item', 'header-bottom__item--active');
|
|
295
|
+
markActiveNav('.mobile-nav__item', 'mobile-nav__item--active');
|
|
285
296
|
|
|
286
297
|
// TOC extraction: move the inline TOC into the right sidebar and hide the original
|
|
287
298
|
const tocHeading = document.getElementById('table-of-contents');
|