@salesforcedevs/docs-components 0.56.2 → 0.56.3-example
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/lwc.config.json +10 -2
- package/package.json +19 -13
- package/src/modules/doc/{amfReference/utils.ts → amfModelParser/amfModelParser.ts} +10 -5
- package/src/modules/doc/amfReference/amfReference.css +23 -3
- package/src/modules/doc/amfReference/amfReference.html +42 -21
- package/src/modules/doc/amfReference/amfReference.ts +1022 -341
- package/src/modules/doc/amfReference/constants.ts +76 -0
- package/src/modules/doc/amfReference/types.ts +45 -13
- package/src/modules/doc/amfTopic/amfTopic.css +20 -0
- package/src/modules/doc/amfTopic/amfTopic.ts +35 -18
- package/src/modules/doc/amfTopic/types.ts +15 -13
- package/src/modules/doc/amfTopic/utils.ts +12 -6
- package/src/modules/doc/breadcrumbItem/breadcrumbItem.css +2 -1
- package/src/modules/doc/breadcrumbItem/breadcrumbItem.html +1 -1
- package/src/modules/doc/breadcrumbItem/breadcrumbItem.ts +22 -0
- package/src/modules/doc/breadcrumbs/breadcrumbs.css +9 -1
- package/src/modules/doc/breadcrumbs/breadcrumbs.html +44 -34
- package/src/modules/doc/breadcrumbs/breadcrumbs.ts +62 -23
- package/src/modules/doc/componentPlayground/componentPlayground.css +22 -0
- package/src/modules/doc/componentPlayground/componentPlayground.html +20 -0
- package/src/modules/doc/componentPlayground/componentPlayground.ts +42 -0
- package/src/modules/doc/content/content.css +70 -76
- package/src/modules/doc/content/content.html +1 -0
- package/src/modules/doc/content/content.ts +26 -47
- package/src/modules/doc/contentCallout/contentCallout.css +15 -7
- package/src/modules/doc/contentCallout/contentCallout.html +13 -4
- package/src/modules/doc/contentCallout/contentCallout.ts +14 -2
- package/src/modules/doc/contentLayout/contentLayout.css +1 -100
- package/src/modules/doc/contentLayout/contentLayout.html +30 -17
- package/src/modules/doc/contentLayout/contentLayout.ts +354 -65
- package/src/modules/doc/doDont/doDont.css +47 -0
- package/src/modules/doc/doDont/doDont.html +27 -0
- package/src/modules/doc/doDont/doDont.ts +17 -0
- package/src/modules/doc/header/header.css +65 -36
- package/src/modules/doc/header/header.html +41 -139
- package/src/modules/doc/header/header.ts +54 -76
- package/src/modules/doc/heading/heading.css +16 -37
- package/src/modules/doc/heading/heading.html +4 -4
- package/src/modules/doc/heading/heading.ts +12 -10
- package/src/modules/doc/headingAnchor/headingAnchor.css +2 -2
- package/src/modules/doc/headingAnchor/headingAnchor.ts +2 -2
- package/src/modules/doc/headingContent/headingContent.css +6 -8
- package/src/modules/doc/headingContent/headingContent.html +9 -15
- package/src/modules/doc/headingContent/headingContent.ts +2 -14
- package/src/modules/doc/lwcContentLayout/lwcContentLayout.css +1 -0
- package/src/modules/doc/lwcContentLayout/lwcContentLayout.html +68 -0
- package/src/modules/doc/lwcContentLayout/lwcContentLayout.ts +256 -0
- package/src/modules/doc/overview/overview.css +40 -0
- package/src/modules/doc/overview/overview.html +34 -0
- package/src/modules/doc/overview/overview.ts +12 -0
- package/src/modules/doc/phase/phase.css +18 -3
- package/src/modules/doc/phase/phase.html +15 -3
- package/src/modules/doc/phase/phase.ts +44 -8
- package/src/modules/doc/specificationContent/specificationContent.css +36 -0
- package/src/modules/doc/specificationContent/specificationContent.html +167 -0
- package/src/modules/doc/specificationContent/specificationContent.ts +127 -0
- package/src/modules/doc/sprigSurvey/sprigSurvey.html +20 -0
- package/src/modules/doc/sprigSurvey/sprigSurvey.scoped.css +16 -0
- package/src/modules/doc/sprigSurvey/sprigSurvey.ts +16 -0
- package/src/modules/doc/toc/toc.ts +1 -1
- package/src/modules/doc/versionPicker/versionPicker.css +64 -0
- package/src/modules/doc/versionPicker/versionPicker.html +38 -0
- package/src/modules/doc/versionPicker/versionPicker.ts +65 -0
- package/src/modules/doc/xmlContent/types.ts +12 -3
- package/src/modules/doc/xmlContent/utils.ts +17 -12
- package/src/modules/doc/xmlContent/xmlContent.css +32 -3
- package/src/modules/doc/xmlContent/xmlContent.html +41 -15
- package/src/modules/doc/xmlContent/xmlContent.ts +295 -95
- package/src/modules/docHelpers/amfStyle/amfStyle.css +10 -45
- package/src/modules/docHelpers/contentLayoutStyle/contentLayoutStyle.css +131 -0
- package/src/modules/docHelpers/imgStyle/imgStyle.css +59 -0
- package/src/modules/docHelpers/status/status.css +1 -1
- package/src/modules/docUtils/{SearchSyncer/SearchSyncer.ts → searchSyncer/searchSyncer.ts} +1 -0
- package/src/modules/docUtils/utils/__mocks__/coveo.analytics.ts +16 -0
- package/src/modules/docUtils/utils/coveo.analytics.d.ts +10 -0
- package/src/modules/docUtils/utils/utils.ts +32 -0
- package/LICENSE +0 -12
- package/src/modules/doc/amfReference/route-meta.ts +0 -22
- package/src/modules/docBaseElements/lightningElementWithState/lightningElementWithState.ts +0 -93
- package/src/modules/docHelpers/phaseContentLayout/phaseContentLayout.css +0 -39
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @lwc/lwc/no-document-query */
|
|
1
2
|
import { api, track } from "lwc";
|
|
2
3
|
import { normalizeBoolean } from "dxUtils/normalizers";
|
|
3
4
|
import { FetchContent } from "./utils";
|
|
@@ -7,24 +8,45 @@ import {
|
|
|
7
8
|
DocVersion,
|
|
8
9
|
TreeNode,
|
|
9
10
|
Header,
|
|
11
|
+
SiderbarFooter,
|
|
10
12
|
HistoryState,
|
|
11
|
-
PageReference
|
|
13
|
+
PageReference,
|
|
14
|
+
TocMap,
|
|
15
|
+
ContentData
|
|
12
16
|
} from "./types";
|
|
13
|
-
import { SearchSyncer } from "docUtils/
|
|
14
|
-
import { LightningElementWithState } from "
|
|
15
|
-
import {
|
|
17
|
+
import { SearchSyncer } from "docUtils/searchSyncer";
|
|
18
|
+
import { LightningElementWithState } from "dxBaseElements/lightningElementWithState";
|
|
19
|
+
import { logCoveoPageView, oldVersionDocInfo } from "docUtils/utils";
|
|
20
|
+
import { Breadcrumb, DocPhaseInfo, Language } from "typings/custom";
|
|
21
|
+
import { track as trackGTM } from "dxUtils/analytics";
|
|
22
|
+
import DOMPurify from "dompurify";
|
|
16
23
|
|
|
17
24
|
// TODO: Imitating from actual implementation as doc-content use it like this. We should refactor it later.
|
|
18
|
-
const handleContentError = (error): void => console.log(error);
|
|
19
|
-
|
|
25
|
+
const handleContentError = (error: any): void => console.log(error);
|
|
26
|
+
|
|
27
|
+
const PIXEL_PER_CHARACTER_MAP: { [key: string]: number } = {
|
|
28
|
+
default: 7.7,
|
|
29
|
+
"ja-jp": 12.5
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const defaultSidebarFooter: SiderbarFooter = {
|
|
33
|
+
bailHref: "",
|
|
34
|
+
bailLabel: "",
|
|
35
|
+
languages: [],
|
|
36
|
+
language: ""
|
|
37
|
+
};
|
|
20
38
|
export default class DocXmlContent extends LightningElementWithState<{
|
|
21
39
|
isFetchingDocument: boolean;
|
|
22
40
|
isFetchingContent: boolean;
|
|
23
41
|
lastHighlightedSearch: string;
|
|
42
|
+
internalLinkClicked: boolean;
|
|
24
43
|
}> {
|
|
25
44
|
@api apiDomain = "https://developer.salesforce.com";
|
|
26
45
|
@api coveoOrganizationId!: string;
|
|
27
46
|
@api coveoPublicAccessToken!: string;
|
|
47
|
+
@api coveoAnalyticsToken!: string;
|
|
48
|
+
@api coveoSearchHub!: string;
|
|
49
|
+
@api hideFooter = false;
|
|
28
50
|
|
|
29
51
|
@api
|
|
30
52
|
get allLanguages(): Array<Language> {
|
|
@@ -47,21 +69,28 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
47
69
|
}
|
|
48
70
|
|
|
49
71
|
private availableLanguages: Array<DocLanguage> = [];
|
|
50
|
-
private availableVersions: Array<DocVersion> = [];
|
|
51
|
-
private contentProvider
|
|
72
|
+
@track private availableVersions: Array<DocVersion> = [];
|
|
73
|
+
private contentProvider?: FetchContent;
|
|
52
74
|
private docContent = "";
|
|
53
|
-
private language
|
|
54
|
-
private
|
|
75
|
+
private language?: DocLanguage | null = null;
|
|
76
|
+
private displayContent = false;
|
|
77
|
+
private display404 = false;
|
|
78
|
+
private _pageHeader?: Header;
|
|
55
79
|
private pdfUrl = "";
|
|
56
|
-
private tocMap =
|
|
57
|
-
private sidebarContent: Array<TreeNode> = null;
|
|
58
|
-
private version: DocVersion = null;
|
|
80
|
+
private tocMap: TocMap = {};
|
|
81
|
+
private sidebarContent: Array<TreeNode> | null = null;
|
|
82
|
+
private version: DocVersion | null = null;
|
|
59
83
|
private docTitle = "";
|
|
60
|
-
private analyticsEvent = "custEv_ctaLinkClick";
|
|
61
84
|
private _pathName = "";
|
|
62
|
-
private _pageHeader?: Header;
|
|
63
85
|
private listenerAttached = false;
|
|
64
86
|
private _enableCoveo?: boolean = false;
|
|
87
|
+
private sidebarFooterContent: SiderbarFooter = { ...defaultSidebarFooter };
|
|
88
|
+
private latestVersion = false;
|
|
89
|
+
private previewVersion = false;
|
|
90
|
+
|
|
91
|
+
private get enableFooter(): boolean {
|
|
92
|
+
return !this.hideFooter;
|
|
93
|
+
}
|
|
65
94
|
|
|
66
95
|
private searchSyncer = new SearchSyncer({
|
|
67
96
|
callbacks: {
|
|
@@ -101,7 +130,39 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
101
130
|
});
|
|
102
131
|
private _allLanguages: Array<Language> = [];
|
|
103
132
|
|
|
133
|
+
private get oldVersionInfo(): DocPhaseInfo | null {
|
|
134
|
+
let info = null;
|
|
135
|
+
if (!this.disableVersion) {
|
|
136
|
+
const currentGAVersion = this.versionOptions.find(
|
|
137
|
+
(version) => !version.url.includes(version.id)
|
|
138
|
+
);
|
|
139
|
+
if (currentGAVersion?.link?.href && this.version?.id) {
|
|
140
|
+
const versionNo = currentGAVersion.id;
|
|
141
|
+
/**
|
|
142
|
+
* Need to show old version doc banner only if the version is less than the current ga version
|
|
143
|
+
* We should not show it to the preview version whose version is more than ga
|
|
144
|
+
**/
|
|
145
|
+
try {
|
|
146
|
+
if (parseFloat(this.version.id) < parseFloat(versionNo)) {
|
|
147
|
+
info = oldVersionDocInfo(currentGAVersion.link.href);
|
|
148
|
+
} else if (
|
|
149
|
+
parseFloat(this.version.id) > parseFloat(versionNo)
|
|
150
|
+
) {
|
|
151
|
+
this.previewVersion = true;
|
|
152
|
+
}
|
|
153
|
+
} catch (exception) {
|
|
154
|
+
/* Ideally this use case should not happen, but just added to not to break the page*/
|
|
155
|
+
console.warn(exception);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return info;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
@track showVersionBanner = false;
|
|
163
|
+
|
|
104
164
|
@track private pageReference: PageReference = {};
|
|
165
|
+
@track breadcrumbs: Array<Breadcrumb> = [];
|
|
105
166
|
|
|
106
167
|
constructor() {
|
|
107
168
|
super();
|
|
@@ -126,7 +187,13 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
126
187
|
this.apiDomain,
|
|
127
188
|
this.allLanguages
|
|
128
189
|
);
|
|
129
|
-
this.fetchDocument().then(() =>
|
|
190
|
+
this.fetchDocument().then((content: any) => {
|
|
191
|
+
if (content) {
|
|
192
|
+
this.displayContent = true;
|
|
193
|
+
} else {
|
|
194
|
+
this.display404 = true;
|
|
195
|
+
}
|
|
196
|
+
});
|
|
130
197
|
window.addEventListener("popstate", this.handlePopState);
|
|
131
198
|
|
|
132
199
|
this.searchSyncer.init();
|
|
@@ -135,8 +202,8 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
135
202
|
renderedCallback(): void {
|
|
136
203
|
this.setState({ internalLinkClicked: true });
|
|
137
204
|
const urlSectionLink =
|
|
138
|
-
this.pageReference?.hash?.split("#").length > 1
|
|
139
|
-
? this.pageReference.hash
|
|
205
|
+
this.pageReference?.hash?.split("#").length! > 1
|
|
206
|
+
? this.pageReference.hash!.split("#")[1]
|
|
140
207
|
: this.pageReference?.hash;
|
|
141
208
|
|
|
142
209
|
const contentEl = this.template.querySelector("doc-content");
|
|
@@ -149,6 +216,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
149
216
|
|
|
150
217
|
if (anchorEl) {
|
|
151
218
|
anchorEl.scrollIntoView();
|
|
219
|
+
|
|
152
220
|
this.setState({ internalLinkClicked: false });
|
|
153
221
|
}
|
|
154
222
|
|
|
@@ -174,24 +242,17 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
174
242
|
disconnectedCallback(): void {
|
|
175
243
|
window.removeEventListener("popstate", this.handlePopState);
|
|
176
244
|
this.searchSyncer.dispose();
|
|
177
|
-
if (this.listenerAttached) {
|
|
178
|
-
this.pageHeader.removeEventListener(
|
|
179
|
-
"langchange",
|
|
180
|
-
this.handleLanguageChange
|
|
181
|
-
);
|
|
182
|
-
this.listenerAttached = false;
|
|
183
|
-
}
|
|
184
245
|
}
|
|
185
246
|
|
|
186
|
-
private get languageId(): string {
|
|
187
|
-
return this.language
|
|
247
|
+
private get languageId(): string | undefined {
|
|
248
|
+
return this.language?.id.replace("-", "_");
|
|
188
249
|
}
|
|
189
250
|
|
|
190
|
-
private get releaseVersionId(): string {
|
|
191
|
-
return this.version
|
|
251
|
+
private get releaseVersionId(): string | undefined {
|
|
252
|
+
return this.version?.id;
|
|
192
253
|
}
|
|
193
254
|
|
|
194
|
-
private get deliverable(): string {
|
|
255
|
+
private get deliverable(): string | undefined {
|
|
195
256
|
return this.pageReference.deliverable;
|
|
196
257
|
}
|
|
197
258
|
|
|
@@ -212,7 +273,11 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
212
273
|
}
|
|
213
274
|
|
|
214
275
|
private get coveoAdvancedQueryConfig(): CoveoAdvancedQueryXMLConfig {
|
|
215
|
-
const config: {
|
|
276
|
+
const config: {
|
|
277
|
+
locale?: string;
|
|
278
|
+
topicid?: string;
|
|
279
|
+
version?: string;
|
|
280
|
+
} = {
|
|
216
281
|
locale: this.languageId,
|
|
217
282
|
topicid: this.deliverable
|
|
218
283
|
};
|
|
@@ -226,7 +291,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
226
291
|
|
|
227
292
|
private get pageHeader(): Header {
|
|
228
293
|
if (!this._pageHeader) {
|
|
229
|
-
this._pageHeader = document.querySelector("doc-header")
|
|
294
|
+
this._pageHeader = document.querySelector("doc-header")!;
|
|
230
295
|
}
|
|
231
296
|
|
|
232
297
|
return this._pageHeader;
|
|
@@ -267,8 +332,26 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
267
332
|
}));
|
|
268
333
|
}
|
|
269
334
|
|
|
270
|
-
private
|
|
271
|
-
|
|
335
|
+
private get breadcrumbPixelPerCharacter() {
|
|
336
|
+
return (
|
|
337
|
+
PIXEL_PER_CHARACTER_MAP[this.language!.id] ||
|
|
338
|
+
PIXEL_PER_CHARACTER_MAP.default
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
private get ANALYTICS_PAYLOAD() {
|
|
343
|
+
return {
|
|
344
|
+
element_title: "version picker",
|
|
345
|
+
content_category: "cta"
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
private handlePopState = (event: PopStateEvent): void =>
|
|
350
|
+
this.updatePageReference(this.getReferenceFromUrl(), event);
|
|
351
|
+
|
|
352
|
+
handleDismissVersionBanner() {
|
|
353
|
+
this.showVersionBanner = false;
|
|
354
|
+
}
|
|
272
355
|
|
|
273
356
|
handleSelect(event: CustomEvent<{ name: string }>): void {
|
|
274
357
|
event.stopPropagation();
|
|
@@ -280,15 +363,15 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
280
363
|
|
|
281
364
|
if (name) {
|
|
282
365
|
const hashIndex = name.indexOf("#");
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
this.pageReference
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
366
|
+
const hash = hashIndex > -1 ? name.slice(hashIndex) : "";
|
|
367
|
+
|
|
368
|
+
const contentDocumentId =
|
|
369
|
+
hashIndex > -1 ? name.slice(0, hashIndex) : name;
|
|
370
|
+
this.updatePageReference({
|
|
371
|
+
...this.pageReference,
|
|
372
|
+
contentDocumentId,
|
|
373
|
+
hash
|
|
374
|
+
});
|
|
292
375
|
this.updateUrl();
|
|
293
376
|
}
|
|
294
377
|
}
|
|
@@ -300,7 +383,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
300
383
|
this.updateUrl();
|
|
301
384
|
}
|
|
302
385
|
|
|
303
|
-
handleLanguageChange = (event:
|
|
386
|
+
handleLanguageChange = (event: any) => {
|
|
304
387
|
if (this.language && this.language.id === event.detail) {
|
|
305
388
|
return;
|
|
306
389
|
}
|
|
@@ -308,12 +391,26 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
308
391
|
this.language = this.availableLanguages.find(
|
|
309
392
|
({ id }) => id === event.detail
|
|
310
393
|
);
|
|
311
|
-
this.pageReference.docId = this.language
|
|
394
|
+
this.pageReference.docId = this.language!.url;
|
|
395
|
+
|
|
396
|
+
trackGTM(event.target!, "custEv_ctaLinkClick", {
|
|
397
|
+
click_text: event.detail,
|
|
398
|
+
element_title: "language selector",
|
|
399
|
+
click_url: `${window.location.origin}${this.pageReferenceToString(
|
|
400
|
+
this.pageReference
|
|
401
|
+
)}`,
|
|
402
|
+
element_type: "link",
|
|
403
|
+
content_category: "cta"
|
|
404
|
+
});
|
|
405
|
+
|
|
312
406
|
this.updateUrl();
|
|
313
407
|
this.fetchDocument();
|
|
314
408
|
};
|
|
315
409
|
|
|
316
|
-
updatePageReference(
|
|
410
|
+
updatePageReference(
|
|
411
|
+
newPageReference: PageReference,
|
|
412
|
+
event: PopStateEvent | undefined = undefined
|
|
413
|
+
): void {
|
|
317
414
|
this.pageReference.hash = newPageReference.hash;
|
|
318
415
|
this.pageReference.search = newPageReference.search;
|
|
319
416
|
|
|
@@ -321,20 +418,35 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
321
418
|
return;
|
|
322
419
|
}
|
|
323
420
|
|
|
324
|
-
const isSameDocId = this.pageReference.docId
|
|
421
|
+
const isSameDocId = this.pageReference.docId === newPageReference.docId;
|
|
325
422
|
this.pageReference = newPageReference;
|
|
326
423
|
|
|
327
|
-
if (isSameDocId) {
|
|
424
|
+
if (!isSameDocId) {
|
|
328
425
|
this.fetchDocument();
|
|
329
426
|
return;
|
|
330
427
|
}
|
|
331
428
|
|
|
332
|
-
this.fetchContent()
|
|
429
|
+
this.fetchContent()
|
|
430
|
+
.then(() => {
|
|
431
|
+
this.buildBreadcrumbs();
|
|
432
|
+
document.body.scrollTop = event?.state?.scroll?.value || 0;
|
|
433
|
+
})
|
|
434
|
+
.catch(handleContentError);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
private sanitizeUrlPart(part: string | undefined): string | undefined {
|
|
438
|
+
if (!part) {
|
|
439
|
+
return part;
|
|
440
|
+
}
|
|
441
|
+
return DOMPurify.sanitize(part);
|
|
333
442
|
}
|
|
334
443
|
|
|
335
444
|
getReferenceFromUrl(): PageReference {
|
|
336
445
|
const [page, docId, deliverable, contentDocumentId] =
|
|
337
|
-
window.location.pathname
|
|
446
|
+
window.location.pathname
|
|
447
|
+
.substr(1)
|
|
448
|
+
.split("/")
|
|
449
|
+
.map(this.sanitizeUrlPart);
|
|
338
450
|
|
|
339
451
|
const { origin: domain, hash, search } = window.location;
|
|
340
452
|
|
|
@@ -343,9 +455,9 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
343
455
|
deliverable,
|
|
344
456
|
docId,
|
|
345
457
|
domain,
|
|
346
|
-
hash,
|
|
458
|
+
hash: this.sanitizeUrlPart(hash),
|
|
347
459
|
page,
|
|
348
|
-
search
|
|
460
|
+
search: this.sanitizeUrlPart(search)
|
|
349
461
|
};
|
|
350
462
|
}
|
|
351
463
|
|
|
@@ -359,12 +471,13 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
359
471
|
);
|
|
360
472
|
}
|
|
361
473
|
|
|
362
|
-
async fetchDocument(): Promise<
|
|
474
|
+
async fetchDocument(): Promise<string> {
|
|
363
475
|
this.setState({
|
|
364
476
|
isFetchingDocument: true
|
|
365
477
|
});
|
|
366
|
-
|
|
367
|
-
|
|
478
|
+
|
|
479
|
+
const data = await this.contentProvider!.fetchDocumentData(
|
|
480
|
+
this.pageReference.docId!
|
|
368
481
|
);
|
|
369
482
|
|
|
370
483
|
// This could be a 404 scenario.
|
|
@@ -372,7 +485,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
372
485
|
this.setState({
|
|
373
486
|
isFetchingDocument: false
|
|
374
487
|
});
|
|
375
|
-
return;
|
|
488
|
+
return "";
|
|
376
489
|
}
|
|
377
490
|
|
|
378
491
|
this.docTitle = data.docTitle;
|
|
@@ -384,23 +497,31 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
384
497
|
this.availableVersions = data.availableVersions;
|
|
385
498
|
this.pdfUrl = data.pdfUrl;
|
|
386
499
|
|
|
387
|
-
this.
|
|
500
|
+
this.updateHeaderAndSidebarFooter();
|
|
501
|
+
|
|
502
|
+
this.buildBreadcrumbs();
|
|
388
503
|
|
|
389
504
|
if (this.pageReference.deliverable !== data.deliverable) {
|
|
390
505
|
this.pageReference.deliverable = data.deliverable;
|
|
391
506
|
this.updateUrl(HistoryState.REPLACE_STATE);
|
|
392
507
|
}
|
|
393
508
|
|
|
509
|
+
if (this.oldVersionInfo) {
|
|
510
|
+
this.showVersionBanner = true;
|
|
511
|
+
} else {
|
|
512
|
+
this.latestVersion = true;
|
|
513
|
+
}
|
|
514
|
+
|
|
394
515
|
if (
|
|
395
516
|
this.pageReference?.contentDocumentId?.replace(/\.htm$/, "") !==
|
|
396
517
|
data.id
|
|
397
518
|
) {
|
|
398
519
|
try {
|
|
399
|
-
await this.fetchContent();
|
|
520
|
+
const moreData = await this.fetchContent();
|
|
400
521
|
this.setState({
|
|
401
522
|
isFetchingDocument: false
|
|
402
523
|
});
|
|
403
|
-
return;
|
|
524
|
+
return moreData.content;
|
|
404
525
|
} catch (error) {
|
|
405
526
|
this.pageReference.contentDocumentId = `${data.id}.htm`;
|
|
406
527
|
this.pageReference.hash = "";
|
|
@@ -414,18 +535,19 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
414
535
|
this.setState({
|
|
415
536
|
isFetchingDocument: false
|
|
416
537
|
});
|
|
538
|
+
return data.content;
|
|
417
539
|
}
|
|
418
540
|
|
|
419
|
-
async fetchContent(): Promise<
|
|
541
|
+
async fetchContent(): Promise<ContentData> {
|
|
420
542
|
this.setState({
|
|
421
543
|
isFetchingContent: true
|
|
422
544
|
});
|
|
423
|
-
const data = await this.contentProvider
|
|
424
|
-
this.pageReference.deliverable
|
|
425
|
-
this.pageReference.contentDocumentId
|
|
545
|
+
const data = await this.contentProvider!.fetchContent(
|
|
546
|
+
this.pageReference.deliverable!,
|
|
547
|
+
this.pageReference.contentDocumentId!,
|
|
426
548
|
{
|
|
427
|
-
language: this.language
|
|
428
|
-
version: this.version
|
|
549
|
+
language: this.language!.id,
|
|
550
|
+
version: this.version!.id
|
|
429
551
|
}
|
|
430
552
|
);
|
|
431
553
|
|
|
@@ -434,19 +556,16 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
434
556
|
this.addMetatags();
|
|
435
557
|
|
|
436
558
|
if (!this.pageReference.hash) {
|
|
437
|
-
document.
|
|
438
|
-
behavior: "smooth",
|
|
439
|
-
block: "start",
|
|
440
|
-
inline: "nearest"
|
|
441
|
-
});
|
|
559
|
+
document.body.scrollIntoView();
|
|
442
560
|
}
|
|
443
561
|
}
|
|
444
562
|
this.setState({
|
|
445
563
|
isFetchingContent: false
|
|
446
564
|
});
|
|
565
|
+
return data;
|
|
447
566
|
}
|
|
448
567
|
|
|
449
|
-
|
|
568
|
+
updateHeaderAndSidebarFooter(): void {
|
|
450
569
|
if (!this.pageHeader) {
|
|
451
570
|
return;
|
|
452
571
|
}
|
|
@@ -456,20 +575,12 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
456
575
|
}
|
|
457
576
|
|
|
458
577
|
if (this.pdfUrl) {
|
|
459
|
-
this.
|
|
460
|
-
this.
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
if (!this.listenerAttached) {
|
|
464
|
-
this.pageHeader.addEventListener(
|
|
465
|
-
"langchange",
|
|
466
|
-
this.handleLanguageChange
|
|
467
|
-
);
|
|
468
|
-
this.listenerAttached = true;
|
|
578
|
+
this.sidebarFooterContent.bailHref = this.pdfUrl;
|
|
579
|
+
this.sidebarFooterContent.bailLabel = "PDF";
|
|
469
580
|
}
|
|
470
581
|
|
|
471
|
-
this.
|
|
472
|
-
this.
|
|
582
|
+
this.sidebarFooterContent.languages = this.availableLanguages;
|
|
583
|
+
this.sidebarFooterContent.language = this.language?.id;
|
|
473
584
|
|
|
474
585
|
if (this.pageReference) {
|
|
475
586
|
const { docId, deliverable, page } = this.pageReference;
|
|
@@ -478,6 +589,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
478
589
|
}
|
|
479
590
|
|
|
480
591
|
updateUrl(method = HistoryState.PUSH_STATE): void {
|
|
592
|
+
logCoveoPageView(this.coveoOrganizationId, this.coveoAnalyticsToken);
|
|
481
593
|
window.history[method](
|
|
482
594
|
{},
|
|
483
595
|
"docs",
|
|
@@ -493,23 +605,24 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
493
605
|
}
|
|
494
606
|
|
|
495
607
|
private updateSearchInput(searchParam: string): void {
|
|
496
|
-
this.
|
|
497
|
-
.querySelector("doc-content-layout")
|
|
498
|
-
?.setSidebarInputValue(searchParam);
|
|
608
|
+
(this.refs.docContentLayout as any)?.setSidebarInputValue(searchParam);
|
|
499
609
|
}
|
|
500
610
|
|
|
501
611
|
private pageReferenceToString(reference: PageReference): string {
|
|
502
612
|
const { page, docId, deliverable, contentDocumentId, hash, search } =
|
|
503
613
|
reference;
|
|
504
614
|
return `/${page}/${docId}/${deliverable}/${contentDocumentId}${this.normalizeSearch(
|
|
505
|
-
search
|
|
615
|
+
search!
|
|
506
616
|
)}${this.normalizeHash(hash)}`;
|
|
507
617
|
}
|
|
508
618
|
|
|
509
|
-
private normalizeUrlPart(
|
|
619
|
+
private normalizeUrlPart(
|
|
620
|
+
part: string | undefined,
|
|
621
|
+
sentinel: string
|
|
622
|
+
): string {
|
|
510
623
|
return (
|
|
511
624
|
(part &&
|
|
512
|
-
(part.startsWith(sentinel) ? part : `${sentinel}${part}`)) ||
|
|
625
|
+
(part.startsWith(sentinel!) ? part : `${sentinel}${part}`)) ||
|
|
513
626
|
""
|
|
514
627
|
);
|
|
515
628
|
}
|
|
@@ -518,16 +631,16 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
518
631
|
return this.normalizeUrlPart(search, "?");
|
|
519
632
|
}
|
|
520
633
|
|
|
521
|
-
private normalizeHash(hash
|
|
634
|
+
private normalizeHash(hash?: string): string {
|
|
522
635
|
return this.normalizeUrlPart(hash, "#");
|
|
523
636
|
}
|
|
524
637
|
|
|
525
638
|
private getComposedTitle(
|
|
526
|
-
topicTitle: string | undefined,
|
|
639
|
+
topicTitle: string | null | undefined,
|
|
527
640
|
docTitle: string | undefined
|
|
528
641
|
): string {
|
|
529
642
|
// map to avoid duplicates
|
|
530
|
-
const titleMap = {};
|
|
643
|
+
const titleMap: { [key: string]: any } = {};
|
|
531
644
|
if (topicTitle) {
|
|
532
645
|
// sometimes the h1 tag text (which is docSubTitle) contains text with new line character. For e.g, "Bulk API 2.0 Older\n Documentation",
|
|
533
646
|
// here it contains \n in the text context which needs to be removed
|
|
@@ -558,16 +671,65 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
558
671
|
);
|
|
559
672
|
}
|
|
560
673
|
|
|
674
|
+
get showBreadcrumbs(): boolean {
|
|
675
|
+
return this.breadcrumbs && this.breadcrumbs.length > 1;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
private buildBreadcrumbs(): void {
|
|
679
|
+
const { contentDocumentId } = this.pageReference;
|
|
680
|
+
if (!contentDocumentId) {
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
const currentNode = this.tocMap[contentDocumentId];
|
|
685
|
+
|
|
686
|
+
if (currentNode?.parent) {
|
|
687
|
+
this.breadcrumbs = this.nodeToBreadcrumb(currentNode);
|
|
688
|
+
} else {
|
|
689
|
+
this.breadcrumbs = [];
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
private nodeToBreadcrumb(node: TreeNode): Breadcrumb[] {
|
|
694
|
+
const item = {
|
|
695
|
+
href: this.pageReferenceToString({
|
|
696
|
+
...this.pageReference,
|
|
697
|
+
contentDocumentId: node.name
|
|
698
|
+
}),
|
|
699
|
+
label: node.label
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
if (node.parent) {
|
|
703
|
+
return [...this.nodeToBreadcrumb(node.parent), item];
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
return [item];
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
// This method take docId and drops the version from the docId.
|
|
710
|
+
// Example:
|
|
711
|
+
// Takes input string: docId = "atlas.en-us.238.0.b2b_b2c_comm_dev.meta"
|
|
712
|
+
// Output string: filteredDocId = "atlas.en-us.b2b_b2c_comm_dev.meta"
|
|
713
|
+
dropVersionFromDocId(docId: string): string {
|
|
714
|
+
if (!this.version?.id) {
|
|
715
|
+
return docId;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
const curVersion = this.version.id + ".";
|
|
719
|
+
const filteredDocId = docId.replace(curVersion, "");
|
|
720
|
+
return filteredDocId;
|
|
721
|
+
}
|
|
722
|
+
|
|
561
723
|
addMetatags(): void {
|
|
562
724
|
const div = document.createElement("div");
|
|
563
|
-
div.innerHTML = this.docContent;
|
|
725
|
+
div.innerHTML = DOMPurify.sanitize(this.docContent);
|
|
564
726
|
const docDescription = div.querySelector(".shortdesc")?.textContent;
|
|
565
727
|
const topicTitle = div.querySelector("h1")?.textContent;
|
|
566
728
|
|
|
567
729
|
const title = document.querySelector("title");
|
|
568
730
|
const composedTitle = this.getComposedTitle(topicTitle, this.docTitle);
|
|
569
731
|
|
|
570
|
-
if (title) {
|
|
732
|
+
if (title && title.textContent) {
|
|
571
733
|
title.textContent = composedTitle;
|
|
572
734
|
}
|
|
573
735
|
const metatitle = document.querySelector('meta[name="title"]');
|
|
@@ -589,14 +751,52 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
589
751
|
'link[rel="canonical"]'
|
|
590
752
|
);
|
|
591
753
|
if (metadescription) {
|
|
754
|
+
const copyPageReference = { ...this.pageReference };
|
|
755
|
+
copyPageReference.docId = copyPageReference.docId
|
|
756
|
+
? this.dropVersionFromDocId(copyPageReference.docId)
|
|
757
|
+
: copyPageReference.docId;
|
|
592
758
|
metadescription.setAttribute(
|
|
593
759
|
"href",
|
|
594
760
|
window.location.protocol +
|
|
595
761
|
"//" +
|
|
596
762
|
window.location.host +
|
|
597
|
-
this.pageReferenceToString(
|
|
763
|
+
this.pageReferenceToString(copyPageReference)
|
|
598
764
|
);
|
|
599
765
|
}
|
|
600
766
|
}
|
|
767
|
+
|
|
768
|
+
this.addNoIndexMetaForOlderDocVersions();
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* Method adds noindex, follow meta tag to the older Couch DB doc pages.
|
|
773
|
+
* Fixes W-12547462.
|
|
774
|
+
*/
|
|
775
|
+
private addNoIndexMetaForOlderDocVersions() {
|
|
776
|
+
// eslint-disable-next-line @lwc/lwc/no-document-query
|
|
777
|
+
const headTag = document.getElementsByTagName("head");
|
|
778
|
+
// this checks if the selected version is not the latest version,
|
|
779
|
+
// then it adds the noindex, follow meta tag to the older version pages.
|
|
780
|
+
const versionId = this.version!.id;
|
|
781
|
+
const docId = this.pageReference.docId;
|
|
782
|
+
|
|
783
|
+
// SEO fix:
|
|
784
|
+
// Doc id without version id is always considered latest and should be used for SEO.
|
|
785
|
+
// Condition is to find a docId which includes version id,
|
|
786
|
+
// these docs are always considered as old and should not be indexed including the preview docs.
|
|
787
|
+
if (
|
|
788
|
+
headTag.length &&
|
|
789
|
+
docId?.includes(versionId) &&
|
|
790
|
+
!document.querySelector('meta[name="robots"]')
|
|
791
|
+
) {
|
|
792
|
+
const robotsMeta = document.createElement("meta");
|
|
793
|
+
robotsMeta.setAttribute("name", "robots");
|
|
794
|
+
robotsMeta.setAttribute("content", "noindex, follow");
|
|
795
|
+
headTag[0].appendChild(robotsMeta);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
private get showVersionPicker(): boolean {
|
|
800
|
+
return !this.disableVersion;
|
|
601
801
|
}
|
|
602
802
|
}
|