@salesforcedevs/docs-components 0.54.0-alpha04 → 0.54.1-a01
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/package.json +1 -2
- package/src/modules/doc/amfReference/amfReference.html +13 -5
- package/src/modules/doc/amfReference/amfReference.ts +799 -303
- package/src/modules/doc/amfReference/constants.ts +76 -0
- package/src/modules/doc/amfReference/types.ts +50 -5
- package/src/modules/doc/amfTopic/types.ts +1 -1
- package/src/modules/doc/amfTopic/utils.ts +20 -7
- 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 +17 -1
- package/src/modules/doc/breadcrumbs/breadcrumbs.css +9 -1
- package/src/modules/doc/breadcrumbs/breadcrumbs.html +12 -2
- package/src/modules/doc/breadcrumbs/breadcrumbs.ts +49 -8
- package/src/modules/doc/content/content.css +31 -7
- package/src/modules/doc/content/content.ts +17 -2
- package/src/modules/doc/contentCallout/contentCallout.ts +5 -0
- package/src/modules/doc/contentLayout/contentLayout.css +8 -10
- package/src/modules/doc/contentLayout/contentLayout.html +2 -9
- package/src/modules/doc/contentLayout/contentLayout.ts +74 -29
- package/src/modules/doc/header/header.ts +3 -3
- package/src/modules/doc/headingContent/headingContent.css +4 -0
- package/src/modules/doc/xmlContent/types.ts +6 -11
- package/src/modules/doc/xmlContent/utils.ts +18 -20
- package/src/modules/doc/xmlContent/xmlContent.css +7 -0
- package/src/modules/doc/xmlContent/xmlContent.html +6 -1
- package/src/modules/doc/xmlContent/xmlContent.ts +132 -34
- package/src/modules/doc/amfReference/route-meta.ts +0 -22
|
@@ -20,6 +20,7 @@ const HIGHLIGHTABLE_SELECTOR = [
|
|
|
20
20
|
"th",
|
|
21
21
|
"td"
|
|
22
22
|
].join(",");
|
|
23
|
+
const OBSERVER_ATTACH_WAIT_TIME = 500;
|
|
23
24
|
|
|
24
25
|
export default class ContentLayout extends LightningElement {
|
|
25
26
|
@api sidebarValue: string;
|
|
@@ -95,6 +96,8 @@ export default class ContentLayout extends LightningElement {
|
|
|
95
96
|
target: window
|
|
96
97
|
});
|
|
97
98
|
private tocValue?: string = undefined;
|
|
99
|
+
private observerTimerId = null;
|
|
100
|
+
private didScrollToSelectedHash = false;
|
|
98
101
|
|
|
99
102
|
get showToc(): boolean {
|
|
100
103
|
return this.tocOptions && this.tocOptions.length > 0;
|
|
@@ -119,6 +122,18 @@ export default class ContentLayout extends LightningElement {
|
|
|
119
122
|
}
|
|
120
123
|
}
|
|
121
124
|
|
|
125
|
+
renderedCallback(): void {
|
|
126
|
+
/**
|
|
127
|
+
* Note: We are adding timeout because chrome is optimizing and not triggering recent renderedCallback though elements reference is changed
|
|
128
|
+
* Also we are considering recent renderedCallback
|
|
129
|
+
*/
|
|
130
|
+
this.clearRenderObserverTimer();
|
|
131
|
+
this.observerTimerId = setTimeout(
|
|
132
|
+
this.attachInteractionObserver,
|
|
133
|
+
OBSERVER_ATTACH_WAIT_TIME
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
122
137
|
disconnectedCallback(): void {
|
|
123
138
|
this.disconnectObserver();
|
|
124
139
|
window.removeEventListener(
|
|
@@ -126,19 +141,25 @@ export default class ContentLayout extends LightningElement {
|
|
|
126
141
|
this.updateHighlighted
|
|
127
142
|
);
|
|
128
143
|
this.searchSyncer.dispose();
|
|
144
|
+
this.clearRenderObserverTimer();
|
|
129
145
|
}
|
|
130
146
|
|
|
147
|
+
clearRenderObserverTimer = () => {
|
|
148
|
+
if (this.observerTimerId) {
|
|
149
|
+
clearTimeout(this.observerTimerId);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
131
153
|
updateHighlighted = (event: Event): void =>
|
|
132
154
|
highlightTerms(
|
|
133
155
|
this.querySelectorAll(HIGHLIGHTABLE_SELECTOR),
|
|
134
156
|
(event as CustomEvent<string>).detail
|
|
135
157
|
);
|
|
136
158
|
|
|
137
|
-
|
|
159
|
+
attachInteractionObserver = (): void => {
|
|
138
160
|
if (!this.enableSlotChange) {
|
|
139
161
|
return;
|
|
140
162
|
}
|
|
141
|
-
|
|
142
163
|
this.disconnectObserver();
|
|
143
164
|
this.observer = new IntersectionObserver((entries) => {
|
|
144
165
|
entries.forEach(
|
|
@@ -150,30 +171,54 @@ export default class ContentLayout extends LightningElement {
|
|
|
150
171
|
this.calculateActualSection();
|
|
151
172
|
});
|
|
152
173
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
return tag;
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
this._tocOptions = anchoredTags.map((tag) => ({
|
|
162
|
-
anchor: `#${tag.hash}`,
|
|
163
|
-
id: tag.id,
|
|
164
|
-
label: tag.title
|
|
165
|
-
}));
|
|
166
|
-
|
|
167
|
-
this.scrollToHash(anchoredTags);
|
|
168
|
-
|
|
169
|
-
anchoredTags.forEach((section) => {
|
|
170
|
-
const id = section.getAttribute("id");
|
|
174
|
+
// Note: We are doing document.querySelectorAll as a quick fix as we are not getting heading elements reference this.querySelectorAll
|
|
175
|
+
const headingElements = document.querySelectorAll(TOC_HEADER_TAG);
|
|
176
|
+
for (const headingElement of headingElements) {
|
|
177
|
+
// Add headingElements to intersectionObserver for highlighting respective RNB item when user scroll
|
|
178
|
+
const id = headingElement.getAttribute("id");
|
|
171
179
|
this.anchoredElements[id] = {
|
|
172
180
|
id,
|
|
173
181
|
intersect: false
|
|
174
182
|
};
|
|
175
|
-
this.observer.observe(
|
|
176
|
-
}
|
|
183
|
+
this.observer.observe(headingElement);
|
|
184
|
+
}
|
|
185
|
+
if (!this.didScrollToSelectedHash) {
|
|
186
|
+
this.didScrollToSelectedHash = true;
|
|
187
|
+
this.scrollToHash(headingElements);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
onSlotChange(event: Event): void {
|
|
192
|
+
const slotElements = (
|
|
193
|
+
event.target as HTMLSlotElement
|
|
194
|
+
).assignedElements();
|
|
195
|
+
|
|
196
|
+
if (slotElements.length) {
|
|
197
|
+
const slotContentElement = slotElements[0];
|
|
198
|
+
const headingElements =
|
|
199
|
+
slotContentElement.ownerDocument?.getElementsByTagName(
|
|
200
|
+
TOC_HEADER_TAG
|
|
201
|
+
);
|
|
202
|
+
for (const headingElement of headingElements) {
|
|
203
|
+
// Sometimes elements hash is not being set when slot content is wrapped with div
|
|
204
|
+
headingElement.hash =
|
|
205
|
+
headingElement.attributes.hash?.nodeValue;
|
|
206
|
+
}
|
|
207
|
+
const tocOptions = [];
|
|
208
|
+
for (const headingElement of headingElements) {
|
|
209
|
+
headingElement.id = headingElement.hash;
|
|
210
|
+
|
|
211
|
+
// Update tocOptions from anchorTags
|
|
212
|
+
const tocItem = {
|
|
213
|
+
anchor: `#${headingElement.hash}`,
|
|
214
|
+
id: headingElement.id,
|
|
215
|
+
label: headingElement.title
|
|
216
|
+
};
|
|
217
|
+
tocOptions.push(tocItem);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
this._tocOptions = tocOptions;
|
|
221
|
+
}
|
|
177
222
|
}
|
|
178
223
|
|
|
179
224
|
private disconnectObserver(): void {
|
|
@@ -183,16 +228,16 @@ export default class ContentLayout extends LightningElement {
|
|
|
183
228
|
}
|
|
184
229
|
}
|
|
185
230
|
|
|
186
|
-
|
|
231
|
+
// eslint-disable-next-line no-undef
|
|
232
|
+
private scrollToHash(headingElements: NodeListOf<Element>): void {
|
|
187
233
|
let { hash } = window.location;
|
|
188
|
-
|
|
189
234
|
if (hash) {
|
|
190
235
|
hash = hash.substr(1);
|
|
191
|
-
const
|
|
192
|
-
(
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
236
|
+
for (const headingElement of headingElements) {
|
|
237
|
+
if (headingElement.getAttribute("id") === hash) {
|
|
238
|
+
headingElement.scrollIntoView({ behavior: "auto" });
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
196
241
|
}
|
|
197
242
|
}
|
|
198
243
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { api } from "lwc";
|
|
2
2
|
import cx from "classnames";
|
|
3
|
-
import type {
|
|
3
|
+
import type { OptionWithNested, OptionWithLink } from "typings/custom";
|
|
4
4
|
import { HeaderBase } from "dxBaseElements/headerBase";
|
|
5
5
|
import { toJson } from "dxUtils/normalizers";
|
|
6
6
|
import get from "lodash.get";
|
|
@@ -43,8 +43,8 @@ export default class Header extends HeaderBase {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
private _language: string | null = null;
|
|
46
|
-
private _languages!:
|
|
47
|
-
private _scopedNavItems!:
|
|
46
|
+
private _languages!: OptionWithLink[];
|
|
47
|
+
private _scopedNavItems!: OptionWithNested[];
|
|
48
48
|
private smallMobile = false;
|
|
49
49
|
private smallMobileMatchMedia!: MediaQueryList;
|
|
50
50
|
private tablet = false;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
export type CoveoAdvancedQueryXMLConfig = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
sfdelivarable__c?: string;
|
|
6
|
-
source?: string;
|
|
2
|
+
locale?: string;
|
|
3
|
+
version?: string;
|
|
4
|
+
topicid?: string;
|
|
7
5
|
};
|
|
8
6
|
|
|
9
7
|
export type PageReference = {
|
|
@@ -21,17 +19,12 @@ export enum HistoryState {
|
|
|
21
19
|
REPLACE_STATE = "replaceState"
|
|
22
20
|
}
|
|
23
21
|
|
|
24
|
-
export type Labels = {
|
|
25
|
-
language_english: string;
|
|
26
|
-
language_japanese: string;
|
|
27
|
-
toc_title: string;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
22
|
export type TreeNode = {
|
|
31
23
|
label: string;
|
|
32
24
|
name: string;
|
|
33
25
|
children?: Array<TreeNode>;
|
|
34
26
|
isExpanded?: boolean;
|
|
27
|
+
parent?: TreeNode;
|
|
35
28
|
};
|
|
36
29
|
|
|
37
30
|
type DropdownOption = {
|
|
@@ -117,3 +110,5 @@ export type ContentApiOptions = {
|
|
|
117
110
|
version: string;
|
|
118
111
|
language: string;
|
|
119
112
|
};
|
|
113
|
+
|
|
114
|
+
export type TocMap = { [key: string]: TreeNode };
|
|
@@ -8,22 +8,19 @@ import {
|
|
|
8
8
|
DocumentData,
|
|
9
9
|
DocLanguage,
|
|
10
10
|
DocVersion,
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
TreeNode,
|
|
12
|
+
TocMap
|
|
13
13
|
} from "./types";
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"en-us": "language_english",
|
|
17
|
-
"ja-jp": "language_japanese"
|
|
18
|
-
};
|
|
14
|
+
import { Language } from "typings/custom";
|
|
15
|
+
import { getLanguageDisplayTextById } from "dxUtils/language";
|
|
19
16
|
|
|
20
17
|
export class FetchContent {
|
|
21
18
|
private apiDomain: string;
|
|
22
|
-
private
|
|
19
|
+
private languages: Array<Language> = [];
|
|
23
20
|
|
|
24
|
-
constructor(apiDomain: string,
|
|
21
|
+
constructor(apiDomain: string, languages: Array<Language>) {
|
|
25
22
|
this.apiDomain = apiDomain;
|
|
26
|
-
this.
|
|
23
|
+
this.languages = languages;
|
|
27
24
|
}
|
|
28
25
|
|
|
29
26
|
async fetchDocumentData(docId: string): Promise<DocumentData | null> {
|
|
@@ -104,26 +101,26 @@ export class FetchContent {
|
|
|
104
101
|
|
|
105
102
|
private normalizeNavItem(
|
|
106
103
|
navItem: ApiNavItem,
|
|
107
|
-
tocMap:
|
|
104
|
+
tocMap: TocMap,
|
|
105
|
+
parentNavItem?: TreeNode
|
|
108
106
|
): TreeNode {
|
|
109
107
|
const name = this.calculateNavItemName(navItem, tocMap);
|
|
110
108
|
const node: TreeNode = {
|
|
111
109
|
label: navItem.text,
|
|
112
|
-
name
|
|
110
|
+
name,
|
|
111
|
+
parent: parentNavItem
|
|
113
112
|
};
|
|
113
|
+
|
|
114
114
|
if (name) {
|
|
115
115
|
tocMap[name] = node;
|
|
116
116
|
}
|
|
117
117
|
node.children = navItem.children?.map((child) =>
|
|
118
|
-
this.normalizeNavItem(child, tocMap)
|
|
118
|
+
this.normalizeNavItem(child, tocMap, node)
|
|
119
119
|
);
|
|
120
120
|
return node;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
private calculateNavItemName(
|
|
124
|
-
navItem: ApiNavItem,
|
|
125
|
-
tocMap: { [key: string]: TreeNode }
|
|
126
|
-
): string {
|
|
123
|
+
private calculateNavItemName(navItem: ApiNavItem, tocMap: TocMap): string {
|
|
127
124
|
let href = navItem.a_attr?.href || "";
|
|
128
125
|
if (href.includes("#")) {
|
|
129
126
|
const [pathUrl] = href.split("#");
|
|
@@ -148,12 +145,13 @@ export class FetchContent {
|
|
|
148
145
|
}
|
|
149
146
|
|
|
150
147
|
private normalizeLanguage(language: ApiDocLanguage): DocLanguage {
|
|
151
|
-
const labelKey = language.locale && LOCALE_TO_LABEL[language.locale];
|
|
152
148
|
return (
|
|
153
149
|
language && {
|
|
154
150
|
label:
|
|
155
|
-
(
|
|
156
|
-
|
|
151
|
+
getLanguageDisplayTextById(
|
|
152
|
+
this.languages,
|
|
153
|
+
language.locale
|
|
154
|
+
) || language.label,
|
|
157
155
|
id: language.locale,
|
|
158
156
|
code: language.code,
|
|
159
157
|
url: language.url
|
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
--button-primary-color-hover: var(--dx-g-blue-vibrant-40);
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
+
doc-breadcrumbs {
|
|
7
|
+
--dx-c-popover-z-index: 5;
|
|
8
|
+
|
|
9
|
+
display: block;
|
|
10
|
+
margin-bottom: var(--dx-g-spacing-2xl);
|
|
11
|
+
}
|
|
12
|
+
|
|
6
13
|
dx-dropdown {
|
|
7
14
|
--dx-c-dropdown-option-font-size: var(--dx-g-text-sm);
|
|
8
15
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
sidebar-content={sidebarContent}
|
|
10
10
|
sidebar-value={sidebarValue}
|
|
11
11
|
onselect={handleSelect}
|
|
12
|
-
use-old-sidebar
|
|
12
|
+
use-old-sidebar={useOldSidebar}
|
|
13
13
|
>
|
|
14
14
|
<div slot="sidebar-header" class="document-pickers">
|
|
15
15
|
<dx-dropdown
|
|
@@ -25,6 +25,11 @@
|
|
|
25
25
|
</dx-button>
|
|
26
26
|
</dx-dropdown>
|
|
27
27
|
</div>
|
|
28
|
+
<doc-breadcrumbs
|
|
29
|
+
if:true={breadcrumbs}
|
|
30
|
+
breadcrumbs={breadcrumbs}
|
|
31
|
+
pixel-per-character={breadcrumbPixelPerCharacter}
|
|
32
|
+
></doc-breadcrumbs>
|
|
28
33
|
<doc-content
|
|
29
34
|
docs-data={docContent}
|
|
30
35
|
page-reference={pageReference}
|
|
@@ -1,22 +1,33 @@
|
|
|
1
1
|
import { api, track } from "lwc";
|
|
2
|
-
import {
|
|
2
|
+
import { normalizeBoolean } from "dxUtils/normalizers";
|
|
3
3
|
import { FetchContent } from "./utils";
|
|
4
4
|
import {
|
|
5
5
|
CoveoAdvancedQueryXMLConfig,
|
|
6
6
|
DocLanguage,
|
|
7
7
|
DocVersion,
|
|
8
|
-
Labels,
|
|
9
8
|
TreeNode,
|
|
10
9
|
Header,
|
|
11
10
|
HistoryState,
|
|
12
|
-
PageReference
|
|
11
|
+
PageReference,
|
|
12
|
+
TocMap
|
|
13
13
|
} from "./types";
|
|
14
14
|
import { SearchSyncer } from "docUtils/SearchSyncer";
|
|
15
15
|
import { LightningElementWithState } from "docBaseElements/lightningElementWithState";
|
|
16
|
+
import { Breadcrumb, Language } from "typings/custom";
|
|
16
17
|
|
|
17
18
|
// TODO: Imitating from actual implementation as doc-content use it like this. We should refactor it later.
|
|
18
19
|
const handleContentError = (error): void => console.log(error);
|
|
19
20
|
|
|
21
|
+
const FIRST_CRUMB = {
|
|
22
|
+
href: "/docs",
|
|
23
|
+
label: "Documentation"
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const PIXEL_PER_CHARACTER_MAP: { [key: string]: number } = {
|
|
27
|
+
default: 7.7,
|
|
28
|
+
"ja-jp": 12.5
|
|
29
|
+
};
|
|
30
|
+
|
|
20
31
|
export default class DocXmlContent extends LightningElementWithState<{
|
|
21
32
|
isFetchingDocument: boolean;
|
|
22
33
|
isFetchingContent: boolean;
|
|
@@ -27,15 +38,25 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
27
38
|
@api coveoPublicAccessToken!: string;
|
|
28
39
|
|
|
29
40
|
@api
|
|
30
|
-
get
|
|
31
|
-
return this.
|
|
41
|
+
get allLanguages(): Array<Language> {
|
|
42
|
+
return this._allLanguages;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
set allLanguages(value: string) {
|
|
46
|
+
if (value) {
|
|
47
|
+
this._allLanguages = JSON.parse(value);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@api
|
|
52
|
+
get enableCoveo() {
|
|
53
|
+
return this._enableCoveo;
|
|
32
54
|
}
|
|
33
55
|
|
|
34
|
-
set
|
|
35
|
-
this.
|
|
56
|
+
set enableCoveo(value) {
|
|
57
|
+
this._enableCoveo = normalizeBoolean(value);
|
|
36
58
|
}
|
|
37
59
|
|
|
38
|
-
private _labels: Labels = null;
|
|
39
60
|
private availableLanguages: Array<DocLanguage> = [];
|
|
40
61
|
private availableVersions: Array<DocVersion> = [];
|
|
41
62
|
private contentProvider: FetchContent;
|
|
@@ -43,7 +64,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
43
64
|
private language: DocLanguage = null;
|
|
44
65
|
private loaded = false;
|
|
45
66
|
private pdfUrl = "";
|
|
46
|
-
private tocMap =
|
|
67
|
+
private tocMap: TocMap = {};
|
|
47
68
|
private sidebarContent: Array<TreeNode> = null;
|
|
48
69
|
private version: DocVersion = null;
|
|
49
70
|
private docTitle = "";
|
|
@@ -51,6 +72,8 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
51
72
|
private _pathName = "";
|
|
52
73
|
private _pageHeader?: Header;
|
|
53
74
|
private listenerAttached = false;
|
|
75
|
+
private _enableCoveo?: boolean = false;
|
|
76
|
+
|
|
54
77
|
private searchSyncer = new SearchSyncer({
|
|
55
78
|
callbacks: {
|
|
56
79
|
onSearchChange: (nextSearchString: string): void => {
|
|
@@ -87,8 +110,10 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
87
110
|
shouldStopPropagation: true,
|
|
88
111
|
target: window
|
|
89
112
|
});
|
|
113
|
+
private _allLanguages: Array<Language> = [];
|
|
90
114
|
|
|
91
115
|
@track private pageReference: PageReference = {};
|
|
116
|
+
@track breadcrumbs: Array<Breadcrumb> = [];
|
|
92
117
|
|
|
93
118
|
constructor() {
|
|
94
119
|
super();
|
|
@@ -109,8 +134,10 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
109
134
|
window.location.href = "/docs";
|
|
110
135
|
return;
|
|
111
136
|
}
|
|
112
|
-
|
|
113
|
-
|
|
137
|
+
this.contentProvider = new FetchContent(
|
|
138
|
+
this.apiDomain,
|
|
139
|
+
this.allLanguages
|
|
140
|
+
);
|
|
114
141
|
this.fetchDocument().then(() => (this.loaded = true));
|
|
115
142
|
window.addEventListener("popstate", this.handlePopState);
|
|
116
143
|
|
|
@@ -180,18 +207,33 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
180
207
|
return this.pageReference.deliverable;
|
|
181
208
|
}
|
|
182
209
|
|
|
210
|
+
private get useOldSidebar(): boolean {
|
|
211
|
+
// Coveo is enabled and the version is greater than 51 (within the latest 3 versions)
|
|
212
|
+
// TODO: we need a better fix for version number check
|
|
213
|
+
return !(
|
|
214
|
+
this.enableCoveo &&
|
|
215
|
+
this.coveoOrganizationId &&
|
|
216
|
+
this.coveoPublicAccessToken &&
|
|
217
|
+
(!this.version?.releaseVersion ||
|
|
218
|
+
(this.version?.releaseVersion &&
|
|
219
|
+
parseInt(
|
|
220
|
+
this.version.releaseVersion.replace("v", ""),
|
|
221
|
+
10
|
|
222
|
+
) >= 53))
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
183
226
|
private get coveoAdvancedQueryConfig(): CoveoAdvancedQueryXMLConfig {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
? { source: "Sitemap - Developer Docs Atlas - Apexref" }
|
|
188
|
-
: {
|
|
189
|
-
objecttype: "HTDeveloperDocumentsC",
|
|
190
|
-
sflocale__c: this.languageId,
|
|
191
|
-
sfrelease__c: this.releaseVersionId,
|
|
192
|
-
sfdelivarable__c: this.deliverable
|
|
193
|
-
})
|
|
227
|
+
const config: { locale: string; topicid: string; version?: string } = {
|
|
228
|
+
locale: this.languageId,
|
|
229
|
+
topicid: this.deliverable
|
|
194
230
|
};
|
|
231
|
+
|
|
232
|
+
if (this.releaseVersionId && this.releaseVersionId !== "noversion") {
|
|
233
|
+
config.version = this.releaseVersionId;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return config;
|
|
195
237
|
}
|
|
196
238
|
|
|
197
239
|
private get pageHeader(): Header {
|
|
@@ -237,6 +279,13 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
237
279
|
}));
|
|
238
280
|
}
|
|
239
281
|
|
|
282
|
+
private get breadcrumbPixelPerCharacter() {
|
|
283
|
+
return (
|
|
284
|
+
PIXEL_PER_CHARACTER_MAP[this.language.id] ||
|
|
285
|
+
PIXEL_PER_CHARACTER_MAP.default
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
240
289
|
private handlePopState = (): void =>
|
|
241
290
|
this.updatePageReference(this.getReferenceFromUrl());
|
|
242
291
|
|
|
@@ -250,15 +299,15 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
250
299
|
|
|
251
300
|
if (name) {
|
|
252
301
|
const hashIndex = name.indexOf("#");
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
this.pageReference
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
302
|
+
const hash = hashIndex > -1 ? name.slice(hashIndex) : "";
|
|
303
|
+
|
|
304
|
+
const contentDocumentId =
|
|
305
|
+
hashIndex > -1 ? name.slice(0, hashIndex) : name;
|
|
306
|
+
this.updatePageReference({
|
|
307
|
+
...this.pageReference,
|
|
308
|
+
contentDocumentId,
|
|
309
|
+
hash
|
|
310
|
+
});
|
|
262
311
|
this.updateUrl();
|
|
263
312
|
}
|
|
264
313
|
}
|
|
@@ -291,15 +340,17 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
291
340
|
return;
|
|
292
341
|
}
|
|
293
342
|
|
|
294
|
-
const isSameDocId = this.pageReference.docId
|
|
343
|
+
const isSameDocId = this.pageReference.docId === newPageReference.docId;
|
|
295
344
|
this.pageReference = newPageReference;
|
|
296
345
|
|
|
297
|
-
if (isSameDocId) {
|
|
346
|
+
if (!isSameDocId) {
|
|
298
347
|
this.fetchDocument();
|
|
299
348
|
return;
|
|
300
349
|
}
|
|
301
350
|
|
|
302
|
-
this.fetchContent()
|
|
351
|
+
this.fetchContent()
|
|
352
|
+
.then(() => this.buildBreadcrumbs())
|
|
353
|
+
.catch(handleContentError);
|
|
303
354
|
}
|
|
304
355
|
|
|
305
356
|
getReferenceFromUrl(): PageReference {
|
|
@@ -356,6 +407,8 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
356
407
|
|
|
357
408
|
this.updateHeader();
|
|
358
409
|
|
|
410
|
+
this.buildBreadcrumbs();
|
|
411
|
+
|
|
359
412
|
if (this.pageReference.deliverable !== data.deliverable) {
|
|
360
413
|
this.pageReference.deliverable = data.deliverable;
|
|
361
414
|
this.updateUrl(HistoryState.REPLACE_STATE);
|
|
@@ -404,7 +457,11 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
404
457
|
this.addMetatags();
|
|
405
458
|
|
|
406
459
|
if (!this.pageReference.hash) {
|
|
407
|
-
|
|
460
|
+
document.querySelector("main")?.scrollIntoView({
|
|
461
|
+
behavior: "smooth",
|
|
462
|
+
block: "start",
|
|
463
|
+
inline: "nearest"
|
|
464
|
+
});
|
|
408
465
|
}
|
|
409
466
|
}
|
|
410
467
|
this.setState({
|
|
@@ -524,6 +581,32 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
524
581
|
);
|
|
525
582
|
}
|
|
526
583
|
|
|
584
|
+
private buildBreadcrumbs(): void {
|
|
585
|
+
const { contentDocumentId } = this.pageReference;
|
|
586
|
+
if (!contentDocumentId) {
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
const currentNode = this.tocMap[contentDocumentId];
|
|
591
|
+
this.breadcrumbs = this.nodeToBreadcrumb(currentNode);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
private nodeToBreadcrumb(node?: TreeNode): Breadcrumb[] {
|
|
595
|
+
if (!node) {
|
|
596
|
+
return [FIRST_CRUMB];
|
|
597
|
+
}
|
|
598
|
+
return [
|
|
599
|
+
...this.nodeToBreadcrumb(node.parent),
|
|
600
|
+
{
|
|
601
|
+
href: this.pageReferenceToString({
|
|
602
|
+
...this.pageReference,
|
|
603
|
+
contentDocumentId: node.name
|
|
604
|
+
}),
|
|
605
|
+
label: node.label
|
|
606
|
+
}
|
|
607
|
+
];
|
|
608
|
+
}
|
|
609
|
+
|
|
527
610
|
addMetatags(): void {
|
|
528
611
|
const div = document.createElement("div");
|
|
529
612
|
div.innerHTML = this.docContent;
|
|
@@ -549,5 +632,20 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
549
632
|
metadescription.setAttribute("content", docDescription);
|
|
550
633
|
}
|
|
551
634
|
}
|
|
635
|
+
|
|
636
|
+
if (this.pageReference) {
|
|
637
|
+
const metadescription = document.querySelector(
|
|
638
|
+
'link[rel="canonical"]'
|
|
639
|
+
);
|
|
640
|
+
if (metadescription) {
|
|
641
|
+
metadescription.setAttribute(
|
|
642
|
+
"href",
|
|
643
|
+
window.location.protocol +
|
|
644
|
+
"//" +
|
|
645
|
+
window.location.host +
|
|
646
|
+
this.pageReferenceToString(this.pageReference)
|
|
647
|
+
);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
552
650
|
}
|
|
553
651
|
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Represents the URL reference meta on Reference page.
|
|
3
|
-
* Contains information on selected Reference ID, Topic ID, and Topic Type
|
|
4
|
-
* separated by ":"
|
|
5
|
-
*/
|
|
6
|
-
export class RouteMeta {
|
|
7
|
-
meta: string;
|
|
8
|
-
referenceId = "";
|
|
9
|
-
topicId = "";
|
|
10
|
-
type = "";
|
|
11
|
-
|
|
12
|
-
constructor(meta: string) {
|
|
13
|
-
this.meta = meta;
|
|
14
|
-
|
|
15
|
-
if (meta && meta.includes(":")) {
|
|
16
|
-
const [referenceId, type, topicId] = meta.split(":");
|
|
17
|
-
this.referenceId = referenceId;
|
|
18
|
-
this.topicId = topicId || type;
|
|
19
|
-
this.type = type;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|