@salesforcedevs/docs-components 1.3.166-alpha → 1.3.169
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/LICENSE +12 -0
- package/package.json +2 -2
- package/src/modules/doc/amfReference/amfReference.ts +16 -28
- package/src/modules/doc/amfReference/utils.ts +4 -8
- package/src/modules/doc/amfTopic/amfTopic.ts +7 -12
- package/src/modules/doc/amfTopic/types.ts +12 -14
- package/src/modules/doc/amfTopic/utils.ts +6 -12
- package/src/modules/doc/content/content.ts +11 -10
- package/src/modules/doc/contentLayout/contentLayout.ts +35 -39
- package/src/modules/doc/heading/heading.ts +0 -2
- package/src/modules/doc/toc/toc.ts +1 -1
- package/src/modules/docUtils/SearchSyncer/SearchSyncer.ts +6 -6
- package/src/modules/docUtils/searchSyncer/SearchSyncer.ts +85 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
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.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforcedevs/docs-components",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.169",
|
|
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": "e819e60b958af0fa567045741481fd7a4e8417b3"
|
|
28
28
|
}
|
|
@@ -30,14 +30,6 @@ 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
|
-
|
|
41
33
|
export default class AmfReference extends LightningElement {
|
|
42
34
|
@api breadcrumbs?: string | null | undefined = null;
|
|
43
35
|
@api sidebarHeader!: string;
|
|
@@ -49,7 +41,7 @@ export default class AmfReference extends LightningElement {
|
|
|
49
41
|
@api useOldSidebar?: boolean = false;
|
|
50
42
|
@api tocTitle?: string;
|
|
51
43
|
@api tocOptions?: string;
|
|
52
|
-
@track navigation = []
|
|
44
|
+
@track navigation = [];
|
|
53
45
|
@track versions: Array<ReferenceVersion> = [];
|
|
54
46
|
@track showVersionBanner = false;
|
|
55
47
|
|
|
@@ -133,8 +125,8 @@ export default class AmfReference extends LightningElement {
|
|
|
133
125
|
}
|
|
134
126
|
|
|
135
127
|
@api
|
|
136
|
-
get docPhaseInfo()
|
|
137
|
-
return this.selectedReferenceDocPhase
|
|
128
|
+
get docPhaseInfo() {
|
|
129
|
+
return this.selectedReferenceDocPhase;
|
|
138
130
|
}
|
|
139
131
|
|
|
140
132
|
set docPhaseInfo(value: string) {
|
|
@@ -159,9 +151,9 @@ export default class AmfReference extends LightningElement {
|
|
|
159
151
|
protected _referenceSetConfig!: ReferenceSetConfig;
|
|
160
152
|
protected _currentReferenceId = "";
|
|
161
153
|
|
|
162
|
-
protected parentReferenceUrls = []
|
|
154
|
+
protected parentReferenceUrls = [];
|
|
163
155
|
protected amfMap: Record<string, AmfModelRecord> = {};
|
|
164
|
-
protected amfFetchPromiseMap = {}
|
|
156
|
+
protected amfFetchPromiseMap = {};
|
|
165
157
|
protected metadata: { [key: string]: AmfMetadataTopic } = {};
|
|
166
158
|
protected selectedTopic?: AmfMetaTopicType = undefined;
|
|
167
159
|
protected selectedSidebarValue = undefined;
|
|
@@ -355,13 +347,13 @@ export default class AmfReference extends LightningElement {
|
|
|
355
347
|
/**
|
|
356
348
|
* Returns the selected version or the first available version.
|
|
357
349
|
*/
|
|
358
|
-
private getSelectedVersion(): ReferenceVersion
|
|
350
|
+
private getSelectedVersion(): ReferenceVersion {
|
|
359
351
|
const versions = this._referenceSetConfig?.versions || [];
|
|
360
352
|
const selectedVersion = versions.find(
|
|
361
353
|
(v: ReferenceVersion) => v.selected
|
|
362
354
|
);
|
|
363
355
|
// return a selected version if there is one, else return the first one.
|
|
364
|
-
return selectedVersion || (versions.length && versions[0])
|
|
356
|
+
return selectedVersion || (versions.length && versions[0]);
|
|
365
357
|
}
|
|
366
358
|
|
|
367
359
|
private updateAmfConfigInView(): void {
|
|
@@ -375,11 +367,9 @@ export default class AmfReference extends LightningElement {
|
|
|
375
367
|
}
|
|
376
368
|
}
|
|
377
369
|
|
|
378
|
-
private async fetchAmf(
|
|
379
|
-
amfConfig: AmfConfig
|
|
380
|
-
): Promise<AmfModel | AmfModel[]> {
|
|
370
|
+
private async fetchAmf(amfConfig): Promise<AmfModel | AmfModel[]> {
|
|
381
371
|
const { amf } = amfConfig;
|
|
382
|
-
const response = await fetch(amf
|
|
372
|
+
const response = await fetch(amf, {
|
|
383
373
|
headers: {
|
|
384
374
|
"Cache-Control": `max-age=86400`
|
|
385
375
|
}
|
|
@@ -429,9 +419,9 @@ export default class AmfReference extends LightningElement {
|
|
|
429
419
|
* Populates reference Items from amfConfigList and assigns it to navigation for sidebar
|
|
430
420
|
*/
|
|
431
421
|
private populateReferenceItems(): void {
|
|
432
|
-
const navAmfOrder = []
|
|
422
|
+
const navAmfOrder = [];
|
|
433
423
|
for (const [index, amfConfig] of this._amfConfigList.entries()) {
|
|
434
|
-
let navItemChildren = []
|
|
424
|
+
let navItemChildren = [];
|
|
435
425
|
let isChildrenLoading = false;
|
|
436
426
|
if (amfConfig.referenceType !== REFERENCE_TYPES.markdown) {
|
|
437
427
|
if (amfConfig.isSelected) {
|
|
@@ -451,10 +441,10 @@ export default class AmfReference extends LightningElement {
|
|
|
451
441
|
// check whether we should expand all the child nodes, this is required for Coveo to crawl.
|
|
452
442
|
if (isExpandChildrenEnabled) {
|
|
453
443
|
this.expandChildrenForMarkdownReferences(
|
|
454
|
-
amfConfig.topic
|
|
444
|
+
amfConfig.topic.children
|
|
455
445
|
);
|
|
456
446
|
}
|
|
457
|
-
navItemChildren = amfConfig.topic
|
|
447
|
+
navItemChildren = amfConfig.topic.children;
|
|
458
448
|
}
|
|
459
449
|
// store nav items for each spec in order
|
|
460
450
|
navAmfOrder[index] = {
|
|
@@ -475,9 +465,7 @@ export default class AmfReference extends LightningElement {
|
|
|
475
465
|
* Returns a boolean indicating whether the children should be expanded or not.
|
|
476
466
|
*/
|
|
477
467
|
private isExpandChildrenEnabled(referenceId: string): boolean {
|
|
478
|
-
return
|
|
479
|
-
!!this.expandChildren && this._currentReferenceId === referenceId
|
|
480
|
-
);
|
|
468
|
+
return this.expandChildren && this._currentReferenceId === referenceId;
|
|
481
469
|
}
|
|
482
470
|
|
|
483
471
|
/**
|
|
@@ -521,12 +509,12 @@ export default class AmfReference extends LightningElement {
|
|
|
521
509
|
referenceId: string,
|
|
522
510
|
items: ParsedTopicModel[]
|
|
523
511
|
): NavItem[] {
|
|
524
|
-
const methodList = []
|
|
512
|
+
const methodList = [];
|
|
525
513
|
|
|
526
514
|
items.forEach((item) => {
|
|
527
515
|
item.methods?.forEach((method) => {
|
|
528
516
|
const title =
|
|
529
|
-
this.getTitleForLabel(method.label
|
|
517
|
+
this.getTitleForLabel(method.label) || method.method;
|
|
530
518
|
const meta = this.addToMetadata(
|
|
531
519
|
parentReferencePath,
|
|
532
520
|
referenceId,
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AmfHelperMixin,
|
|
3
|
-
EndPoint,
|
|
4
|
-
Operation
|
|
5
|
-
} from "@api-components/amf-helper-mixin";
|
|
1
|
+
import { AmfHelperMixin } from "@api-components/amf-helper-mixin";
|
|
6
2
|
import { normalizeDomId } from "dxUtils/normalizers";
|
|
7
3
|
|
|
8
4
|
const ID_PROPERTY = "@id";
|
|
@@ -521,7 +517,7 @@ export class AmfModelParser extends AmfHelperMixin(Object) {
|
|
|
521
517
|
* @param {string} selected Currently selected `@id`.
|
|
522
518
|
* @return {any|undefined} Model definition for an endpoint fragment.
|
|
523
519
|
*/
|
|
524
|
-
computeEndpointApiModel(model, selectedId)
|
|
520
|
+
computeEndpointApiModel(model, selectedId) {
|
|
525
521
|
const webApi = this._computeApi(model);
|
|
526
522
|
return this._computeEndpointModel(webApi, selectedId);
|
|
527
523
|
}
|
|
@@ -533,7 +529,7 @@ export class AmfModelParser extends AmfHelperMixin(Object) {
|
|
|
533
529
|
* @param {string} selected Currently selected `@id`.
|
|
534
530
|
* @return {any|undefined} Model definition for an endpoint fragment.
|
|
535
531
|
*/
|
|
536
|
-
computeMethodApiModel(model, selected)
|
|
532
|
+
computeMethodApiModel(model, selected) {
|
|
537
533
|
const webApi = this._computeApi(model);
|
|
538
534
|
return this._computeMethodModel(webApi, selected);
|
|
539
535
|
}
|
|
@@ -545,7 +541,7 @@ export class AmfModelParser extends AmfHelperMixin(Object) {
|
|
|
545
541
|
* @param {string} selected Currently selected `@id`.
|
|
546
542
|
* @return {any|undefined} Model definition for an endpoint fragment.
|
|
547
543
|
*/
|
|
548
|
-
computeEndpointApiMethodModel(model, selected)
|
|
544
|
+
computeEndpointApiMethodModel(model, selected) {
|
|
549
545
|
const webApi = this._computeApi(model);
|
|
550
546
|
return this._computeMethodEndpoint(webApi, selected);
|
|
551
547
|
}
|
|
@@ -8,15 +8,14 @@ import {
|
|
|
8
8
|
createTypeElement
|
|
9
9
|
} from "./utils";
|
|
10
10
|
import type { TopicModel } from "./types";
|
|
11
|
-
import { Json } from "typings/custom";
|
|
12
11
|
|
|
13
12
|
export default class AmfTopic extends LightningElement {
|
|
14
|
-
private _model
|
|
15
|
-
private amf
|
|
16
|
-
private type
|
|
13
|
+
private _model;
|
|
14
|
+
private amf;
|
|
15
|
+
private type;
|
|
17
16
|
|
|
18
17
|
@api
|
|
19
|
-
get model(): TopicModel
|
|
18
|
+
get model(): TopicModel {
|
|
20
19
|
return this._model;
|
|
21
20
|
}
|
|
22
21
|
|
|
@@ -42,11 +41,7 @@ export default class AmfTopic extends LightningElement {
|
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
update(): void {
|
|
45
|
-
|
|
46
|
-
throw new Error("Amf TopicModel undefined when trying to update");
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const container = this.template.querySelector("div.topic-container")!;
|
|
44
|
+
const container = this.template.querySelector("div.topic-container");
|
|
50
45
|
const { id } = this.model;
|
|
51
46
|
const type = this.type;
|
|
52
47
|
const amf = this.amf;
|
|
@@ -84,7 +79,7 @@ export default class AmfTopic extends LightningElement {
|
|
|
84
79
|
if (container.firstChild) {
|
|
85
80
|
container.firstChild.remove();
|
|
86
81
|
}
|
|
87
|
-
container.appendChild(element
|
|
82
|
+
container.appendChild(element);
|
|
88
83
|
}
|
|
89
84
|
}
|
|
90
85
|
|
|
@@ -94,6 +89,6 @@ export default class AmfTopic extends LightningElement {
|
|
|
94
89
|
* @param value JSON Serializable object to clone.
|
|
95
90
|
* @returns A copy of Value. One that has been serialized and parsed via JSON. (Functions, Regex, etc are not preserved.)
|
|
96
91
|
*/
|
|
97
|
-
function clone(value
|
|
92
|
+
function clone(value): object {
|
|
98
93
|
return JSON.parse(JSON.stringify(value));
|
|
99
94
|
}
|
|
@@ -1,11 +1,4 @@
|
|
|
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";
|
|
9
2
|
|
|
10
3
|
export type ApiSummaryElement = HTMLElement & {
|
|
11
4
|
amf: Json;
|
|
@@ -18,39 +11,44 @@ export type ApiEndpointElement = HTMLElement & {
|
|
|
18
11
|
inlineMethods: boolean;
|
|
19
12
|
noNavigation: boolean;
|
|
20
13
|
selected: string;
|
|
21
|
-
endpoint:
|
|
14
|
+
endpoint: Json;
|
|
22
15
|
noTryIt: boolean;
|
|
23
16
|
};
|
|
24
17
|
|
|
25
18
|
export type ApiMethodElement = HTMLElement & {
|
|
26
19
|
amf: Json;
|
|
27
20
|
noNavigation: boolean;
|
|
28
|
-
endpoint:
|
|
29
|
-
method:
|
|
21
|
+
endpoint: Json;
|
|
22
|
+
method: Json;
|
|
30
23
|
noTryIt: boolean;
|
|
31
24
|
};
|
|
32
25
|
|
|
33
26
|
export type ApiSecurityElement = HTMLElement & {
|
|
34
27
|
amf: Json;
|
|
35
|
-
security:
|
|
28
|
+
security: Json;
|
|
36
29
|
};
|
|
37
30
|
|
|
38
31
|
export type ApiTypeElement = HTMLElement & {
|
|
39
32
|
amf: Json;
|
|
40
|
-
type
|
|
33
|
+
type: Json;
|
|
41
34
|
mediaTypes: Json;
|
|
42
35
|
};
|
|
43
36
|
|
|
44
37
|
export type ApiDocElement = HTMLElement & {
|
|
45
38
|
amf: Json;
|
|
46
|
-
shape:
|
|
39
|
+
shape: Json;
|
|
47
40
|
};
|
|
48
41
|
|
|
49
42
|
export type AmfModel = Json;
|
|
50
43
|
|
|
44
|
+
export interface AmfParser {
|
|
45
|
+
parse(): void;
|
|
46
|
+
parsedModel: any;
|
|
47
|
+
}
|
|
48
|
+
|
|
51
49
|
export interface TopicModel {
|
|
52
50
|
id: string;
|
|
53
51
|
type: string;
|
|
54
52
|
amf: AmfModel;
|
|
55
|
-
parser:
|
|
53
|
+
parser: AmfParser;
|
|
56
54
|
}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DomainElement,
|
|
3
|
-
EndPoint,
|
|
4
|
-
Operation,
|
|
5
|
-
Shape
|
|
6
|
-
} from "@api-components/amf-helper-mixin";
|
|
7
1
|
import type {
|
|
8
2
|
ApiDocElement,
|
|
9
3
|
ApiEndpointElement,
|
|
@@ -43,7 +37,7 @@ export function createSummaryElement(amf: Json): HTMLElement {
|
|
|
43
37
|
*/
|
|
44
38
|
export function createEndpointElement(
|
|
45
39
|
amf: Json,
|
|
46
|
-
endpointModel:
|
|
40
|
+
endpointModel: Json,
|
|
47
41
|
selected: string
|
|
48
42
|
): HTMLElement {
|
|
49
43
|
const el: ApiEndpointElement = document.createElement(
|
|
@@ -63,8 +57,8 @@ export function createEndpointElement(
|
|
|
63
57
|
*/
|
|
64
58
|
export function createMethodElement(
|
|
65
59
|
amf: Json,
|
|
66
|
-
endpointMethodModel:
|
|
67
|
-
methodModel:
|
|
60
|
+
endpointMethodModel: Json,
|
|
61
|
+
methodModel: Json
|
|
68
62
|
): HTMLElement {
|
|
69
63
|
const el: ApiMethodElement = document.createElement(
|
|
70
64
|
"api-method-documentation"
|
|
@@ -85,7 +79,7 @@ export function createMethodElement(
|
|
|
85
79
|
*/
|
|
86
80
|
export function createSecurityElement(
|
|
87
81
|
amf: Json,
|
|
88
|
-
securityModel:
|
|
82
|
+
securityModel: Json
|
|
89
83
|
): HTMLElement {
|
|
90
84
|
const el: ApiSecurityElement = document.createElement(
|
|
91
85
|
"api-security-documentation"
|
|
@@ -104,7 +98,7 @@ export function createSecurityElement(
|
|
|
104
98
|
*/
|
|
105
99
|
export function createTypeElement(
|
|
106
100
|
amf: Json,
|
|
107
|
-
typeModel:
|
|
101
|
+
typeModel: Json,
|
|
108
102
|
mediaTypes: Json
|
|
109
103
|
): HTMLElement {
|
|
110
104
|
const el: ApiTypeElement = document.createElement(
|
|
@@ -125,7 +119,7 @@ export function createTypeElement(
|
|
|
125
119
|
*/
|
|
126
120
|
export function createDocumentationElement(
|
|
127
121
|
amf: Json,
|
|
128
|
-
docsModel:
|
|
122
|
+
docsModel: Json
|
|
129
123
|
): HTMLElement {
|
|
130
124
|
const el: ApiDocElement = document.createElement(
|
|
131
125
|
"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";
|
|
4
5
|
import CodeBlock from "dx/codeBlock";
|
|
6
|
+
import ContentMedia from "doc/contentMedia";
|
|
5
7
|
import Button from "dx/button";
|
|
6
8
|
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 =
|
|
119
|
+
const classList = codeBlockEl.firstChild.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 &=
|
|
163
|
+
flag &= detailEls[i].innerHTML.trim() === "";
|
|
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) => {
|
|
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,7 +326,8 @@ export default class Content extends LightningElement {
|
|
|
326
326
|
|
|
327
327
|
handleNavClick(event: InputEvent) {
|
|
328
328
|
event.preventDefault();
|
|
329
|
-
|
|
329
|
+
// eslint-disable-next-line no-use-before-define
|
|
330
|
+
const target = event.currentTarget.dataset.id;
|
|
330
331
|
const [page, docId, deliverable, tempContentDocumentId] =
|
|
331
332
|
target.split("/");
|
|
332
333
|
const [contentDocumentId, hash] = tempContentDocumentId.split("#");
|
|
@@ -3,13 +3,13 @@ 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 "
|
|
6
|
+
import { SearchSyncer } from "docUtils/SearchSyncer";
|
|
7
7
|
|
|
8
8
|
type AnchorMap = { [key: string]: { intersect: boolean; id: string } };
|
|
9
9
|
|
|
10
10
|
declare const Sprig: (eventType: string, eventNme: string) => void;
|
|
11
11
|
|
|
12
|
-
const TOC_HEADER_TAG = "
|
|
12
|
+
const TOC_HEADER_TAG = "doc-heading";
|
|
13
13
|
const HIGHLIGHTABLE_SELECTOR = [
|
|
14
14
|
"p",
|
|
15
15
|
"h1",
|
|
@@ -23,12 +23,12 @@ const HIGHLIGHTABLE_SELECTOR = [
|
|
|
23
23
|
"th",
|
|
24
24
|
"td"
|
|
25
25
|
].join(",");
|
|
26
|
-
const OBSERVER_ATTACH_WAIT_TIME = 500;
|
|
26
|
+
export 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) {
|
|
56
56
|
this._sidebarContent = toJson(value);
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -67,9 +67,7 @@ export default class ContentLayout extends LightningElement {
|
|
|
67
67
|
|
|
68
68
|
@api
|
|
69
69
|
setSidebarInputValue(searchTerm: string): void {
|
|
70
|
-
|
|
71
|
-
searchTerm
|
|
72
|
-
);
|
|
70
|
+
this.template.querySelector("dx-sidebar")?.setInputValue(searchTerm);
|
|
73
71
|
}
|
|
74
72
|
|
|
75
73
|
@track
|
|
@@ -78,11 +76,11 @@ export default class ContentLayout extends LightningElement {
|
|
|
78
76
|
private _breadcrumbs = null;
|
|
79
77
|
|
|
80
78
|
@track
|
|
81
|
-
private _tocOptions
|
|
79
|
+
private _tocOptions: Array<unknown>;
|
|
82
80
|
|
|
83
81
|
private tocOptionIdsSet = new Set();
|
|
84
82
|
private anchoredElements: AnchorMap = {};
|
|
85
|
-
private lastScrollPosition
|
|
83
|
+
private lastScrollPosition: number;
|
|
86
84
|
private observer?: IntersectionObserver;
|
|
87
85
|
private hasRendered: boolean = false;
|
|
88
86
|
private contentLoaded: boolean = false;
|
|
@@ -107,8 +105,7 @@ export default class ContentLayout extends LightningElement {
|
|
|
107
105
|
target: window
|
|
108
106
|
});
|
|
109
107
|
private tocValue?: string = undefined;
|
|
110
|
-
|
|
111
|
-
private observerTimerId?: NodeJS.Timeout;
|
|
108
|
+
private observerTimerId = null;
|
|
112
109
|
private didScrollToSelectedHash = false;
|
|
113
110
|
private _scrollInterval = 0;
|
|
114
111
|
|
|
@@ -206,9 +203,9 @@ export default class ContentLayout extends LightningElement {
|
|
|
206
203
|
".sticky-doc-header"
|
|
207
204
|
) as HTMLElement;
|
|
208
205
|
|
|
209
|
-
const docPhaseEl =
|
|
210
|
-
|
|
211
|
-
|
|
206
|
+
const docPhaseEl = this.template
|
|
207
|
+
.querySelector("[name=doc-phase]")!
|
|
208
|
+
.assignedElements()[0] as HTMLSlotElement;
|
|
212
209
|
|
|
213
210
|
if (!sidebarEl || !globalNavEl || !contextNavEl || !docHeaderEl) {
|
|
214
211
|
console.warn("One or more required elements are missing.");
|
|
@@ -250,7 +247,7 @@ export default class ContentLayout extends LightningElement {
|
|
|
250
247
|
document.querySelectorAll("doc-heading")
|
|
251
248
|
);
|
|
252
249
|
docHeadingEls.forEach((docHeadingEl) => {
|
|
253
|
-
|
|
250
|
+
docHeadingEl.style.scrollMarginTop = `${
|
|
254
251
|
globalNavHeight +
|
|
255
252
|
docHeaderHeight +
|
|
256
253
|
docPhaseEl.getBoundingClientRect().height
|
|
@@ -258,8 +255,9 @@ export default class ContentLayout extends LightningElement {
|
|
|
258
255
|
});
|
|
259
256
|
|
|
260
257
|
// Adjust right nav bar position when doc phase is present
|
|
261
|
-
const rightNavBarEl =
|
|
262
|
-
|
|
258
|
+
const rightNavBarEl = this.template.querySelector(
|
|
259
|
+
".right-nav-bar"
|
|
260
|
+
);
|
|
263
261
|
|
|
264
262
|
if (rightNavBarEl) {
|
|
265
263
|
rightNavBarEl.style.top = `${
|
|
@@ -293,7 +291,7 @@ export default class ContentLayout extends LightningElement {
|
|
|
293
291
|
entries.forEach(
|
|
294
292
|
(entry) =>
|
|
295
293
|
(this.anchoredElements[
|
|
296
|
-
entry.target.getAttribute("id")
|
|
294
|
+
entry.target.getAttribute("id")
|
|
297
295
|
].intersect = entry.isIntersecting)
|
|
298
296
|
);
|
|
299
297
|
this.calculateActualSection();
|
|
@@ -305,7 +303,8 @@ export default class ContentLayout extends LightningElement {
|
|
|
305
303
|
|
|
306
304
|
// Note: We are doing document.querySelectorAll as a quick fix as we are not getting heading elements reference this.querySelectorAll
|
|
307
305
|
const headingElements = document.querySelectorAll(TOC_HEADER_TAG);
|
|
308
|
-
|
|
306
|
+
|
|
307
|
+
for (const headingElement of headingElements) {
|
|
309
308
|
// Add headingElements to intersectionObserver for highlighting respective RNB item when user scroll
|
|
310
309
|
const id = headingElement.getAttribute("id");
|
|
311
310
|
this.anchoredElements[id] = {
|
|
@@ -321,26 +320,23 @@ export default class ContentLayout extends LightningElement {
|
|
|
321
320
|
};
|
|
322
321
|
|
|
323
322
|
onSlotChange(event: Event): void {
|
|
324
|
-
const slotElements = (
|
|
325
|
-
event.target as HTMLSlotElement
|
|
326
|
-
).assignedElements();
|
|
323
|
+
const slotElements = (event.target as HTMLSlotElement).assignedElements();
|
|
327
324
|
|
|
328
325
|
if (slotElements.length) {
|
|
329
326
|
this.contentLoaded = true;
|
|
330
327
|
const slotContentElement = slotElements[0];
|
|
331
|
-
const headingElements =
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
);
|
|
328
|
+
const headingElements = slotContentElement.ownerDocument?.getElementsByTagName(
|
|
329
|
+
TOC_HEADER_TAG
|
|
330
|
+
);
|
|
335
331
|
|
|
336
|
-
for (const headingElement of headingElements
|
|
332
|
+
for (const headingElement of headingElements) {
|
|
337
333
|
// Sometimes elements hash is not being set when slot content is wrapped with div
|
|
338
334
|
headingElement.hash = headingElement.attributes.hash?.nodeValue;
|
|
339
335
|
}
|
|
340
336
|
|
|
341
337
|
const tocOptions = [];
|
|
342
338
|
|
|
343
|
-
for (const headingElement of headingElements
|
|
339
|
+
for (const headingElement of headingElements) {
|
|
344
340
|
headingElement.id = headingElement.hash;
|
|
345
341
|
|
|
346
342
|
// Update tocOptions from anchorTags only for H2, consider default as 2 as per component
|
|
@@ -366,7 +362,7 @@ export default class ContentLayout extends LightningElement {
|
|
|
366
362
|
private disconnectObserver(): void {
|
|
367
363
|
if (this.observer) {
|
|
368
364
|
this.observer.disconnect();
|
|
369
|
-
this.observer =
|
|
365
|
+
this.observer = null;
|
|
370
366
|
}
|
|
371
367
|
}
|
|
372
368
|
|
|
@@ -391,15 +387,15 @@ export default class ContentLayout extends LightningElement {
|
|
|
391
387
|
globalNavEl.offsetHeight +
|
|
392
388
|
contextNavEl.offsetHeight;
|
|
393
389
|
|
|
394
|
-
const docPhaseEl =
|
|
395
|
-
|
|
396
|
-
|
|
390
|
+
const docPhaseEl = this.template
|
|
391
|
+
.querySelector("[name=doc-phase]")!
|
|
392
|
+
.assignedElements()[0] as HTMLSlotElement;
|
|
397
393
|
|
|
398
394
|
const offset = docPhaseEl
|
|
399
395
|
? headerHeight + docPhaseEl.offsetHeight
|
|
400
396
|
: headerHeight;
|
|
401
397
|
|
|
402
|
-
for (const headingElement of headingElements
|
|
398
|
+
for (const headingElement of headingElements) {
|
|
403
399
|
if (headingElement.getAttribute("id") === hash) {
|
|
404
400
|
this.scrollIntoViewWithOffset(headingElement, offset);
|
|
405
401
|
break;
|
|
@@ -436,14 +432,14 @@ export default class ContentLayout extends LightningElement {
|
|
|
436
432
|
this.lastScrollPosition = currentScrollPosition;
|
|
437
433
|
}
|
|
438
434
|
|
|
439
|
-
private calculatePreviousElementId(): string
|
|
435
|
+
private calculatePreviousElementId(): string {
|
|
440
436
|
const keys = Object.keys(this.anchoredElements);
|
|
441
437
|
const currentIndex = keys.findIndex((id) => this.tocValue === id);
|
|
442
438
|
|
|
443
439
|
return currentIndex > 0 ? keys[currentIndex - 1] : undefined;
|
|
444
440
|
}
|
|
445
441
|
|
|
446
|
-
private assignElementId(id: string
|
|
442
|
+
private assignElementId(id: string): void {
|
|
447
443
|
// Change toc(RNB) highlight only for H2
|
|
448
444
|
if (this.tocOptionIdsSet.has(id)) {
|
|
449
445
|
this.tocValue = id;
|
|
@@ -11,14 +11,12 @@ 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
|
|
15
14
|
export default class Heading extends LightningElement {
|
|
16
15
|
@api title: string = "";
|
|
17
16
|
@api hash: string | null = null;
|
|
18
17
|
|
|
19
18
|
@api
|
|
20
19
|
private get ariaLevel(): string {
|
|
21
|
-
// Really Dark Magic (TM)
|
|
22
20
|
return this._ariaLevel || "2";
|
|
23
21
|
}
|
|
24
22
|
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 =
|
|
14
|
+
const target = event.currentTarget.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;
|
|
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;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export interface SearchSyncerConstructorArgs {
|
|
2
|
+
callbacks: {
|
|
3
|
+
onSearchChange?: (nextSearchString: string) => unknown;
|
|
4
|
+
onUrlChange?: (nextSearchString: string) => unknown;
|
|
5
|
+
};
|
|
6
|
+
eventName: string;
|
|
7
|
+
historyMethod?:
|
|
8
|
+
| typeof window.history.pushState
|
|
9
|
+
| typeof window.history.replaceState;
|
|
10
|
+
searchParam: string;
|
|
11
|
+
shouldStopPropagation?: boolean;
|
|
12
|
+
target: EventTarget;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class SearchSyncer {
|
|
16
|
+
private callbacks: SearchSyncerConstructorArgs["callbacks"];
|
|
17
|
+
private eventName: SearchSyncerConstructorArgs["eventName"];
|
|
18
|
+
private historyMethod: SearchSyncerConstructorArgs["historyMethod"];
|
|
19
|
+
private searchParam: SearchSyncerConstructorArgs["searchParam"];
|
|
20
|
+
private shouldStopPropagation: SearchSyncerConstructorArgs["shouldStopPropagation"];
|
|
21
|
+
private target: SearchSyncerConstructorArgs["target"];
|
|
22
|
+
|
|
23
|
+
constructor({
|
|
24
|
+
callbacks = {},
|
|
25
|
+
eventName,
|
|
26
|
+
historyMethod = window.history.pushState,
|
|
27
|
+
searchParam,
|
|
28
|
+
shouldStopPropagation = true,
|
|
29
|
+
target
|
|
30
|
+
}: SearchSyncerConstructorArgs) {
|
|
31
|
+
this.callbacks = callbacks;
|
|
32
|
+
this.eventName = eventName;
|
|
33
|
+
this.historyMethod = historyMethod.bind(window.history);
|
|
34
|
+
this.searchParam = searchParam;
|
|
35
|
+
this.shouldStopPropagation = shouldStopPropagation;
|
|
36
|
+
this.target = target;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public init = (): void => {
|
|
40
|
+
this.target.addEventListener(this.eventName, this.handleSearchChange);
|
|
41
|
+
this.target.addEventListener("popstate", this.handlePopState);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
public dispose = (): void => {
|
|
45
|
+
this.target.removeEventListener(
|
|
46
|
+
this.eventName,
|
|
47
|
+
this.handleSearchChange
|
|
48
|
+
);
|
|
49
|
+
this.target.removeEventListener("popstate", this.handlePopState);
|
|
50
|
+
this.target = undefined;
|
|
51
|
+
this.callbacks.onSearchChange = undefined;
|
|
52
|
+
this.callbacks.onUrlChange = undefined;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
private handleSearchChange = (event: Event): void => {
|
|
56
|
+
if (this.shouldStopPropagation) {
|
|
57
|
+
event.stopPropagation();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const { detail: searchTerm } = event as CustomEvent<string>;
|
|
61
|
+
const fullUrl = new URL(window.location.href);
|
|
62
|
+
const { searchParams } = fullUrl;
|
|
63
|
+
|
|
64
|
+
if (searchTerm) {
|
|
65
|
+
searchParams.set(this.searchParam, searchTerm);
|
|
66
|
+
} else {
|
|
67
|
+
searchParams.delete(this.searchParam);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const nextSearchString = searchParams.toString();
|
|
71
|
+
|
|
72
|
+
if (this.callbacks.onSearchChange) {
|
|
73
|
+
this.callbacks.onSearchChange(nextSearchString);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
fullUrl.search = nextSearchString;
|
|
77
|
+
this.historyMethod({}, "", fullUrl.toString());
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
private handlePopState = (): void => {
|
|
81
|
+
if (this.callbacks.onUrlChange) {
|
|
82
|
+
this.callbacks.onUrlChange(window.location.search);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|