@salesforcedevs/docs-components 0.56.2-comp-flex-ref-2 → 0.56.2-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 +18 -12
- 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 +34 -21
- package/src/modules/doc/amfReference/amfReference.ts +377 -97
- package/src/modules/doc/amfReference/types.ts +5 -12
- 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 +314 -70
- 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 +310 -96
- 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/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,25 +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 {
|
|
16
|
-
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";
|
|
17
23
|
|
|
18
24
|
// TODO: Imitating from actual implementation as doc-content use it like this. We should refactor it later.
|
|
19
|
-
const handleContentError = (error): void => console.log(error);
|
|
20
|
-
|
|
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
|
+
};
|
|
21
38
|
export default class DocXmlContent extends LightningElementWithState<{
|
|
22
39
|
isFetchingDocument: boolean;
|
|
23
40
|
isFetchingContent: boolean;
|
|
24
41
|
lastHighlightedSearch: string;
|
|
42
|
+
internalLinkClicked: boolean;
|
|
25
43
|
}> {
|
|
26
44
|
@api apiDomain = "https://developer.salesforce.com";
|
|
27
45
|
@api coveoOrganizationId!: string;
|
|
28
46
|
@api coveoPublicAccessToken!: string;
|
|
47
|
+
@api coveoAnalyticsToken!: string;
|
|
48
|
+
@api coveoSearchHub!: string;
|
|
49
|
+
@api hideFooter = false;
|
|
29
50
|
|
|
30
51
|
@api
|
|
31
52
|
get allLanguages(): Array<Language> {
|
|
@@ -48,21 +69,28 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
48
69
|
}
|
|
49
70
|
|
|
50
71
|
private availableLanguages: Array<DocLanguage> = [];
|
|
51
|
-
private availableVersions: Array<DocVersion> = [];
|
|
52
|
-
private contentProvider
|
|
72
|
+
@track private availableVersions: Array<DocVersion> = [];
|
|
73
|
+
private contentProvider?: FetchContent;
|
|
53
74
|
private docContent = "";
|
|
54
|
-
private language
|
|
55
|
-
private
|
|
75
|
+
private language?: DocLanguage | null = null;
|
|
76
|
+
private displayContent = false;
|
|
77
|
+
private display404 = false;
|
|
78
|
+
private _pageHeader?: Header;
|
|
56
79
|
private pdfUrl = "";
|
|
57
|
-
private tocMap =
|
|
58
|
-
private sidebarContent: Array<TreeNode> = null;
|
|
59
|
-
private version: DocVersion = null;
|
|
80
|
+
private tocMap: TocMap = {};
|
|
81
|
+
private sidebarContent: Array<TreeNode> | null = null;
|
|
82
|
+
private version: DocVersion | null = null;
|
|
60
83
|
private docTitle = "";
|
|
61
|
-
private analyticsEvent = "custEv_ctaLinkClick";
|
|
62
84
|
private _pathName = "";
|
|
63
|
-
private _pageHeader?: Header;
|
|
64
85
|
private listenerAttached = false;
|
|
65
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
|
+
}
|
|
66
94
|
|
|
67
95
|
private searchSyncer = new SearchSyncer({
|
|
68
96
|
callbacks: {
|
|
@@ -100,9 +128,41 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
100
128
|
shouldStopPropagation: true,
|
|
101
129
|
target: window
|
|
102
130
|
});
|
|
103
|
-
private _allLanguages: Array<Language> =
|
|
131
|
+
private _allLanguages: Array<Language> = [];
|
|
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;
|
|
104
163
|
|
|
105
164
|
@track private pageReference: PageReference = {};
|
|
165
|
+
@track breadcrumbs: Array<Breadcrumb> = [];
|
|
106
166
|
|
|
107
167
|
constructor() {
|
|
108
168
|
super();
|
|
@@ -127,7 +187,13 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
127
187
|
this.apiDomain,
|
|
128
188
|
this.allLanguages
|
|
129
189
|
);
|
|
130
|
-
this.fetchDocument().then(() =>
|
|
190
|
+
this.fetchDocument().then((content: any) => {
|
|
191
|
+
if (content) {
|
|
192
|
+
this.displayContent = true;
|
|
193
|
+
} else {
|
|
194
|
+
this.display404 = true;
|
|
195
|
+
}
|
|
196
|
+
});
|
|
131
197
|
window.addEventListener("popstate", this.handlePopState);
|
|
132
198
|
|
|
133
199
|
this.searchSyncer.init();
|
|
@@ -136,8 +202,8 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
136
202
|
renderedCallback(): void {
|
|
137
203
|
this.setState({ internalLinkClicked: true });
|
|
138
204
|
const urlSectionLink =
|
|
139
|
-
this.pageReference?.hash?.split("#").length > 1
|
|
140
|
-
? this.pageReference.hash
|
|
205
|
+
this.pageReference?.hash?.split("#").length! > 1
|
|
206
|
+
? this.pageReference.hash!.split("#")[1]
|
|
141
207
|
: this.pageReference?.hash;
|
|
142
208
|
|
|
143
209
|
const contentEl = this.template.querySelector("doc-content");
|
|
@@ -150,6 +216,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
150
216
|
|
|
151
217
|
if (anchorEl) {
|
|
152
218
|
anchorEl.scrollIntoView();
|
|
219
|
+
|
|
153
220
|
this.setState({ internalLinkClicked: false });
|
|
154
221
|
}
|
|
155
222
|
|
|
@@ -175,24 +242,17 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
175
242
|
disconnectedCallback(): void {
|
|
176
243
|
window.removeEventListener("popstate", this.handlePopState);
|
|
177
244
|
this.searchSyncer.dispose();
|
|
178
|
-
if (this.listenerAttached) {
|
|
179
|
-
this.pageHeader.removeEventListener(
|
|
180
|
-
"langchange",
|
|
181
|
-
this.handleLanguageChange
|
|
182
|
-
);
|
|
183
|
-
this.listenerAttached = false;
|
|
184
|
-
}
|
|
185
245
|
}
|
|
186
246
|
|
|
187
|
-
private get languageId(): string {
|
|
188
|
-
return this.language
|
|
247
|
+
private get languageId(): string | undefined {
|
|
248
|
+
return this.language?.id.replace("-", "_");
|
|
189
249
|
}
|
|
190
250
|
|
|
191
|
-
private get releaseVersionId(): string {
|
|
192
|
-
return this.version
|
|
251
|
+
private get releaseVersionId(): string | undefined {
|
|
252
|
+
return this.version?.id;
|
|
193
253
|
}
|
|
194
254
|
|
|
195
|
-
private get deliverable(): string {
|
|
255
|
+
private get deliverable(): string | undefined {
|
|
196
256
|
return this.pageReference.deliverable;
|
|
197
257
|
}
|
|
198
258
|
|
|
@@ -213,7 +273,11 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
213
273
|
}
|
|
214
274
|
|
|
215
275
|
private get coveoAdvancedQueryConfig(): CoveoAdvancedQueryXMLConfig {
|
|
216
|
-
const config: {
|
|
276
|
+
const config: {
|
|
277
|
+
locale?: string;
|
|
278
|
+
topicid?: string;
|
|
279
|
+
version?: string;
|
|
280
|
+
} = {
|
|
217
281
|
locale: this.languageId,
|
|
218
282
|
topicid: this.deliverable
|
|
219
283
|
};
|
|
@@ -227,7 +291,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
227
291
|
|
|
228
292
|
private get pageHeader(): Header {
|
|
229
293
|
if (!this._pageHeader) {
|
|
230
|
-
this._pageHeader = document.querySelector("doc-header")
|
|
294
|
+
this._pageHeader = document.querySelector("doc-header")!;
|
|
231
295
|
}
|
|
232
296
|
|
|
233
297
|
return this._pageHeader;
|
|
@@ -268,8 +332,26 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
268
332
|
}));
|
|
269
333
|
}
|
|
270
334
|
|
|
271
|
-
private
|
|
272
|
-
|
|
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
|
+
}
|
|
273
355
|
|
|
274
356
|
handleSelect(event: CustomEvent<{ name: string }>): void {
|
|
275
357
|
event.stopPropagation();
|
|
@@ -281,15 +363,15 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
281
363
|
|
|
282
364
|
if (name) {
|
|
283
365
|
const hashIndex = name.indexOf("#");
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
this.pageReference
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
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
|
+
});
|
|
293
375
|
this.updateUrl();
|
|
294
376
|
}
|
|
295
377
|
}
|
|
@@ -301,7 +383,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
301
383
|
this.updateUrl();
|
|
302
384
|
}
|
|
303
385
|
|
|
304
|
-
handleLanguageChange = (event:
|
|
386
|
+
handleLanguageChange = (event: any) => {
|
|
305
387
|
if (this.language && this.language.id === event.detail) {
|
|
306
388
|
return;
|
|
307
389
|
}
|
|
@@ -309,12 +391,26 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
309
391
|
this.language = this.availableLanguages.find(
|
|
310
392
|
({ id }) => id === event.detail
|
|
311
393
|
);
|
|
312
|
-
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
|
+
|
|
313
406
|
this.updateUrl();
|
|
314
407
|
this.fetchDocument();
|
|
315
408
|
};
|
|
316
409
|
|
|
317
|
-
updatePageReference(
|
|
410
|
+
updatePageReference(
|
|
411
|
+
newPageReference: PageReference,
|
|
412
|
+
event: PopStateEvent | undefined = undefined
|
|
413
|
+
): void {
|
|
318
414
|
this.pageReference.hash = newPageReference.hash;
|
|
319
415
|
this.pageReference.search = newPageReference.search;
|
|
320
416
|
|
|
@@ -322,20 +418,35 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
322
418
|
return;
|
|
323
419
|
}
|
|
324
420
|
|
|
325
|
-
const isSameDocId = this.pageReference.docId
|
|
421
|
+
const isSameDocId = this.pageReference.docId === newPageReference.docId;
|
|
326
422
|
this.pageReference = newPageReference;
|
|
327
423
|
|
|
328
|
-
if (isSameDocId) {
|
|
424
|
+
if (!isSameDocId) {
|
|
329
425
|
this.fetchDocument();
|
|
330
426
|
return;
|
|
331
427
|
}
|
|
332
428
|
|
|
333
|
-
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);
|
|
334
442
|
}
|
|
335
443
|
|
|
336
444
|
getReferenceFromUrl(): PageReference {
|
|
337
445
|
const [page, docId, deliverable, contentDocumentId] =
|
|
338
|
-
window.location.pathname
|
|
446
|
+
window.location.pathname
|
|
447
|
+
.substr(1)
|
|
448
|
+
.split("/")
|
|
449
|
+
.map(this.sanitizeUrlPart);
|
|
339
450
|
|
|
340
451
|
const { origin: domain, hash, search } = window.location;
|
|
341
452
|
|
|
@@ -344,9 +455,9 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
344
455
|
deliverable,
|
|
345
456
|
docId,
|
|
346
457
|
domain,
|
|
347
|
-
hash,
|
|
458
|
+
hash: this.sanitizeUrlPart(hash),
|
|
348
459
|
page,
|
|
349
|
-
search
|
|
460
|
+
search: this.sanitizeUrlPart(search)
|
|
350
461
|
};
|
|
351
462
|
}
|
|
352
463
|
|
|
@@ -360,12 +471,13 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
360
471
|
);
|
|
361
472
|
}
|
|
362
473
|
|
|
363
|
-
async fetchDocument(): Promise<
|
|
474
|
+
async fetchDocument(): Promise<string> {
|
|
364
475
|
this.setState({
|
|
365
476
|
isFetchingDocument: true
|
|
366
477
|
});
|
|
367
|
-
|
|
368
|
-
|
|
478
|
+
|
|
479
|
+
const data = await this.contentProvider!.fetchDocumentData(
|
|
480
|
+
this.pageReference.docId!
|
|
369
481
|
);
|
|
370
482
|
|
|
371
483
|
// This could be a 404 scenario.
|
|
@@ -373,7 +485,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
373
485
|
this.setState({
|
|
374
486
|
isFetchingDocument: false
|
|
375
487
|
});
|
|
376
|
-
return;
|
|
488
|
+
return "";
|
|
377
489
|
}
|
|
378
490
|
|
|
379
491
|
this.docTitle = data.docTitle;
|
|
@@ -385,23 +497,31 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
385
497
|
this.availableVersions = data.availableVersions;
|
|
386
498
|
this.pdfUrl = data.pdfUrl;
|
|
387
499
|
|
|
388
|
-
this.
|
|
500
|
+
this.updateHeaderAndSidebarFooter();
|
|
501
|
+
|
|
502
|
+
this.buildBreadcrumbs();
|
|
389
503
|
|
|
390
504
|
if (this.pageReference.deliverable !== data.deliverable) {
|
|
391
505
|
this.pageReference.deliverable = data.deliverable;
|
|
392
506
|
this.updateUrl(HistoryState.REPLACE_STATE);
|
|
393
507
|
}
|
|
394
508
|
|
|
509
|
+
if (this.oldVersionInfo) {
|
|
510
|
+
this.showVersionBanner = true;
|
|
511
|
+
} else {
|
|
512
|
+
this.latestVersion = true;
|
|
513
|
+
}
|
|
514
|
+
|
|
395
515
|
if (
|
|
396
516
|
this.pageReference?.contentDocumentId?.replace(/\.htm$/, "") !==
|
|
397
517
|
data.id
|
|
398
518
|
) {
|
|
399
519
|
try {
|
|
400
|
-
await this.fetchContent();
|
|
520
|
+
const moreData = await this.fetchContent();
|
|
401
521
|
this.setState({
|
|
402
522
|
isFetchingDocument: false
|
|
403
523
|
});
|
|
404
|
-
return;
|
|
524
|
+
return moreData.content;
|
|
405
525
|
} catch (error) {
|
|
406
526
|
this.pageReference.contentDocumentId = `${data.id}.htm`;
|
|
407
527
|
this.pageReference.hash = "";
|
|
@@ -415,18 +535,19 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
415
535
|
this.setState({
|
|
416
536
|
isFetchingDocument: false
|
|
417
537
|
});
|
|
538
|
+
return data.content;
|
|
418
539
|
}
|
|
419
540
|
|
|
420
|
-
async fetchContent(): Promise<
|
|
541
|
+
async fetchContent(): Promise<ContentData> {
|
|
421
542
|
this.setState({
|
|
422
543
|
isFetchingContent: true
|
|
423
544
|
});
|
|
424
|
-
const data = await this.contentProvider
|
|
425
|
-
this.pageReference.deliverable
|
|
426
|
-
this.pageReference.contentDocumentId
|
|
545
|
+
const data = await this.contentProvider!.fetchContent(
|
|
546
|
+
this.pageReference.deliverable!,
|
|
547
|
+
this.pageReference.contentDocumentId!,
|
|
427
548
|
{
|
|
428
|
-
language: this.language
|
|
429
|
-
version: this.version
|
|
549
|
+
language: this.language!.id,
|
|
550
|
+
version: this.version!.id
|
|
430
551
|
}
|
|
431
552
|
);
|
|
432
553
|
|
|
@@ -435,19 +556,16 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
435
556
|
this.addMetatags();
|
|
436
557
|
|
|
437
558
|
if (!this.pageReference.hash) {
|
|
438
|
-
document.
|
|
439
|
-
behavior: "smooth",
|
|
440
|
-
block: "start",
|
|
441
|
-
inline: "nearest"
|
|
442
|
-
});
|
|
559
|
+
document.body.scrollIntoView();
|
|
443
560
|
}
|
|
444
561
|
}
|
|
445
562
|
this.setState({
|
|
446
563
|
isFetchingContent: false
|
|
447
564
|
});
|
|
565
|
+
return data;
|
|
448
566
|
}
|
|
449
567
|
|
|
450
|
-
|
|
568
|
+
updateHeaderAndSidebarFooter(): void {
|
|
451
569
|
if (!this.pageHeader) {
|
|
452
570
|
return;
|
|
453
571
|
}
|
|
@@ -457,20 +575,12 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
457
575
|
}
|
|
458
576
|
|
|
459
577
|
if (this.pdfUrl) {
|
|
460
|
-
this.
|
|
461
|
-
this.
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
if (!this.listenerAttached) {
|
|
465
|
-
this.pageHeader.addEventListener(
|
|
466
|
-
"langchange",
|
|
467
|
-
this.handleLanguageChange
|
|
468
|
-
);
|
|
469
|
-
this.listenerAttached = true;
|
|
578
|
+
this.sidebarFooterContent.bailHref = this.pdfUrl;
|
|
579
|
+
this.sidebarFooterContent.bailLabel = "PDF";
|
|
470
580
|
}
|
|
471
581
|
|
|
472
|
-
this.
|
|
473
|
-
this.
|
|
582
|
+
this.sidebarFooterContent.languages = this.availableLanguages;
|
|
583
|
+
this.sidebarFooterContent.language = this.language?.id;
|
|
474
584
|
|
|
475
585
|
if (this.pageReference) {
|
|
476
586
|
const { docId, deliverable, page } = this.pageReference;
|
|
@@ -479,6 +589,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
479
589
|
}
|
|
480
590
|
|
|
481
591
|
updateUrl(method = HistoryState.PUSH_STATE): void {
|
|
592
|
+
logCoveoPageView(this.coveoOrganizationId, this.coveoAnalyticsToken);
|
|
482
593
|
window.history[method](
|
|
483
594
|
{},
|
|
484
595
|
"docs",
|
|
@@ -494,23 +605,24 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
494
605
|
}
|
|
495
606
|
|
|
496
607
|
private updateSearchInput(searchParam: string): void {
|
|
497
|
-
this.
|
|
498
|
-
.querySelector("doc-content-layout")
|
|
499
|
-
?.setSidebarInputValue(searchParam);
|
|
608
|
+
(this.refs.docContentLayout as any)?.setSidebarInputValue(searchParam);
|
|
500
609
|
}
|
|
501
610
|
|
|
502
611
|
private pageReferenceToString(reference: PageReference): string {
|
|
503
612
|
const { page, docId, deliverable, contentDocumentId, hash, search } =
|
|
504
613
|
reference;
|
|
505
614
|
return `/${page}/${docId}/${deliverable}/${contentDocumentId}${this.normalizeSearch(
|
|
506
|
-
search
|
|
615
|
+
search!
|
|
507
616
|
)}${this.normalizeHash(hash)}`;
|
|
508
617
|
}
|
|
509
618
|
|
|
510
|
-
private normalizeUrlPart(
|
|
619
|
+
private normalizeUrlPart(
|
|
620
|
+
part: string | undefined,
|
|
621
|
+
sentinel: string
|
|
622
|
+
): string {
|
|
511
623
|
return (
|
|
512
624
|
(part &&
|
|
513
|
-
(part.startsWith(sentinel) ? part : `${sentinel}${part}`)) ||
|
|
625
|
+
(part.startsWith(sentinel!) ? part : `${sentinel}${part}`)) ||
|
|
514
626
|
""
|
|
515
627
|
);
|
|
516
628
|
}
|
|
@@ -519,16 +631,16 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
519
631
|
return this.normalizeUrlPart(search, "?");
|
|
520
632
|
}
|
|
521
633
|
|
|
522
|
-
private normalizeHash(hash
|
|
634
|
+
private normalizeHash(hash?: string): string {
|
|
523
635
|
return this.normalizeUrlPart(hash, "#");
|
|
524
636
|
}
|
|
525
637
|
|
|
526
638
|
private getComposedTitle(
|
|
527
|
-
topicTitle: string | undefined,
|
|
639
|
+
topicTitle: string | null | undefined,
|
|
528
640
|
docTitle: string | undefined
|
|
529
641
|
): string {
|
|
530
642
|
// map to avoid duplicates
|
|
531
|
-
const titleMap = {};
|
|
643
|
+
const titleMap: { [key: string]: any } = {};
|
|
532
644
|
if (topicTitle) {
|
|
533
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",
|
|
534
646
|
// here it contains \n in the text context which needs to be removed
|
|
@@ -559,16 +671,65 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
559
671
|
);
|
|
560
672
|
}
|
|
561
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
|
+
|
|
562
723
|
addMetatags(): void {
|
|
563
724
|
const div = document.createElement("div");
|
|
564
|
-
div.innerHTML = this.docContent;
|
|
725
|
+
div.innerHTML = DOMPurify.sanitize(this.docContent);
|
|
565
726
|
const docDescription = div.querySelector(".shortdesc")?.textContent;
|
|
566
727
|
const topicTitle = div.querySelector("h1")?.textContent;
|
|
567
728
|
|
|
568
729
|
const title = document.querySelector("title");
|
|
569
730
|
const composedTitle = this.getComposedTitle(topicTitle, this.docTitle);
|
|
570
731
|
|
|
571
|
-
if (title) {
|
|
732
|
+
if (title && title.textContent) {
|
|
572
733
|
title.textContent = composedTitle;
|
|
573
734
|
}
|
|
574
735
|
const metatitle = document.querySelector('meta[name="title"]');
|
|
@@ -584,5 +745,58 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
584
745
|
metadescription.setAttribute("content", docDescription);
|
|
585
746
|
}
|
|
586
747
|
}
|
|
748
|
+
|
|
749
|
+
if (this.pageReference) {
|
|
750
|
+
const metadescription = document.querySelector(
|
|
751
|
+
'link[rel="canonical"]'
|
|
752
|
+
);
|
|
753
|
+
if (metadescription) {
|
|
754
|
+
const copyPageReference = { ...this.pageReference };
|
|
755
|
+
copyPageReference.docId = copyPageReference.docId
|
|
756
|
+
? this.dropVersionFromDocId(copyPageReference.docId)
|
|
757
|
+
: copyPageReference.docId;
|
|
758
|
+
metadescription.setAttribute(
|
|
759
|
+
"href",
|
|
760
|
+
window.location.protocol +
|
|
761
|
+
"//" +
|
|
762
|
+
window.location.host +
|
|
763
|
+
this.pageReferenceToString(copyPageReference)
|
|
764
|
+
);
|
|
765
|
+
}
|
|
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;
|
|
587
801
|
}
|
|
588
802
|
}
|