@salesforcedevs/docs-components 1.3.155 → 1.3.166-alpha
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 +2 -2
- package/src/modules/doc/amfReference/amfReference.ts +28 -16
- package/src/modules/doc/amfReference/utils.ts +8 -4
- package/src/modules/doc/amfTopic/amfTopic.ts +12 -7
- package/src/modules/doc/amfTopic/types.ts +14 -12
- package/src/modules/doc/amfTopic/utils.ts +12 -6
- package/src/modules/doc/content/content.ts +10 -11
- package/src/modules/doc/contentLayout/contentLayout.ts +28 -25
- package/src/modules/doc/heading/heading.ts +2 -0
- package/src/modules/doc/toc/toc.ts +1 -1
- package/src/modules/docUtils/SearchSyncer/SearchSyncer.ts +6 -6
- package/LICENSE +0 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforcedevs/docs-components",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.166-alpha",
|
|
4
4
|
"description": "Docs Lightning web components for DSC",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "index.js",
|
|
@@ -24,5 +24,5 @@
|
|
|
24
24
|
"@types/lodash.orderby": "^4.6.7",
|
|
25
25
|
"@types/lodash.uniqby": "^4.7.7"
|
|
26
26
|
},
|
|
27
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "4629fdd9ca18a13480044ad43515b91945d16aad"
|
|
28
28
|
}
|
|
@@ -30,6 +30,14 @@ import { restoreScroll } from "dx/scrollManager";
|
|
|
30
30
|
import { DocPhaseInfo } from "typings/custom";
|
|
31
31
|
import { oldVersionDocInfo } from "docUtils/utils";
|
|
32
32
|
|
|
33
|
+
type NavigationItem = {
|
|
34
|
+
label: string;
|
|
35
|
+
name: string;
|
|
36
|
+
isExpanded: boolean;
|
|
37
|
+
children: ParsedMarkdownTopic[];
|
|
38
|
+
isChildrenLoading: boolean;
|
|
39
|
+
};
|
|
40
|
+
|
|
33
41
|
export default class AmfReference extends LightningElement {
|
|
34
42
|
@api breadcrumbs?: string | null | undefined = null;
|
|
35
43
|
@api sidebarHeader!: string;
|
|
@@ -41,7 +49,7 @@ export default class AmfReference extends LightningElement {
|
|
|
41
49
|
@api useOldSidebar?: boolean = false;
|
|
42
50
|
@api tocTitle?: string;
|
|
43
51
|
@api tocOptions?: string;
|
|
44
|
-
@track navigation = [];
|
|
52
|
+
@track navigation = [] as NavigationItem[];
|
|
45
53
|
@track versions: Array<ReferenceVersion> = [];
|
|
46
54
|
@track showVersionBanner = false;
|
|
47
55
|
|
|
@@ -125,8 +133,8 @@ export default class AmfReference extends LightningElement {
|
|
|
125
133
|
}
|
|
126
134
|
|
|
127
135
|
@api
|
|
128
|
-
get docPhaseInfo() {
|
|
129
|
-
return this.selectedReferenceDocPhase;
|
|
136
|
+
get docPhaseInfo(): string | null {
|
|
137
|
+
return this.selectedReferenceDocPhase || null;
|
|
130
138
|
}
|
|
131
139
|
|
|
132
140
|
set docPhaseInfo(value: string) {
|
|
@@ -151,9 +159,9 @@ export default class AmfReference extends LightningElement {
|
|
|
151
159
|
protected _referenceSetConfig!: ReferenceSetConfig;
|
|
152
160
|
protected _currentReferenceId = "";
|
|
153
161
|
|
|
154
|
-
protected parentReferenceUrls = [];
|
|
162
|
+
protected parentReferenceUrls = [] as string[];
|
|
155
163
|
protected amfMap: Record<string, AmfModelRecord> = {};
|
|
156
|
-
protected amfFetchPromiseMap = {};
|
|
164
|
+
protected amfFetchPromiseMap = {} as any;
|
|
157
165
|
protected metadata: { [key: string]: AmfMetadataTopic } = {};
|
|
158
166
|
protected selectedTopic?: AmfMetaTopicType = undefined;
|
|
159
167
|
protected selectedSidebarValue = undefined;
|
|
@@ -347,13 +355,13 @@ export default class AmfReference extends LightningElement {
|
|
|
347
355
|
/**
|
|
348
356
|
* Returns the selected version or the first available version.
|
|
349
357
|
*/
|
|
350
|
-
private getSelectedVersion(): ReferenceVersion {
|
|
358
|
+
private getSelectedVersion(): ReferenceVersion | null {
|
|
351
359
|
const versions = this._referenceSetConfig?.versions || [];
|
|
352
360
|
const selectedVersion = versions.find(
|
|
353
361
|
(v: ReferenceVersion) => v.selected
|
|
354
362
|
);
|
|
355
363
|
// return a selected version if there is one, else return the first one.
|
|
356
|
-
return selectedVersion || (versions.length && versions[0]);
|
|
364
|
+
return selectedVersion || (versions.length && versions[0]) || null;
|
|
357
365
|
}
|
|
358
366
|
|
|
359
367
|
private updateAmfConfigInView(): void {
|
|
@@ -367,9 +375,11 @@ export default class AmfReference extends LightningElement {
|
|
|
367
375
|
}
|
|
368
376
|
}
|
|
369
377
|
|
|
370
|
-
private async fetchAmf(
|
|
378
|
+
private async fetchAmf(
|
|
379
|
+
amfConfig: AmfConfig
|
|
380
|
+
): Promise<AmfModel | AmfModel[]> {
|
|
371
381
|
const { amf } = amfConfig;
|
|
372
|
-
const response = await fetch(amf
|
|
382
|
+
const response = await fetch(amf!, {
|
|
373
383
|
headers: {
|
|
374
384
|
"Cache-Control": `max-age=86400`
|
|
375
385
|
}
|
|
@@ -419,9 +429,9 @@ export default class AmfReference extends LightningElement {
|
|
|
419
429
|
* Populates reference Items from amfConfigList and assigns it to navigation for sidebar
|
|
420
430
|
*/
|
|
421
431
|
private populateReferenceItems(): void {
|
|
422
|
-
const navAmfOrder = [];
|
|
432
|
+
const navAmfOrder = [] as NavigationItem[];
|
|
423
433
|
for (const [index, amfConfig] of this._amfConfigList.entries()) {
|
|
424
|
-
let navItemChildren = [];
|
|
434
|
+
let navItemChildren = [] as ParsedMarkdownTopic[];
|
|
425
435
|
let isChildrenLoading = false;
|
|
426
436
|
if (amfConfig.referenceType !== REFERENCE_TYPES.markdown) {
|
|
427
437
|
if (amfConfig.isSelected) {
|
|
@@ -441,10 +451,10 @@ export default class AmfReference extends LightningElement {
|
|
|
441
451
|
// check whether we should expand all the child nodes, this is required for Coveo to crawl.
|
|
442
452
|
if (isExpandChildrenEnabled) {
|
|
443
453
|
this.expandChildrenForMarkdownReferences(
|
|
444
|
-
amfConfig.topic
|
|
454
|
+
amfConfig.topic!.children
|
|
445
455
|
);
|
|
446
456
|
}
|
|
447
|
-
navItemChildren = amfConfig.topic
|
|
457
|
+
navItemChildren = amfConfig.topic!.children;
|
|
448
458
|
}
|
|
449
459
|
// store nav items for each spec in order
|
|
450
460
|
navAmfOrder[index] = {
|
|
@@ -465,7 +475,9 @@ export default class AmfReference extends LightningElement {
|
|
|
465
475
|
* Returns a boolean indicating whether the children should be expanded or not.
|
|
466
476
|
*/
|
|
467
477
|
private isExpandChildrenEnabled(referenceId: string): boolean {
|
|
468
|
-
return
|
|
478
|
+
return (
|
|
479
|
+
!!this.expandChildren && this._currentReferenceId === referenceId
|
|
480
|
+
);
|
|
469
481
|
}
|
|
470
482
|
|
|
471
483
|
/**
|
|
@@ -509,12 +521,12 @@ export default class AmfReference extends LightningElement {
|
|
|
509
521
|
referenceId: string,
|
|
510
522
|
items: ParsedTopicModel[]
|
|
511
523
|
): NavItem[] {
|
|
512
|
-
const methodList = [];
|
|
524
|
+
const methodList = [] as NavItem[];
|
|
513
525
|
|
|
514
526
|
items.forEach((item) => {
|
|
515
527
|
item.methods?.forEach((method) => {
|
|
516
528
|
const title =
|
|
517
|
-
this.getTitleForLabel(method.label) || method.method;
|
|
529
|
+
this.getTitleForLabel(method.label!) || method.method;
|
|
518
530
|
const meta = this.addToMetadata(
|
|
519
531
|
parentReferencePath,
|
|
520
532
|
referenceId,
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AmfHelperMixin,
|
|
3
|
+
EndPoint,
|
|
4
|
+
Operation
|
|
5
|
+
} from "@api-components/amf-helper-mixin";
|
|
2
6
|
import { normalizeDomId } from "dxUtils/normalizers";
|
|
3
7
|
|
|
4
8
|
const ID_PROPERTY = "@id";
|
|
@@ -517,7 +521,7 @@ export class AmfModelParser extends AmfHelperMixin(Object) {
|
|
|
517
521
|
* @param {string} selected Currently selected `@id`.
|
|
518
522
|
* @return {any|undefined} Model definition for an endpoint fragment.
|
|
519
523
|
*/
|
|
520
|
-
computeEndpointApiModel(model, selectedId) {
|
|
524
|
+
computeEndpointApiModel(model, selectedId): EndPoint {
|
|
521
525
|
const webApi = this._computeApi(model);
|
|
522
526
|
return this._computeEndpointModel(webApi, selectedId);
|
|
523
527
|
}
|
|
@@ -529,7 +533,7 @@ export class AmfModelParser extends AmfHelperMixin(Object) {
|
|
|
529
533
|
* @param {string} selected Currently selected `@id`.
|
|
530
534
|
* @return {any|undefined} Model definition for an endpoint fragment.
|
|
531
535
|
*/
|
|
532
|
-
computeMethodApiModel(model, selected) {
|
|
536
|
+
computeMethodApiModel(model, selected): Operation | undefined {
|
|
533
537
|
const webApi = this._computeApi(model);
|
|
534
538
|
return this._computeMethodModel(webApi, selected);
|
|
535
539
|
}
|
|
@@ -541,7 +545,7 @@ export class AmfModelParser extends AmfHelperMixin(Object) {
|
|
|
541
545
|
* @param {string} selected Currently selected `@id`.
|
|
542
546
|
* @return {any|undefined} Model definition for an endpoint fragment.
|
|
543
547
|
*/
|
|
544
|
-
computeEndpointApiMethodModel(model, selected) {
|
|
548
|
+
computeEndpointApiMethodModel(model, selected): EndPoint | undefined {
|
|
545
549
|
const webApi = this._computeApi(model);
|
|
546
550
|
return this._computeMethodEndpoint(webApi, selected);
|
|
547
551
|
}
|
|
@@ -8,14 +8,15 @@ import {
|
|
|
8
8
|
createTypeElement
|
|
9
9
|
} from "./utils";
|
|
10
10
|
import type { TopicModel } from "./types";
|
|
11
|
+
import { Json } from "typings/custom";
|
|
11
12
|
|
|
12
13
|
export default class AmfTopic extends LightningElement {
|
|
13
|
-
private _model;
|
|
14
|
-
private amf;
|
|
15
|
-
private type;
|
|
14
|
+
private _model: TopicModel | undefined;
|
|
15
|
+
private amf: Json;
|
|
16
|
+
private type: string | undefined;
|
|
16
17
|
|
|
17
18
|
@api
|
|
18
|
-
get model(): TopicModel {
|
|
19
|
+
get model(): TopicModel | undefined {
|
|
19
20
|
return this._model;
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -41,7 +42,11 @@ export default class AmfTopic extends LightningElement {
|
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
update(): void {
|
|
44
|
-
|
|
45
|
+
if (!this.model) {
|
|
46
|
+
throw new Error("Amf TopicModel undefined when trying to update");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const container = this.template.querySelector("div.topic-container")!;
|
|
45
50
|
const { id } = this.model;
|
|
46
51
|
const type = this.type;
|
|
47
52
|
const amf = this.amf;
|
|
@@ -79,7 +84,7 @@ export default class AmfTopic extends LightningElement {
|
|
|
79
84
|
if (container.firstChild) {
|
|
80
85
|
container.firstChild.remove();
|
|
81
86
|
}
|
|
82
|
-
container.appendChild(element);
|
|
87
|
+
container.appendChild(element as Node);
|
|
83
88
|
}
|
|
84
89
|
}
|
|
85
90
|
|
|
@@ -89,6 +94,6 @@ export default class AmfTopic extends LightningElement {
|
|
|
89
94
|
* @param value JSON Serializable object to clone.
|
|
90
95
|
* @returns A copy of Value. One that has been serialized and parsed via JSON. (Functions, Regex, etc are not preserved.)
|
|
91
96
|
*/
|
|
92
|
-
function clone(value):
|
|
97
|
+
function clone(value: any): any {
|
|
93
98
|
return JSON.parse(JSON.stringify(value));
|
|
94
99
|
}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { Json } from "typings/custom";
|
|
2
|
+
import { AmfModelParser } from "../amfReference/utils";
|
|
3
|
+
import {
|
|
4
|
+
DomainElement,
|
|
5
|
+
EndPoint,
|
|
6
|
+
Operation,
|
|
7
|
+
Shape
|
|
8
|
+
} from "@api-components/amf-helper-mixin";
|
|
2
9
|
|
|
3
10
|
export type ApiSummaryElement = HTMLElement & {
|
|
4
11
|
amf: Json;
|
|
@@ -11,44 +18,39 @@ export type ApiEndpointElement = HTMLElement & {
|
|
|
11
18
|
inlineMethods: boolean;
|
|
12
19
|
noNavigation: boolean;
|
|
13
20
|
selected: string;
|
|
14
|
-
endpoint:
|
|
21
|
+
endpoint: EndPoint;
|
|
15
22
|
noTryIt: boolean;
|
|
16
23
|
};
|
|
17
24
|
|
|
18
25
|
export type ApiMethodElement = HTMLElement & {
|
|
19
26
|
amf: Json;
|
|
20
27
|
noNavigation: boolean;
|
|
21
|
-
endpoint:
|
|
22
|
-
method:
|
|
28
|
+
endpoint: EndPoint | undefined;
|
|
29
|
+
method: Operation | undefined;
|
|
23
30
|
noTryIt: boolean;
|
|
24
31
|
};
|
|
25
32
|
|
|
26
33
|
export type ApiSecurityElement = HTMLElement & {
|
|
27
34
|
amf: Json;
|
|
28
|
-
security:
|
|
35
|
+
security: DomainElement | undefined;
|
|
29
36
|
};
|
|
30
37
|
|
|
31
38
|
export type ApiTypeElement = HTMLElement & {
|
|
32
39
|
amf: Json;
|
|
33
|
-
type
|
|
40
|
+
type?: Shape;
|
|
34
41
|
mediaTypes: Json;
|
|
35
42
|
};
|
|
36
43
|
|
|
37
44
|
export type ApiDocElement = HTMLElement & {
|
|
38
45
|
amf: Json;
|
|
39
|
-
shape:
|
|
46
|
+
shape: DomainElement | undefined;
|
|
40
47
|
};
|
|
41
48
|
|
|
42
49
|
export type AmfModel = Json;
|
|
43
50
|
|
|
44
|
-
export interface AmfParser {
|
|
45
|
-
parse(): void;
|
|
46
|
-
parsedModel: any;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
51
|
export interface TopicModel {
|
|
50
52
|
id: string;
|
|
51
53
|
type: string;
|
|
52
54
|
amf: AmfModel;
|
|
53
|
-
parser:
|
|
55
|
+
parser: AmfModelParser;
|
|
54
56
|
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DomainElement,
|
|
3
|
+
EndPoint,
|
|
4
|
+
Operation,
|
|
5
|
+
Shape
|
|
6
|
+
} from "@api-components/amf-helper-mixin";
|
|
1
7
|
import type {
|
|
2
8
|
ApiDocElement,
|
|
3
9
|
ApiEndpointElement,
|
|
@@ -37,7 +43,7 @@ export function createSummaryElement(amf: Json): HTMLElement {
|
|
|
37
43
|
*/
|
|
38
44
|
export function createEndpointElement(
|
|
39
45
|
amf: Json,
|
|
40
|
-
endpointModel:
|
|
46
|
+
endpointModel: EndPoint,
|
|
41
47
|
selected: string
|
|
42
48
|
): HTMLElement {
|
|
43
49
|
const el: ApiEndpointElement = document.createElement(
|
|
@@ -57,8 +63,8 @@ export function createEndpointElement(
|
|
|
57
63
|
*/
|
|
58
64
|
export function createMethodElement(
|
|
59
65
|
amf: Json,
|
|
60
|
-
endpointMethodModel:
|
|
61
|
-
methodModel:
|
|
66
|
+
endpointMethodModel: EndPoint | undefined,
|
|
67
|
+
methodModel: Operation | undefined
|
|
62
68
|
): HTMLElement {
|
|
63
69
|
const el: ApiMethodElement = document.createElement(
|
|
64
70
|
"api-method-documentation"
|
|
@@ -79,7 +85,7 @@ export function createMethodElement(
|
|
|
79
85
|
*/
|
|
80
86
|
export function createSecurityElement(
|
|
81
87
|
amf: Json,
|
|
82
|
-
securityModel:
|
|
88
|
+
securityModel: DomainElement | undefined
|
|
83
89
|
): HTMLElement {
|
|
84
90
|
const el: ApiSecurityElement = document.createElement(
|
|
85
91
|
"api-security-documentation"
|
|
@@ -98,7 +104,7 @@ export function createSecurityElement(
|
|
|
98
104
|
*/
|
|
99
105
|
export function createTypeElement(
|
|
100
106
|
amf: Json,
|
|
101
|
-
typeModel:
|
|
107
|
+
typeModel: Shape | undefined,
|
|
102
108
|
mediaTypes: Json
|
|
103
109
|
): HTMLElement {
|
|
104
110
|
const el: ApiTypeElement = document.createElement(
|
|
@@ -119,7 +125,7 @@ export function createTypeElement(
|
|
|
119
125
|
*/
|
|
120
126
|
export function createDocumentationElement(
|
|
121
127
|
amf: Json,
|
|
122
|
-
docsModel:
|
|
128
|
+
docsModel: DomainElement | undefined
|
|
123
129
|
): HTMLElement {
|
|
124
130
|
const el: ApiDocElement = document.createElement(
|
|
125
131
|
"api-documentation-document"
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/* eslint-disable @lwc/lwc/no-inner-html */
|
|
2
2
|
import { createElement, LightningElement, api, track } from "lwc";
|
|
3
3
|
import { DocContent, PageReference } from "typings/custom";
|
|
4
|
-
import ContentCallout from "doc/contentCallout";
|
|
5
4
|
import CodeBlock from "dx/codeBlock";
|
|
6
|
-
import ContentMedia from "doc/contentMedia";
|
|
7
5
|
import Button from "dx/button";
|
|
8
6
|
import { highlightTerms } from "dxUtils/highlight";
|
|
7
|
+
import ContentCallout from "../contentCallout/contentCallout";
|
|
8
|
+
import ContentMedia from "../contentMedia/contentMedia";
|
|
9
9
|
|
|
10
10
|
const HIGHLIGHTABLE_SELECTOR = [
|
|
11
11
|
"p",
|
|
@@ -86,7 +86,7 @@ export default class Content extends LightningElement {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
renderPaginationButton(anchorEl: HTMLElement) {
|
|
89
|
-
const isNext = anchorEl.textContent
|
|
89
|
+
const isNext = anchorEl.textContent!.includes("Next →");
|
|
90
90
|
anchorEl.innerHTML = "";
|
|
91
91
|
const buttonEl = createElement("dx-button", { is: Button });
|
|
92
92
|
const params = isNext
|
|
@@ -116,7 +116,7 @@ export default class Content extends LightningElement {
|
|
|
116
116
|
const codeBlockEls = divEl.querySelectorAll(".codeSection");
|
|
117
117
|
codeBlockEls.forEach((codeBlockEl) => {
|
|
118
118
|
codeBlockEl.setAttribute("lwc:dom", "manual");
|
|
119
|
-
const classList = codeBlockEl.firstChild.classList;
|
|
119
|
+
const classList = (codeBlockEl.firstChild as any).classList;
|
|
120
120
|
let language = "";
|
|
121
121
|
for (const key in classList) {
|
|
122
122
|
if (typeof classList[key] === "string") {
|
|
@@ -160,7 +160,7 @@ export default class Content extends LightningElement {
|
|
|
160
160
|
|
|
161
161
|
let flag = 1;
|
|
162
162
|
for (let i: number = 0; i < detailEls.length; i++) {
|
|
163
|
-
flag &= detailEls[i].innerHTML.trim() === "";
|
|
163
|
+
flag &= (detailEls[i].innerHTML.trim() === "") as any; // Dark Magic TM
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
if (flag) {
|
|
@@ -170,7 +170,7 @@ export default class Content extends LightningElement {
|
|
|
170
170
|
});
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
const type = calloutEl.querySelector("h4")
|
|
173
|
+
const type = calloutEl.querySelector("h4")!.textContent!;
|
|
174
174
|
const typeLower = type.toLowerCase();
|
|
175
175
|
Object.assign(calloutCompEl, {
|
|
176
176
|
title: type,
|
|
@@ -184,10 +184,10 @@ export default class Content extends LightningElement {
|
|
|
184
184
|
// Modify links to work with any domain, links that start with "#" are excluded
|
|
185
185
|
const anchorEls = divEl.querySelectorAll("a:not([href^='#'])");
|
|
186
186
|
|
|
187
|
-
anchorEls.forEach((anchorEl) => {
|
|
187
|
+
anchorEls.forEach((anchorEl: any) => {
|
|
188
188
|
if (
|
|
189
|
-
anchorEl.textContent
|
|
190
|
-
anchorEl.textContent
|
|
189
|
+
anchorEl.textContent!.includes("Next →") ||
|
|
190
|
+
anchorEl.textContent!.includes("← Previous")
|
|
191
191
|
) {
|
|
192
192
|
if (this.showPaginationButtons) {
|
|
193
193
|
this.renderPaginationButton(anchorEl);
|
|
@@ -326,8 +326,7 @@ export default class Content extends LightningElement {
|
|
|
326
326
|
|
|
327
327
|
handleNavClick(event: InputEvent) {
|
|
328
328
|
event.preventDefault();
|
|
329
|
-
|
|
330
|
-
const target = event.currentTarget.dataset.id;
|
|
329
|
+
const target = (event.currentTarget! as any).dataset.id;
|
|
331
330
|
const [page, docId, deliverable, tempContentDocumentId] =
|
|
332
331
|
target.split("/");
|
|
333
332
|
const [contentDocumentId, hash] = tempContentDocumentId.split("#");
|
|
@@ -3,7 +3,7 @@ import { LightningElement, api, track } from "lwc";
|
|
|
3
3
|
import { closest } from "kagekiri";
|
|
4
4
|
import { toJson } from "dxUtils/normalizers";
|
|
5
5
|
import { highlightTerms } from "dxUtils/highlight";
|
|
6
|
-
import { SearchSyncer } from "docUtils/SearchSyncer";
|
|
6
|
+
import { SearchSyncer } from "../../docUtils/SearchSyncer/SearchSyncer";
|
|
7
7
|
|
|
8
8
|
type AnchorMap = { [key: string]: { intersect: boolean; id: string } };
|
|
9
9
|
|
|
@@ -26,9 +26,9 @@ const HIGHLIGHTABLE_SELECTOR = [
|
|
|
26
26
|
const OBSERVER_ATTACH_WAIT_TIME = 500;
|
|
27
27
|
|
|
28
28
|
export default class ContentLayout extends LightningElement {
|
|
29
|
-
@api sidebarValue
|
|
30
|
-
@api sidebarHeader
|
|
31
|
-
@api tocTitle
|
|
29
|
+
@api sidebarValue!: string;
|
|
30
|
+
@api sidebarHeader!: string;
|
|
31
|
+
@api tocTitle!: string;
|
|
32
32
|
@api enableSlotChange = false;
|
|
33
33
|
@api coveoOrganizationId!: string;
|
|
34
34
|
@api coveoPublicAccessToken!: string;
|
|
@@ -41,7 +41,7 @@ export default class ContentLayout extends LightningElement {
|
|
|
41
41
|
return this._breadcrumbs;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
set breadcrumbs(value)
|
|
44
|
+
set breadcrumbs(value) {
|
|
45
45
|
if (value) {
|
|
46
46
|
this._breadcrumbs = toJson(value);
|
|
47
47
|
}
|
|
@@ -52,7 +52,7 @@ export default class ContentLayout extends LightningElement {
|
|
|
52
52
|
return this._sidebarContent;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
set sidebarContent(value) {
|
|
55
|
+
set sidebarContent(value: any) {
|
|
56
56
|
this._sidebarContent = toJson(value);
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -67,7 +67,9 @@ export default class ContentLayout extends LightningElement {
|
|
|
67
67
|
|
|
68
68
|
@api
|
|
69
69
|
setSidebarInputValue(searchTerm: string): void {
|
|
70
|
-
this.template.querySelector("dx-sidebar")?.setInputValue(
|
|
70
|
+
(this.template.querySelector("dx-sidebar") as any)?.setInputValue(
|
|
71
|
+
searchTerm
|
|
72
|
+
);
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
@track
|
|
@@ -76,11 +78,11 @@ export default class ContentLayout extends LightningElement {
|
|
|
76
78
|
private _breadcrumbs = null;
|
|
77
79
|
|
|
78
80
|
@track
|
|
79
|
-
private _tocOptions
|
|
81
|
+
private _tocOptions!: Array<unknown>;
|
|
80
82
|
|
|
81
83
|
private tocOptionIdsSet = new Set();
|
|
82
84
|
private anchoredElements: AnchorMap = {};
|
|
83
|
-
private lastScrollPosition
|
|
85
|
+
private lastScrollPosition!: number;
|
|
84
86
|
private observer?: IntersectionObserver;
|
|
85
87
|
private hasRendered: boolean = false;
|
|
86
88
|
private contentLoaded: boolean = false;
|
|
@@ -105,7 +107,8 @@ export default class ContentLayout extends LightningElement {
|
|
|
105
107
|
target: window
|
|
106
108
|
});
|
|
107
109
|
private tocValue?: string = undefined;
|
|
108
|
-
|
|
110
|
+
// eslint-disable-next-line no-undef
|
|
111
|
+
private observerTimerId?: NodeJS.Timeout;
|
|
109
112
|
private didScrollToSelectedHash = false;
|
|
110
113
|
private _scrollInterval = 0;
|
|
111
114
|
|
|
@@ -203,9 +206,9 @@ export default class ContentLayout extends LightningElement {
|
|
|
203
206
|
".sticky-doc-header"
|
|
204
207
|
) as HTMLElement;
|
|
205
208
|
|
|
206
|
-
const docPhaseEl =
|
|
207
|
-
.querySelector("[name=doc-phase]")!
|
|
208
|
-
|
|
209
|
+
const docPhaseEl = (
|
|
210
|
+
this.template.querySelector("[name=doc-phase]")! as any
|
|
211
|
+
).assignedElements()[0] as HTMLSlotElement;
|
|
209
212
|
|
|
210
213
|
if (!sidebarEl || !globalNavEl || !contextNavEl || !docHeaderEl) {
|
|
211
214
|
console.warn("One or more required elements are missing.");
|
|
@@ -247,7 +250,7 @@ export default class ContentLayout extends LightningElement {
|
|
|
247
250
|
document.querySelectorAll("doc-heading")
|
|
248
251
|
);
|
|
249
252
|
docHeadingEls.forEach((docHeadingEl) => {
|
|
250
|
-
docHeadingEl.style.scrollMarginTop = `${
|
|
253
|
+
(docHeadingEl as any).style.scrollMarginTop = `${
|
|
251
254
|
globalNavHeight +
|
|
252
255
|
docHeaderHeight +
|
|
253
256
|
docPhaseEl.getBoundingClientRect().height
|
|
@@ -290,7 +293,7 @@ export default class ContentLayout extends LightningElement {
|
|
|
290
293
|
entries.forEach(
|
|
291
294
|
(entry) =>
|
|
292
295
|
(this.anchoredElements[
|
|
293
|
-
entry.target.getAttribute("id")
|
|
296
|
+
entry.target.getAttribute("id")!
|
|
294
297
|
].intersect = entry.isIntersecting)
|
|
295
298
|
);
|
|
296
299
|
this.calculateActualSection();
|
|
@@ -302,7 +305,7 @@ export default class ContentLayout extends LightningElement {
|
|
|
302
305
|
|
|
303
306
|
// Note: We are doing document.querySelectorAll as a quick fix as we are not getting heading elements reference this.querySelectorAll
|
|
304
307
|
const headingElements = document.querySelectorAll(TOC_HEADER_TAG);
|
|
305
|
-
for (const headingElement of headingElements) {
|
|
308
|
+
for (const headingElement of headingElements as any) {
|
|
306
309
|
// Add headingElements to intersectionObserver for highlighting respective RNB item when user scroll
|
|
307
310
|
const id = headingElement.getAttribute("id");
|
|
308
311
|
this.anchoredElements[id] = {
|
|
@@ -330,14 +333,14 @@ export default class ContentLayout extends LightningElement {
|
|
|
330
333
|
TOC_HEADER_TAG
|
|
331
334
|
);
|
|
332
335
|
|
|
333
|
-
for (const headingElement of headingElements) {
|
|
336
|
+
for (const headingElement of headingElements as any) {
|
|
334
337
|
// Sometimes elements hash is not being set when slot content is wrapped with div
|
|
335
338
|
headingElement.hash = headingElement.attributes.hash?.nodeValue;
|
|
336
339
|
}
|
|
337
340
|
|
|
338
341
|
const tocOptions = [];
|
|
339
342
|
|
|
340
|
-
for (const headingElement of headingElements) {
|
|
343
|
+
for (const headingElement of headingElements as any) {
|
|
341
344
|
headingElement.id = headingElement.hash;
|
|
342
345
|
|
|
343
346
|
// Update tocOptions from anchorTags only for H2, consider default as 2 as per component
|
|
@@ -363,7 +366,7 @@ export default class ContentLayout extends LightningElement {
|
|
|
363
366
|
private disconnectObserver(): void {
|
|
364
367
|
if (this.observer) {
|
|
365
368
|
this.observer.disconnect();
|
|
366
|
-
this.observer =
|
|
369
|
+
this.observer = undefined;
|
|
367
370
|
}
|
|
368
371
|
}
|
|
369
372
|
|
|
@@ -388,15 +391,15 @@ export default class ContentLayout extends LightningElement {
|
|
|
388
391
|
globalNavEl.offsetHeight +
|
|
389
392
|
contextNavEl.offsetHeight;
|
|
390
393
|
|
|
391
|
-
const docPhaseEl =
|
|
392
|
-
.querySelector("[name=doc-phase]")!
|
|
393
|
-
|
|
394
|
+
const docPhaseEl = (
|
|
395
|
+
this.template.querySelector("[name=doc-phase]")! as any
|
|
396
|
+
).assignedElements()[0] as HTMLSlotElement;
|
|
394
397
|
|
|
395
398
|
const offset = docPhaseEl
|
|
396
399
|
? headerHeight + docPhaseEl.offsetHeight
|
|
397
400
|
: headerHeight;
|
|
398
401
|
|
|
399
|
-
for (const headingElement of headingElements) {
|
|
402
|
+
for (const headingElement of headingElements as any) {
|
|
400
403
|
if (headingElement.getAttribute("id") === hash) {
|
|
401
404
|
this.scrollIntoViewWithOffset(headingElement, offset);
|
|
402
405
|
break;
|
|
@@ -433,14 +436,14 @@ export default class ContentLayout extends LightningElement {
|
|
|
433
436
|
this.lastScrollPosition = currentScrollPosition;
|
|
434
437
|
}
|
|
435
438
|
|
|
436
|
-
private calculatePreviousElementId(): string {
|
|
439
|
+
private calculatePreviousElementId(): string | undefined {
|
|
437
440
|
const keys = Object.keys(this.anchoredElements);
|
|
438
441
|
const currentIndex = keys.findIndex((id) => this.tocValue === id);
|
|
439
442
|
|
|
440
443
|
return currentIndex > 0 ? keys[currentIndex - 1] : undefined;
|
|
441
444
|
}
|
|
442
445
|
|
|
443
|
-
private assignElementId(id: string): void {
|
|
446
|
+
private assignElementId(id: string | undefined): void {
|
|
444
447
|
// Change toc(RNB) highlight only for H2
|
|
445
448
|
if (this.tocOptionIdsSet.has(id)) {
|
|
446
449
|
this.tocValue = id;
|
|
@@ -11,12 +11,14 @@ export const ariaLevels = Object.keys(ariaDisplayLevels);
|
|
|
11
11
|
|
|
12
12
|
export const displayLevels = Object.values(ariaDisplayLevels);
|
|
13
13
|
|
|
14
|
+
// @ts-ignore: Really Dark Magic (TM) to do with ariaLevel needing explicit getter/setters
|
|
14
15
|
export default class Heading extends LightningElement {
|
|
15
16
|
@api title: string = "";
|
|
16
17
|
@api hash: string | null = null;
|
|
17
18
|
|
|
18
19
|
@api
|
|
19
20
|
private get ariaLevel(): string {
|
|
21
|
+
// Really Dark Magic (TM)
|
|
20
22
|
return this._ariaLevel || "2";
|
|
21
23
|
}
|
|
22
24
|
private set ariaLevel(value: string | null) {
|
|
@@ -11,7 +11,7 @@ export default class Toc extends LightningElement {
|
|
|
11
11
|
const newPageReference = { ...this.pageReference };
|
|
12
12
|
// When moving to the new navigation component
|
|
13
13
|
//const target = event.detail.name.split('-')
|
|
14
|
-
const target = event.currentTarget.dataset.id.split("-");
|
|
14
|
+
const target = (event.currentTarget as any).dataset.id.split("-");
|
|
15
15
|
newPageReference.contentDocumentId = target[0] + ".htm";
|
|
16
16
|
newPageReference.hash = target[1];
|
|
17
17
|
this.dispatchEvent(
|
|
@@ -4,12 +4,12 @@ export interface SearchSyncerConstructorArgs {
|
|
|
4
4
|
onUrlChange?: (nextSearchString: string) => unknown;
|
|
5
5
|
};
|
|
6
6
|
eventName: string;
|
|
7
|
-
historyMethod
|
|
7
|
+
historyMethod:
|
|
8
8
|
| typeof window.history.pushState
|
|
9
9
|
| typeof window.history.replaceState;
|
|
10
10
|
searchParam: string;
|
|
11
11
|
shouldStopPropagation?: boolean;
|
|
12
|
-
target: EventTarget;
|
|
12
|
+
target: EventTarget | undefined;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export class SearchSyncer {
|
|
@@ -37,16 +37,16 @@ export class SearchSyncer {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
public init = (): void => {
|
|
40
|
-
this.target
|
|
41
|
-
this.target
|
|
40
|
+
this.target!.addEventListener(this.eventName, this.handleSearchChange);
|
|
41
|
+
this.target!.addEventListener("popstate", this.handlePopState);
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
public dispose = (): void => {
|
|
45
|
-
this.target
|
|
45
|
+
this.target!.removeEventListener(
|
|
46
46
|
this.eventName,
|
|
47
47
|
this.handleSearchChange
|
|
48
48
|
);
|
|
49
|
-
this.target
|
|
49
|
+
this.target!.removeEventListener("popstate", this.handlePopState);
|
|
50
50
|
this.target = undefined;
|
|
51
51
|
this.callbacks.onSearchChange = undefined;
|
|
52
52
|
this.callbacks.onUrlChange = undefined;
|
package/LICENSE
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
Copyright (c) 2020, Salesforce.com, Inc.
|
|
2
|
-
All rights reserved.
|
|
3
|
-
|
|
4
|
-
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
5
|
-
|
|
6
|
-
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
7
|
-
|
|
8
|
-
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
9
|
-
|
|
10
|
-
* Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
11
|
-
|
|
12
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|