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