@salesforcedevs/docs-components 0.57.1-flex-ref1 → 0.60.0
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.html +5 -13
- package/src/modules/doc/amfReference/amfReference.ts +303 -799
- package/src/modules/doc/amfReference/route-meta.ts +22 -0
- package/src/modules/doc/amfReference/types.ts +3 -43
- package/src/modules/doc/breadcrumbItem/breadcrumbItem.css +2 -1
- package/src/modules/doc/breadcrumbs/breadcrumbs.css +2 -0
- package/src/modules/doc/breadcrumbs/breadcrumbs.html +1 -1
- package/src/modules/doc/breadcrumbs/breadcrumbs.ts +31 -6
- package/src/modules/doc/contentLayout/contentLayout.css +1 -5
- package/src/modules/doc/contentLayout/contentLayout.html +2 -9
- package/src/modules/doc/contentLayout/contentLayout.ts +29 -74
- package/src/modules/doc/xmlContent/types.ts +3 -0
- package/src/modules/doc/xmlContent/utils.ts +14 -11
- package/src/modules/doc/xmlContent/xmlContent.css +5 -0
- package/src/modules/doc/xmlContent/xmlContent.html +5 -0
- package/src/modules/doc/xmlContent/xmlContent.ts +64 -15
- package/src/modules/doc/amfReference/constants.ts +0 -76
|
@@ -3,7 +3,7 @@ import { noCase } from "no-case";
|
|
|
3
3
|
import { sentenceCase } from "sentence-case";
|
|
4
4
|
import qs from "query-string";
|
|
5
5
|
import { AmfModelParser } from "./utils";
|
|
6
|
-
import {
|
|
6
|
+
import { RouteMeta } from "./route-meta";
|
|
7
7
|
import type {
|
|
8
8
|
AmfConfig,
|
|
9
9
|
AmfMetadataTopic,
|
|
@@ -14,46 +14,94 @@ import type {
|
|
|
14
14
|
TopicModel,
|
|
15
15
|
ReferenceVersion,
|
|
16
16
|
ReferenceSetConfig,
|
|
17
|
-
AmfMetaTopicType
|
|
18
|
-
RouteMeta,
|
|
19
|
-
ParsedMarkdownTopic
|
|
17
|
+
AmfMetaTopicType
|
|
20
18
|
} from "./types";
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
const NAVIGATION_ITEMS = [
|
|
21
|
+
{
|
|
22
|
+
label: "Summary",
|
|
23
|
+
name: "summary",
|
|
24
|
+
childrenPropertyName: undefined,
|
|
25
|
+
type: "summary"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
label: "Endpoints",
|
|
29
|
+
name: "endpoints",
|
|
30
|
+
childrenPropertyName: "endpoints",
|
|
31
|
+
type: "endpoint"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
label: "Documentation",
|
|
35
|
+
name: "documentation",
|
|
36
|
+
childrenPropertyName: "docs",
|
|
37
|
+
type: "documentation"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
label: "Types",
|
|
41
|
+
name: "types",
|
|
42
|
+
childrenPropertyName: "types",
|
|
43
|
+
type: "type"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
label: "Security",
|
|
47
|
+
name: "security",
|
|
48
|
+
childrenPropertyName: "security",
|
|
49
|
+
type: "security"
|
|
50
|
+
}
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
const URL_CONFIG = {
|
|
54
|
+
summary: {
|
|
55
|
+
urlIdentifer: "label"
|
|
56
|
+
},
|
|
57
|
+
endpoint: {
|
|
58
|
+
urlIdentifer: "path"
|
|
59
|
+
},
|
|
60
|
+
method: {
|
|
61
|
+
urlIdentifer: "label"
|
|
62
|
+
},
|
|
63
|
+
documentation: {
|
|
64
|
+
urlIdentifer: "label"
|
|
65
|
+
},
|
|
66
|
+
type: {
|
|
67
|
+
urlIdentifer: "label",
|
|
68
|
+
prefix: "type:"
|
|
69
|
+
},
|
|
70
|
+
security: {
|
|
71
|
+
urlIdentifer: "label",
|
|
72
|
+
prefix: "security:"
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const urlHashToMetaRedirectMap = {
|
|
77
|
+
"commerce-api-assignments:Summary": "assignments:Summary",
|
|
78
|
+
"commerce-api-campaigns:Summary": "campaigns:Summary",
|
|
79
|
+
"commerce-api-catalogs:Summary": "catalogs:Summary",
|
|
80
|
+
"cdn-zones:Summary": "cdn-api-process-apis:Summary",
|
|
81
|
+
"inventory-impex:Summary": "impex:Summary",
|
|
82
|
+
"inventory-reservations:Summary": "inventory-reservation-service:Summary",
|
|
83
|
+
"shopper-login-and-api-access-service:Summary": "shopper-login:Summary",
|
|
84
|
+
"shopper-login-and-api-access-service-admin:Summary": "slas-admin:Summary",
|
|
85
|
+
"einstein-recommendations:Summary": "einstein-api-quick-start-guide:Summary"
|
|
86
|
+
};
|
|
28
87
|
|
|
29
88
|
export default class AmfReference extends LightningElement {
|
|
30
|
-
@api breadcrumbs?: string
|
|
31
|
-
@api sidebarHeader
|
|
89
|
+
@api breadcrumbs?: string = null;
|
|
90
|
+
@api sidebarHeader: string;
|
|
32
91
|
@api coveoOrganizationId!: string;
|
|
33
92
|
@api coveoPublicAccessToken!: string;
|
|
34
93
|
@api coveoAdvancedQueryConfig!: string;
|
|
35
94
|
@api coveoSearchHub!: string;
|
|
36
95
|
@api useOldSidebar?: boolean = false;
|
|
37
|
-
@api tocTitle?: string;
|
|
38
|
-
@api tocOptions?: string;
|
|
39
|
-
@track navigation = [];
|
|
40
|
-
@track versions: Array<ReferenceVersion> = [];
|
|
41
96
|
|
|
42
97
|
// Update this to update what component gets rendered in the content block
|
|
43
98
|
@track
|
|
44
|
-
protected topicModel
|
|
99
|
+
protected topicModel: TopicModel;
|
|
45
100
|
|
|
46
101
|
get isVersionEnabled(): boolean {
|
|
47
102
|
return !!this._referenceSetConfig?.versions?.length;
|
|
48
103
|
}
|
|
49
104
|
|
|
50
|
-
/**
|
|
51
|
-
* Gives if the currently selected reference is spec based or not
|
|
52
|
-
*/
|
|
53
|
-
get showSpecBasedReference(): boolean {
|
|
54
|
-
return this.isSpecBasedReference(this._currentReferenceId);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
105
|
@api
|
|
58
106
|
get referenceSetConfig(): ReferenceSetConfig {
|
|
59
107
|
return this._referenceSetConfig;
|
|
@@ -74,42 +122,22 @@ export default class AmfReference extends LightningElement {
|
|
|
74
122
|
this._referenceSetConfig = refConfig;
|
|
75
123
|
} catch (e) {
|
|
76
124
|
this._referenceSetConfig = {
|
|
77
|
-
refList: []
|
|
78
|
-
versions: []
|
|
125
|
+
refList: []
|
|
79
126
|
};
|
|
80
127
|
}
|
|
81
128
|
|
|
82
|
-
this._amfConfigList = this._referenceSetConfig.refList || [];
|
|
83
|
-
|
|
84
|
-
this._amfConfigList.forEach((amfConfig) => {
|
|
85
|
-
this._amfConfigMap.set(amfConfig.id, amfConfig);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
if (this._amfConfigList.length > 0) {
|
|
89
|
-
this._currentReferenceId =
|
|
90
|
-
this._referenceSetConfig.refId || this._amfConfigList[0].id;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
129
|
if (this.isVersionEnabled) {
|
|
94
130
|
const selectedVersion = this.getSelectedVersion();
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
*/
|
|
100
|
-
if (this.isSpecBasedReference(this._currentReferenceId)) {
|
|
101
|
-
this.versions = this.getVersions();
|
|
102
|
-
}
|
|
131
|
+
this.versionToRefMap = this._referenceSetConfig.versionToRefMap;
|
|
132
|
+
// if version is not available, then show empty - this will be the default behaviour
|
|
133
|
+
this._amfConfig = this.versionToRefMap[selectedVersion.id] || [];
|
|
134
|
+
this.versions = this._referenceSetConfig.versions;
|
|
103
135
|
this.selectedVersion = selectedVersion;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// This is to check if the url is hash based and redirect if needed
|
|
107
|
-
const redirectUrl = this.getHashBasedRedirectUrl();
|
|
108
|
-
if (redirectUrl) {
|
|
109
|
-
window.location.href = redirectUrl;
|
|
110
136
|
} else {
|
|
111
|
-
this.
|
|
137
|
+
this._amfConfig = this._referenceSetConfig.refList;
|
|
112
138
|
}
|
|
139
|
+
|
|
140
|
+
this.updateAmfConfigInView();
|
|
113
141
|
}
|
|
114
142
|
|
|
115
143
|
@api
|
|
@@ -124,51 +152,53 @@ export default class AmfReference extends LightningElement {
|
|
|
124
152
|
}
|
|
125
153
|
}
|
|
126
154
|
|
|
127
|
-
@api
|
|
128
|
-
get expandChildren() {
|
|
129
|
-
return this._expandChildren;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
set expandChildren(value) {
|
|
133
|
-
this._expandChildren = normalizeBoolean(value);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
155
|
// model
|
|
137
|
-
protected
|
|
138
|
-
protected
|
|
139
|
-
protected _referenceSetConfig!: ReferenceSetConfig;
|
|
156
|
+
protected _amfConfig: AmfConfig[] = [];
|
|
157
|
+
protected _referenceSetConfig: ReferenceSetConfig;
|
|
140
158
|
protected _currentReferenceId = "";
|
|
141
159
|
|
|
142
|
-
protected parentReferenceUrls = [];
|
|
143
160
|
protected amfMap: Record<string, AmfModelRecord> = {};
|
|
144
161
|
protected amfFetchPromiseMap = {};
|
|
145
162
|
protected metadata: { [key: string]: AmfMetadataTopic } = {};
|
|
146
|
-
protected selectedTopic
|
|
163
|
+
protected selectedTopic: AmfMetaTopicType = undefined;
|
|
164
|
+
protected navigation = [];
|
|
147
165
|
protected selectedSidebarValue = undefined;
|
|
148
|
-
|
|
149
|
-
protected selectedVersion: ReferenceVersion
|
|
166
|
+
protected versions: Array<ReferenceVersion> = [];
|
|
167
|
+
protected selectedVersion: ReferenceVersion = null;
|
|
150
168
|
|
|
151
169
|
private hasRendered = false;
|
|
170
|
+
private navAmfOrder = [];
|
|
171
|
+
|
|
172
|
+
private versionToRefMap: Map<string, Array<AmfConfig>>;
|
|
152
173
|
|
|
153
174
|
private isParentLevelDocPhaseEnabled = false;
|
|
154
|
-
private selectedReferenceDocPhase?: string
|
|
155
|
-
private _expandChildren?: boolean = false;
|
|
175
|
+
private selectedReferenceDocPhase?: string = null;
|
|
156
176
|
|
|
157
177
|
/**
|
|
158
|
-
* Key for storing the currently selected reference
|
|
159
|
-
* previously selected reference
|
|
178
|
+
* Key for storing the currently selected reference meta query param. This will be used to save the
|
|
179
|
+
* previously selected reference meta and restoring it when changing between reference versions.
|
|
160
180
|
*/
|
|
161
|
-
private readonly
|
|
181
|
+
private readonly docsReferenceMetaSessionKey: string = "docsReferenceMeta";
|
|
162
182
|
|
|
163
183
|
_boundOnApiNavigationChanged;
|
|
164
184
|
_boundUpdateSelectedItemFromUrlQuery;
|
|
165
185
|
|
|
186
|
+
get amfConfigMapped(): AmfConfig[] {
|
|
187
|
+
return this._amfConfig.map((config) => {
|
|
188
|
+
return config.id in this.amfMap
|
|
189
|
+
? Object.assign(config, this.amfMap[config.id])
|
|
190
|
+
: config;
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
166
194
|
constructor() {
|
|
167
195
|
super();
|
|
168
|
-
this._boundOnApiNavigationChanged =
|
|
169
|
-
this
|
|
170
|
-
|
|
171
|
-
|
|
196
|
+
this._boundOnApiNavigationChanged = this.onApiNavigationChanged.bind(
|
|
197
|
+
this
|
|
198
|
+
);
|
|
199
|
+
this._boundUpdateSelectedItemFromUrlQuery = this.updateSelectedItemFromUrlQuery.bind(
|
|
200
|
+
this
|
|
201
|
+
);
|
|
172
202
|
}
|
|
173
203
|
|
|
174
204
|
connectedCallback(): void {
|
|
@@ -196,7 +226,7 @@ export default class AmfReference extends LightningElement {
|
|
|
196
226
|
renderedCallback(): void {
|
|
197
227
|
if (!this.hasRendered) {
|
|
198
228
|
this.hasRendered = true;
|
|
199
|
-
if (this.
|
|
229
|
+
if (this._amfConfig && this._amfConfig.length) {
|
|
200
230
|
// If amfConfig has a value and length, it is assumed that fetch
|
|
201
231
|
// has already been called and promises stored.
|
|
202
232
|
this.updateView();
|
|
@@ -204,109 +234,6 @@ export default class AmfReference extends LightningElement {
|
|
|
204
234
|
}
|
|
205
235
|
}
|
|
206
236
|
|
|
207
|
-
/**
|
|
208
|
-
* Check if the URL hash to see whether this is one we want to redirect
|
|
209
|
-
* See GUS W-10718771 for references where we want hash-based redirects
|
|
210
|
-
* Return if we needs to redirect url to updated url
|
|
211
|
-
*/
|
|
212
|
-
private getHashBasedRedirectUrl(): string | undefined {
|
|
213
|
-
const { hash } = window.location;
|
|
214
|
-
let hashBasedRedirectUrl = "";
|
|
215
|
-
if (hash) {
|
|
216
|
-
const strippedHash = hash.startsWith("#") ? hash.slice(1) : hash;
|
|
217
|
-
const strippedHashItems = strippedHash
|
|
218
|
-
? strippedHash.split(":")
|
|
219
|
-
: [];
|
|
220
|
-
if (strippedHashItems.length) {
|
|
221
|
-
const referenceId = strippedHashItems[0];
|
|
222
|
-
const meta = strippedHashItems[1];
|
|
223
|
-
const encodedMeta = this.getUrlEncoded(meta);
|
|
224
|
-
const updatedReferenceId =
|
|
225
|
-
oldReferenceIdNewReferenceIdMap[referenceId];
|
|
226
|
-
const newReferenceId = updatedReferenceId || referenceId;
|
|
227
|
-
const referenceItemConfig =
|
|
228
|
-
this.getAmfConfigWithId(newReferenceId);
|
|
229
|
-
if (referenceItemConfig) {
|
|
230
|
-
hashBasedRedirectUrl = `${referenceItemConfig.href}?meta=${encodedMeta}`;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return hashBasedRedirectUrl;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* @param referenceId
|
|
239
|
-
* @returns AMFConfig with given reference Id
|
|
240
|
-
*/
|
|
241
|
-
private getAmfConfigWithId(referenceId: string): AmfConfig | undefined {
|
|
242
|
-
return this._amfConfigMap.get(referenceId);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* @param referenceId
|
|
247
|
-
* @returns if the reference is spec based one or not with given referenceId.
|
|
248
|
-
*/
|
|
249
|
-
private isSpecBasedReference(referenceId: string): boolean {
|
|
250
|
-
const selectedReference = this.getAmfConfigWithId(referenceId);
|
|
251
|
-
return selectedReference
|
|
252
|
-
? selectedReference.referenceType !== REFERENCE_TYPES.markdown
|
|
253
|
-
: false;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/*
|
|
257
|
-
* Refactor below method when sidebar allows sending extraData along with the name for each item.
|
|
258
|
-
* See if we can refactor the below method using regex.
|
|
259
|
-
*/
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* @param url
|
|
263
|
-
* @returns reference Id from url path / selected sidebar item.
|
|
264
|
-
*/
|
|
265
|
-
private getReferenceIdFromUrl(url: string): string {
|
|
266
|
-
let referenceId = "";
|
|
267
|
-
const urlItems = url.split("/references/");
|
|
268
|
-
if (urlItems.length > 1) {
|
|
269
|
-
const rightSidePart = urlItems[1];
|
|
270
|
-
|
|
271
|
-
//This covers urls like "/project-name/references/reference-id/..."
|
|
272
|
-
const slashSeparatorItems = rightSidePart.split("/");
|
|
273
|
-
|
|
274
|
-
//This covers urls like "/project-name/references/reference-id?meta=Summary"
|
|
275
|
-
const querySeparatorItems = slashSeparatorItems[0].split("?");
|
|
276
|
-
|
|
277
|
-
referenceId = querySeparatorItems[0];
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
return referenceId;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* @returns versions to be shown in the dropdown
|
|
285
|
-
* For markdown based specs, Adds selected markdown topic url to same references
|
|
286
|
-
*/
|
|
287
|
-
private getVersions(): Array<ReferenceVersion> {
|
|
288
|
-
const allVersions = this._referenceSetConfig.versions;
|
|
289
|
-
if (!this.isSpecBasedReference(this._currentReferenceId)) {
|
|
290
|
-
const currentRefMeta = this.getMarkdownReferenceMeta(
|
|
291
|
-
window.location.href
|
|
292
|
-
);
|
|
293
|
-
if (currentRefMeta) {
|
|
294
|
-
for (let i = 0; i < allVersions.length; i++) {
|
|
295
|
-
const versionItem = allVersions[i];
|
|
296
|
-
const referenceLink = versionItem.link.href;
|
|
297
|
-
const referenceId =
|
|
298
|
-
this.getReferenceIdFromUrl(referenceLink);
|
|
299
|
-
if (this._currentReferenceId === referenceId) {
|
|
300
|
-
// This is to navigate to respective topic in the changed version
|
|
301
|
-
versionItem.link.href = `${referenceLink}/${currentRefMeta}`;
|
|
302
|
-
allVersions[i] = versionItem;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
return allVersions;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
237
|
/**
|
|
311
238
|
* Returns the selected version or the first available version.
|
|
312
239
|
*/
|
|
@@ -320,9 +247,9 @@ export default class AmfReference extends LightningElement {
|
|
|
320
247
|
}
|
|
321
248
|
|
|
322
249
|
private updateAmfConfigInView(): void {
|
|
323
|
-
if (this.
|
|
250
|
+
if (this._amfConfig && this._amfConfig.length) {
|
|
324
251
|
// fetch AMF Json as soon as config is set
|
|
325
|
-
this.
|
|
252
|
+
this.fetchAllAmf();
|
|
326
253
|
// update() must be called after renderedCallback.
|
|
327
254
|
if (this.hasRendered) {
|
|
328
255
|
this.updateView();
|
|
@@ -342,69 +269,17 @@ export default class AmfReference extends LightningElement {
|
|
|
342
269
|
}
|
|
343
270
|
|
|
344
271
|
/**
|
|
345
|
-
*
|
|
346
|
-
|
|
347
|
-
private isProjectRootPath(): boolean {
|
|
348
|
-
return this.getReferenceIdFromUrl(window.location.href) === "";
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Returns whether given url is parent reference path like ../example-project/references/reference-id
|
|
272
|
+
* Calls the fetch for each AMF in the config.
|
|
273
|
+
* Stores each fetch promise for handling after renderCallback.
|
|
353
274
|
*/
|
|
354
|
-
private
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
}
|
|
362
|
-
);
|
|
363
|
-
return parentReferenceIndex !== -1;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
/**
|
|
367
|
-
* Populates reference Items from amfConfigList and assigns it to navigation for sidebar
|
|
368
|
-
*/
|
|
369
|
-
private populateReferenceItems(): void {
|
|
370
|
-
const navAmfOrder = [];
|
|
371
|
-
for (const [index, amfConfig] of this._amfConfigList.entries()) {
|
|
372
|
-
let navItemChildren = [];
|
|
373
|
-
let isChildrenLoading = false;
|
|
374
|
-
if (amfConfig.referenceType !== REFERENCE_TYPES.markdown) {
|
|
375
|
-
if (amfConfig.isSelected) {
|
|
376
|
-
const amfPromise = this.fetchAmf(amfConfig).then(
|
|
377
|
-
(amfJson) => {
|
|
378
|
-
this.updateModel(amfConfig.id, amfJson);
|
|
379
|
-
this.assignNavigationItemsFromAmf(amfConfig, index);
|
|
380
|
-
}
|
|
381
|
-
);
|
|
382
|
-
this.amfFetchPromiseMap[amfConfig.id] = amfPromise;
|
|
383
|
-
}
|
|
384
|
-
isChildrenLoading = true;
|
|
385
|
-
} else {
|
|
386
|
-
navItemChildren = amfConfig.topic.children;
|
|
387
|
-
}
|
|
388
|
-
// store nav items for each spec in order
|
|
389
|
-
navAmfOrder[index] = {
|
|
390
|
-
label: amfConfig.title,
|
|
391
|
-
name: amfConfig.href,
|
|
392
|
-
isExpanded:
|
|
393
|
-
amfConfig.isSelected ||
|
|
394
|
-
this.isExpandChildrenEnabled(amfConfig.id),
|
|
395
|
-
children: navItemChildren,
|
|
396
|
-
isChildrenLoading
|
|
397
|
-
};
|
|
398
|
-
this.parentReferenceUrls.push(amfConfig.href);
|
|
275
|
+
private fetchAllAmf(): void {
|
|
276
|
+
for (const [i, amfConfig] of this._amfConfig.entries()) {
|
|
277
|
+
const p = this.fetchAmf(amfConfig).then((amfJson) => {
|
|
278
|
+
this.updateModel(amfConfig.id, amfJson);
|
|
279
|
+
this.assignNavigationItemsFromAmf(amfConfig.id, i);
|
|
280
|
+
});
|
|
281
|
+
this.amfFetchPromiseMap[amfConfig.id] = p;
|
|
399
282
|
}
|
|
400
|
-
this.navigation = navAmfOrder;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
/**
|
|
404
|
-
* Returns a boolean indicating whether the children should be expanded or not.
|
|
405
|
-
*/
|
|
406
|
-
private isExpandChildrenEnabled(referenceId: string): boolean {
|
|
407
|
-
return this.expandChildren && this._currentReferenceId === referenceId;
|
|
408
283
|
}
|
|
409
284
|
|
|
410
285
|
/**
|
|
@@ -436,7 +311,7 @@ export default class AmfReference extends LightningElement {
|
|
|
436
311
|
|
|
437
312
|
/**
|
|
438
313
|
* Transforms a list of model data for endpoints into corresponding
|
|
439
|
-
* navigation list items that
|
|
314
|
+
* navigation list items that is compatible with dx-sidebar.
|
|
440
315
|
* Compatible with transforming AMF data parsed from both RAML and OAS spec.
|
|
441
316
|
* Transforms a flat list of endpoints into a nested list based on indentation level
|
|
442
317
|
* for RAML spec.
|
|
@@ -444,7 +319,6 @@ export default class AmfReference extends LightningElement {
|
|
|
444
319
|
* @returns {array<Object>} List of navigation items
|
|
445
320
|
*/
|
|
446
321
|
private assignEndpointNavItems(
|
|
447
|
-
parentReferencePath: string,
|
|
448
322
|
referenceId: string,
|
|
449
323
|
items: ParsedTopicModel[]
|
|
450
324
|
): NavItem[] {
|
|
@@ -452,39 +326,22 @@ export default class AmfReference extends LightningElement {
|
|
|
452
326
|
|
|
453
327
|
items.forEach((item) => {
|
|
454
328
|
item.methods?.forEach((method) => {
|
|
455
|
-
const
|
|
456
|
-
this.getTitleForLabel(method.label) || method.method;
|
|
457
|
-
const meta = this.addToMetadata(
|
|
458
|
-
parentReferencePath,
|
|
459
|
-
referenceId,
|
|
460
|
-
"method",
|
|
461
|
-
method,
|
|
462
|
-
title
|
|
463
|
-
);
|
|
329
|
+
const meta = this.addToMetadata(referenceId, "method", method);
|
|
464
330
|
methodList.push(
|
|
465
331
|
Object.assign(method, {
|
|
466
|
-
name: this.getReferencePathWithMeta(
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
),
|
|
470
|
-
label: title
|
|
332
|
+
name: this.getReferencePathWithMeta(meta),
|
|
333
|
+
label:
|
|
334
|
+
this.getTitleForLabel(method.label) || method.method
|
|
471
335
|
})
|
|
472
336
|
);
|
|
473
337
|
});
|
|
474
338
|
});
|
|
339
|
+
|
|
475
340
|
return methodList;
|
|
476
341
|
}
|
|
477
342
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
*/
|
|
481
|
-
private getReferencePathWithMeta(
|
|
482
|
-
parentReferencePath: string,
|
|
483
|
-
meta: string
|
|
484
|
-
): string {
|
|
485
|
-
// update the encoded url meta param
|
|
486
|
-
const encodedMeta = meta ? this.getUrlEncoded(meta) : "";
|
|
487
|
-
return encodedMeta ? `${parentReferencePath}?meta=${encodedMeta}` : "";
|
|
343
|
+
private getReferencePathWithMeta(meta: string): string {
|
|
344
|
+
return meta ? `${window.location.pathname}?meta=${meta}` : "";
|
|
488
345
|
}
|
|
489
346
|
|
|
490
347
|
/**
|
|
@@ -494,15 +351,12 @@ export default class AmfReference extends LightningElement {
|
|
|
494
351
|
* The 'endpoint' nav item may have nested children.
|
|
495
352
|
*/
|
|
496
353
|
private assignNavigationItemsFromAmf(
|
|
497
|
-
|
|
354
|
+
referenceId: string,
|
|
498
355
|
amfIdx: number
|
|
499
356
|
): void {
|
|
500
|
-
const referenceId = amfConfig.id;
|
|
501
|
-
const parentReferencePath = amfConfig.href;
|
|
502
357
|
const model = this.amfMap[referenceId].parser.parsedModel;
|
|
503
358
|
|
|
504
359
|
const children = [];
|
|
505
|
-
const expandChildren = this.isExpandChildrenEnabled(referenceId);
|
|
506
360
|
|
|
507
361
|
NAVIGATION_ITEMS.forEach(
|
|
508
362
|
({ label, name, childrenPropertyName, type }) => {
|
|
@@ -511,18 +365,13 @@ export default class AmfReference extends LightningElement {
|
|
|
511
365
|
case "summary": {
|
|
512
366
|
const summary = model[type];
|
|
513
367
|
const meta = this.addToMetadata(
|
|
514
|
-
parentReferencePath,
|
|
515
368
|
referenceId,
|
|
516
369
|
type,
|
|
517
|
-
summary
|
|
518
|
-
label
|
|
370
|
+
summary
|
|
519
371
|
);
|
|
520
372
|
children.push({
|
|
521
373
|
label,
|
|
522
|
-
name: this.getReferencePathWithMeta(
|
|
523
|
-
parentReferencePath,
|
|
524
|
-
meta
|
|
525
|
-
)
|
|
374
|
+
name: this.getReferencePathWithMeta(meta)
|
|
526
375
|
});
|
|
527
376
|
break;
|
|
528
377
|
}
|
|
@@ -536,17 +385,15 @@ export default class AmfReference extends LightningElement {
|
|
|
536
385
|
indexedName
|
|
537
386
|
);
|
|
538
387
|
const childTopics = this.assignEndpointNavItems(
|
|
539
|
-
parentReferencePath,
|
|
540
388
|
referenceId,
|
|
541
389
|
model[childrenPropertyName]
|
|
542
390
|
);
|
|
543
391
|
children.push({
|
|
544
392
|
label,
|
|
545
393
|
name: this.getReferencePathWithMeta(
|
|
546
|
-
parentReferencePath,
|
|
547
394
|
this.metadata[amfTopicId]?.meta
|
|
548
395
|
),
|
|
549
|
-
isExpanded:
|
|
396
|
+
isExpanded: false,
|
|
550
397
|
children: childTopics
|
|
551
398
|
});
|
|
552
399
|
}
|
|
@@ -578,23 +425,19 @@ export default class AmfReference extends LightningElement {
|
|
|
578
425
|
children.push({
|
|
579
426
|
label,
|
|
580
427
|
name: this.getReferencePathWithMeta(
|
|
581
|
-
parentReferencePath,
|
|
582
428
|
this.metadata[amfTopicId]?.meta
|
|
583
429
|
),
|
|
584
|
-
isExpanded:
|
|
430
|
+
isExpanded: false,
|
|
585
431
|
children: model[childrenPropertyName].map(
|
|
586
432
|
(topic) => {
|
|
587
433
|
const meta = this.addToMetadata(
|
|
588
|
-
parentReferencePath,
|
|
589
434
|
referenceId,
|
|
590
435
|
type,
|
|
591
|
-
topic
|
|
592
|
-
topic.label
|
|
436
|
+
topic
|
|
593
437
|
);
|
|
594
438
|
return {
|
|
595
439
|
label: topic.label,
|
|
596
440
|
name: this.getReferencePathWithMeta(
|
|
597
|
-
parentReferencePath,
|
|
598
441
|
meta
|
|
599
442
|
)
|
|
600
443
|
};
|
|
@@ -606,41 +449,46 @@ export default class AmfReference extends LightningElement {
|
|
|
606
449
|
}
|
|
607
450
|
);
|
|
608
451
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
452
|
+
// store nav items for each spec in order
|
|
453
|
+
this.navAmfOrder[amfIdx] = {
|
|
454
|
+
label: model.title,
|
|
455
|
+
name: this.getReferencePathWithMeta(`${referenceId}-root`),
|
|
456
|
+
isExpanded: amfIdx === 0, // only expand the first spec
|
|
457
|
+
children
|
|
613
458
|
};
|
|
614
|
-
|
|
459
|
+
|
|
460
|
+
// update navigation with each specs nav items as they become available
|
|
461
|
+
// navigation has to be an array because dx-sidebar expects an array.
|
|
462
|
+
const navigation = [];
|
|
463
|
+
for (const navAmf of this.navAmfOrder) {
|
|
464
|
+
if (navAmf) {
|
|
465
|
+
navigation.push(navAmf);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
this.navigation = navigation;
|
|
615
469
|
}
|
|
616
470
|
|
|
617
471
|
protected addToMetadata(
|
|
618
|
-
parentReferencePath: string,
|
|
619
472
|
referenceId: string,
|
|
620
473
|
type: string,
|
|
621
|
-
topic: { id: string; domId: string }
|
|
622
|
-
|
|
623
|
-
): string | undefined {
|
|
474
|
+
topic: { id: string; domId: string }
|
|
475
|
+
): string {
|
|
624
476
|
const { urlIdentifer, prefix } = URL_CONFIG[type];
|
|
625
477
|
|
|
626
478
|
// encodeURI to avoid special characters in the URL meta.
|
|
627
479
|
const identifier =
|
|
628
480
|
topic[urlIdentifer] && this.encodeIdentifier(topic[urlIdentifer]);
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
type,
|
|
641
|
-
navTitle
|
|
642
|
-
};
|
|
643
|
-
}
|
|
481
|
+
const meta = prefix
|
|
482
|
+
? `${referenceId}:${prefix}${identifier}`
|
|
483
|
+
: `${referenceId}:${identifier}`;
|
|
484
|
+
this.metadata[meta] = {
|
|
485
|
+
meta: meta,
|
|
486
|
+
referenceId: referenceId,
|
|
487
|
+
amfId: topic.id,
|
|
488
|
+
elementId: topic.domId,
|
|
489
|
+
identifier,
|
|
490
|
+
type
|
|
491
|
+
};
|
|
644
492
|
return meta;
|
|
645
493
|
}
|
|
646
494
|
|
|
@@ -699,25 +547,54 @@ export default class AmfReference extends LightningElement {
|
|
|
699
547
|
}
|
|
700
548
|
|
|
701
549
|
/**
|
|
702
|
-
* Parses
|
|
550
|
+
* Parses url query params without decoding of params
|
|
703
551
|
*/
|
|
704
|
-
private parseParams(
|
|
705
|
-
if (!
|
|
552
|
+
private parseParams(path: string): qs.ParsedQuery<string> {
|
|
553
|
+
if (!path) {
|
|
706
554
|
return {};
|
|
707
555
|
}
|
|
708
|
-
return qs.parse(
|
|
556
|
+
return qs.parse(path, {
|
|
709
557
|
decode: false
|
|
710
558
|
});
|
|
711
559
|
}
|
|
712
560
|
|
|
561
|
+
/**
|
|
562
|
+
* Gets the portion from the URL query param 'meta'.
|
|
563
|
+
*/
|
|
564
|
+
protected getCurrentRefMeta(
|
|
565
|
+
previousRefMetaInSession?: string
|
|
566
|
+
): RouteMeta | null {
|
|
567
|
+
const path = window.location.search;
|
|
568
|
+
const urlParams = this.parseParams(path);
|
|
569
|
+
let meta = urlParams.meta as string;
|
|
570
|
+
let routeMeta = null;
|
|
571
|
+
if (previousRefMetaInSession) {
|
|
572
|
+
const refParts = previousRefMetaInSession.split(":");
|
|
573
|
+
const newRefId = refParts.length > 0 ? refParts[0] : null;
|
|
574
|
+
const [, type, topicId] = previousRefMetaInSession.split(":");
|
|
575
|
+
meta = newRefId ? [newRefId, type, topicId].join(":") : null;
|
|
576
|
+
} else if (!meta) {
|
|
577
|
+
// If no `meta` explicitly exists, check the URL hash to see whether this is one we
|
|
578
|
+
// want to redirect (see GUS W-10718771 for one reference where we want hash-based
|
|
579
|
+
// redirects)
|
|
580
|
+
const { hash } = window.location;
|
|
581
|
+
const strippedHash = hash.startsWith("#") ? hash.slice(1) : hash;
|
|
582
|
+
meta = urlHashToMetaRedirectMap[strippedHash];
|
|
583
|
+
}
|
|
584
|
+
if (meta) {
|
|
585
|
+
routeMeta = new RouteMeta(meta);
|
|
586
|
+
}
|
|
587
|
+
return routeMeta;
|
|
588
|
+
}
|
|
589
|
+
|
|
713
590
|
/**
|
|
714
591
|
* Normalizes topic identifier by replacing spaces with '+'
|
|
715
592
|
* and running encodeURI() on it
|
|
716
|
-
* @param
|
|
593
|
+
* @param identifer raw identifer for a topic as parsed from the spec file
|
|
717
594
|
* @returns normalized and encoded identifier
|
|
718
595
|
*/
|
|
719
|
-
protected encodeIdentifier(
|
|
720
|
-
let result =
|
|
596
|
+
protected encodeIdentifier(identifer: string): string {
|
|
597
|
+
let result = identifer.trim();
|
|
721
598
|
result = result.replace(new RegExp(/\s+/, "g"), "+");
|
|
722
599
|
return encodeURI(result);
|
|
723
600
|
}
|
|
@@ -729,134 +606,86 @@ export default class AmfReference extends LightningElement {
|
|
|
729
606
|
return `${referenceId}:${id}`;
|
|
730
607
|
}
|
|
731
608
|
|
|
732
|
-
protected
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
609
|
+
protected updateSelectedItemFromUrlQuery(): void {
|
|
610
|
+
const currentMeta: RouteMeta | null = this.getCurrentRefMeta();
|
|
611
|
+
const metadata = currentMeta && this.getMetadataByUrlQuery(currentMeta);
|
|
612
|
+
if (metadata) {
|
|
613
|
+
const {
|
|
614
|
+
referenceId,
|
|
615
|
+
amfId,
|
|
616
|
+
type,
|
|
617
|
+
elementId
|
|
618
|
+
}: AmfMetadataTopic = metadata;
|
|
619
|
+
this.loadContent(
|
|
620
|
+
referenceId,
|
|
621
|
+
amfId,
|
|
622
|
+
type,
|
|
623
|
+
elementId,
|
|
624
|
+
currentMeta.meta
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
protected onApiNavigationChanged(): void {
|
|
629
|
+
// The API Navigation event will always intend to navigate within the current reference
|
|
630
|
+
const metadata = this.metadata[
|
|
631
|
+
this.getReferencePathWithMeta(this.selectedTopic.meta)
|
|
632
|
+
];
|
|
633
|
+
const {
|
|
634
|
+
referenceId,
|
|
635
|
+
amfId,
|
|
636
|
+
type,
|
|
637
|
+
elementId
|
|
638
|
+
}: AmfMetadataTopic = metadata;
|
|
639
|
+
this.loadContent(referenceId, amfId, type, elementId, metadata.meta);
|
|
640
|
+
this.updateUrlWithSelected();
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
protected updateUrlWithSelected(meta?: string): void {
|
|
736
644
|
if (meta) {
|
|
737
|
-
// update the encoded url meta param
|
|
738
|
-
const encodedMeta = this.getUrlEncoded(meta);
|
|
739
645
|
window.history.pushState(
|
|
740
646
|
{},
|
|
741
647
|
"",
|
|
742
|
-
`${
|
|
648
|
+
`${window.location.pathname}?meta=${meta}`
|
|
743
649
|
);
|
|
744
650
|
}
|
|
745
651
|
}
|
|
746
652
|
|
|
747
653
|
/**
|
|
748
|
-
* Does a replace on the
|
|
654
|
+
* Does a replace on the url meta, so it does not create a history entry.
|
|
749
655
|
*/
|
|
750
|
-
protected replaceUrlWithSelected(
|
|
751
|
-
parentReferencePath: string,
|
|
752
|
-
meta?: string
|
|
753
|
-
): void {
|
|
656
|
+
protected replaceUrlWithSelected(meta?: string): void {
|
|
754
657
|
if (meta) {
|
|
755
|
-
// update the encoded url meta param
|
|
756
|
-
const encodedMeta = this.getUrlEncoded(meta);
|
|
757
658
|
window.history.replaceState(
|
|
758
659
|
{},
|
|
759
660
|
"",
|
|
760
|
-
`${
|
|
661
|
+
`${window.location.pathname}?meta=${meta}`
|
|
761
662
|
);
|
|
762
663
|
}
|
|
763
664
|
}
|
|
764
665
|
|
|
765
|
-
/**
|
|
766
|
-
* This method gets called when the user navigates back and forth using browser arrows
|
|
767
|
-
* Updates content depending on the type of reference - spec based or markdown
|
|
768
|
-
*/
|
|
769
|
-
protected updateSelectedItemFromUrlQuery(): void {
|
|
770
|
-
const specBasedReference = this.isSpecBasedReference(
|
|
771
|
-
this._currentReferenceId
|
|
772
|
-
);
|
|
773
|
-
if (specBasedReference) {
|
|
774
|
-
const currentMeta: RouteMeta | null = this.getReferenceMetaInfo(
|
|
775
|
-
window.location.href
|
|
776
|
-
);
|
|
777
|
-
const metadata =
|
|
778
|
-
currentMeta && this.getMetadataByUrlQuery(currentMeta);
|
|
779
|
-
if (metadata) {
|
|
780
|
-
const {
|
|
781
|
-
parentReferencePath,
|
|
782
|
-
referenceId,
|
|
783
|
-
amfId,
|
|
784
|
-
type,
|
|
785
|
-
elementId
|
|
786
|
-
}: AmfMetadataTopic = metadata;
|
|
787
|
-
this.loadSpecReferenceContent(
|
|
788
|
-
parentReferencePath,
|
|
789
|
-
referenceId,
|
|
790
|
-
amfId,
|
|
791
|
-
type,
|
|
792
|
-
elementId,
|
|
793
|
-
currentMeta.meta
|
|
794
|
-
);
|
|
795
|
-
}
|
|
796
|
-
} else {
|
|
797
|
-
this.loadMarkdownBasedReference();
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
/**
|
|
802
|
-
* The API Navigation event will always intend to navigate within the current reference
|
|
803
|
-
* @param event
|
|
804
|
-
*/
|
|
805
|
-
protected onApiNavigationChanged(): void {
|
|
806
|
-
const specBasedReference = this.isSpecBasedReference(
|
|
807
|
-
this._currentReferenceId
|
|
808
|
-
);
|
|
809
|
-
if (specBasedReference) {
|
|
810
|
-
const { meta } = this.selectedTopic;
|
|
811
|
-
const metadata = this.metadata[meta];
|
|
812
|
-
if (metadata) {
|
|
813
|
-
const {
|
|
814
|
-
parentReferencePath,
|
|
815
|
-
referenceId,
|
|
816
|
-
amfId,
|
|
817
|
-
type,
|
|
818
|
-
elementId
|
|
819
|
-
}: AmfMetadataTopic = metadata;
|
|
820
|
-
this.loadSpecReferenceContent(
|
|
821
|
-
parentReferencePath,
|
|
822
|
-
referenceId,
|
|
823
|
-
amfId,
|
|
824
|
-
type,
|
|
825
|
-
elementId,
|
|
826
|
-
metadata.meta
|
|
827
|
-
);
|
|
828
|
-
}
|
|
829
|
-
} else {
|
|
830
|
-
this.loadMarkdownBasedReference();
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
|
|
834
666
|
/**
|
|
835
667
|
* Updates the currently selected amf and topic
|
|
836
668
|
*/
|
|
837
|
-
protected
|
|
838
|
-
parentReferencePath: string,
|
|
669
|
+
protected loadContent(
|
|
839
670
|
referenceId: string,
|
|
840
671
|
amfId: string,
|
|
841
672
|
type: string,
|
|
842
|
-
elementId
|
|
843
|
-
meta
|
|
673
|
+
elementId = "",
|
|
674
|
+
meta = ""
|
|
844
675
|
): void {
|
|
845
676
|
this.selectedTopic = {
|
|
846
677
|
referenceId,
|
|
847
|
-
parentReferencePath,
|
|
848
678
|
amfId,
|
|
849
679
|
elementId,
|
|
850
680
|
type,
|
|
851
681
|
meta
|
|
852
682
|
};
|
|
853
|
-
this.selectedSidebarValue = this.getReferencePathWithMeta(
|
|
854
|
-
parentReferencePath,
|
|
855
|
-
meta
|
|
856
|
-
);
|
|
683
|
+
this.selectedSidebarValue = this.getReferencePathWithMeta(meta);
|
|
857
684
|
|
|
858
685
|
this.handleSelectedItem();
|
|
859
686
|
|
|
687
|
+
// Ensures that the URL always has the meta, that way we don't get two history entries for summary
|
|
688
|
+
this.replaceUrlWithSelected(meta);
|
|
860
689
|
this.updateDocPhase();
|
|
861
690
|
}
|
|
862
691
|
|
|
@@ -867,9 +696,10 @@ export default class AmfReference extends LightningElement {
|
|
|
867
696
|
/* If parent level doc phase is enabled, Individual reference level doc phase should not be considered */
|
|
868
697
|
|
|
869
698
|
if (!this.isParentLevelDocPhaseEnabled) {
|
|
870
|
-
const
|
|
699
|
+
const referenceId = this.selectedTopic?.referenceId;
|
|
700
|
+
const selectedReference = this._amfConfig.find(
|
|
871
701
|
(referenceItem: AmfConfig) => {
|
|
872
|
-
return referenceItem.id ===
|
|
702
|
+
return referenceItem.id === referenceId;
|
|
873
703
|
}
|
|
874
704
|
);
|
|
875
705
|
if (selectedReference) {
|
|
@@ -881,414 +711,88 @@ export default class AmfReference extends LightningElement {
|
|
|
881
711
|
}
|
|
882
712
|
|
|
883
713
|
/**
|
|
884
|
-
*
|
|
885
|
-
*/
|
|
886
|
-
getMetaFromUrl(referenceUrl: string): string {
|
|
887
|
-
const indexOfQueryParam = referenceUrl.indexOf("?");
|
|
888
|
-
const urlPath = referenceUrl.substring(
|
|
889
|
-
indexOfQueryParam >= 0 ? indexOfQueryParam : referenceUrl.length
|
|
890
|
-
);
|
|
891
|
-
const meta = this.parseParams(urlPath).meta as string;
|
|
892
|
-
// Always get the meta query param encoded and decode it and store it for internal use
|
|
893
|
-
// This has 2 advantages,
|
|
894
|
-
// 1. Supports backward compatible meta query param, so there is no need for redirects.
|
|
895
|
-
// 2. Supports Prerender and Coveo for their crawling.
|
|
896
|
-
const encodedMeta = meta && this.getUrlEncoded(meta);
|
|
897
|
-
const decodedMeta = encodedMeta && decodeURIComponent(encodedMeta);
|
|
898
|
-
return decodedMeta || "";
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
/**
|
|
902
|
-
*
|
|
903
|
-
* @returns meta for given markdown based referenceUrl
|
|
904
|
-
* Consider last topic url in ../references/reference-name/example.html
|
|
905
|
-
*/
|
|
906
|
-
getMarkdownReferenceMeta(referenceUrl: string): string {
|
|
907
|
-
let meta = "";
|
|
908
|
-
if (referenceUrl) {
|
|
909
|
-
const slashSeparatorItems = referenceUrl.split("/");
|
|
910
|
-
const lastItem =
|
|
911
|
-
slashSeparatorItems[slashSeparatorItems.length - 1];
|
|
912
|
-
if (lastItem.endsWith(".html")) {
|
|
913
|
-
meta = lastItem;
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
return meta;
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
/**
|
|
920
|
-
* Gets the encoded url.
|
|
921
|
-
* This method will return the encoded url for 2 cases,
|
|
922
|
-
* 1. If the url is encoded already
|
|
923
|
-
* 2. If the url is decoded
|
|
924
|
-
*/
|
|
925
|
-
getUrlEncoded(url: string) {
|
|
926
|
-
// if url matches, then return the encoded url.
|
|
927
|
-
if (decodeURIComponent(url) === url) {
|
|
928
|
-
return encodeURIComponent(url);
|
|
929
|
-
}
|
|
930
|
-
// return the encoded url.
|
|
931
|
-
return this.getUrlEncoded(decodeURIComponent(url));
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
/**
|
|
935
|
-
*
|
|
936
|
-
* @returns RouteMeta object for given referenceUrl
|
|
937
|
-
* referenceId - gets referenceId from url
|
|
938
|
-
* For spec based references gets meta parm from url and then topicId & type from meta
|
|
939
|
-
* For markdown based references gets topicId as last html path in the name, meta & type will be empty
|
|
940
|
-
*/
|
|
941
|
-
getReferenceMetaInfo(referenceUrl: string): RouteMeta | undefined {
|
|
942
|
-
let metaReferenceInfo;
|
|
943
|
-
if (referenceUrl) {
|
|
944
|
-
const referenceId = this.getReferenceIdFromUrl(referenceUrl);
|
|
945
|
-
let meta = "";
|
|
946
|
-
let topicId = "";
|
|
947
|
-
let type = "";
|
|
948
|
-
if (this.isSpecBasedReference(referenceId)) {
|
|
949
|
-
meta = this.getMetaFromUrl(referenceUrl);
|
|
950
|
-
if (meta) {
|
|
951
|
-
if (meta.includes(":")) {
|
|
952
|
-
const metaInfo = meta.split(":");
|
|
953
|
-
type = metaInfo[0];
|
|
954
|
-
topicId = metaInfo[1] || type;
|
|
955
|
-
} else {
|
|
956
|
-
topicId = meta;
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
} else {
|
|
960
|
-
topicId = this.getMarkdownReferenceMeta(referenceUrl);
|
|
961
|
-
}
|
|
962
|
-
metaReferenceInfo = {
|
|
963
|
-
referenceId,
|
|
964
|
-
meta,
|
|
965
|
-
topicId,
|
|
966
|
-
type
|
|
967
|
-
};
|
|
968
|
-
}
|
|
969
|
-
return metaReferenceInfo;
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
/**
|
|
973
|
-
* Finds and returns referenceUrl and topicTitle if given topic url matches
|
|
974
|
-
*/
|
|
975
|
-
getReferenceDetailsInGivenTopics(
|
|
976
|
-
topics: ParsedMarkdownTopic[],
|
|
977
|
-
topicMeta: string
|
|
978
|
-
): { referenceUrl: string; topicTitle: string } {
|
|
979
|
-
let referenceUrl = "";
|
|
980
|
-
let topicTitle = "";
|
|
981
|
-
for (let i = 0; i < topics.length; i++) {
|
|
982
|
-
const topic = topics[i];
|
|
983
|
-
const meta = this.getMarkdownReferenceMeta(topic.link.href);
|
|
984
|
-
const childTopics = topic.children;
|
|
985
|
-
if (meta === topicMeta) {
|
|
986
|
-
referenceUrl = topic.link.href;
|
|
987
|
-
topicTitle = topic.label;
|
|
988
|
-
} else if (childTopics && childTopics.length) {
|
|
989
|
-
const referenceDetails = this.getReferenceDetailsInGivenTopics(
|
|
990
|
-
childTopics,
|
|
991
|
-
topicMeta
|
|
992
|
-
);
|
|
993
|
-
referenceUrl = referenceDetails.referenceUrl;
|
|
994
|
-
topicTitle = referenceDetails.topicTitle;
|
|
995
|
-
}
|
|
996
|
-
if (referenceUrl && topicTitle) {
|
|
997
|
-
break;
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
return {
|
|
1001
|
-
referenceUrl,
|
|
1002
|
-
topicTitle
|
|
1003
|
-
};
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
|
-
/**
|
|
1007
|
-
* Gives referenceUrl and topicTitle for given markdown topic url
|
|
1008
|
-
*/
|
|
1009
|
-
getRefDetailsForGivenTopicMeta(
|
|
1010
|
-
referenceId: string,
|
|
1011
|
-
topicMeta: string
|
|
1012
|
-
): { referenceUrl: string; topicTitle: string } | undefined {
|
|
1013
|
-
const amfConfig = this.getAmfConfigWithId(referenceId);
|
|
1014
|
-
let referenceDetails;
|
|
1015
|
-
if (amfConfig) {
|
|
1016
|
-
const topics = amfConfig.topic?.children || [];
|
|
1017
|
-
referenceDetails = this.getReferenceDetailsInGivenTopics(
|
|
1018
|
-
topics,
|
|
1019
|
-
topicMeta
|
|
1020
|
-
);
|
|
1021
|
-
}
|
|
1022
|
-
return referenceDetails;
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
/**
|
|
1026
|
-
* Updates the DOM on the first load
|
|
714
|
+
* Updates the DOM on first load
|
|
1027
715
|
*/
|
|
1028
716
|
updateView(): void {
|
|
1029
|
-
const previousRefUrlInSession = window.sessionStorage.getItem(
|
|
1030
|
-
this.docsReferenceUrlSessionKey
|
|
1031
|
-
);
|
|
1032
|
-
window.sessionStorage.removeItem(this.docsReferenceUrlSessionKey);
|
|
1033
|
-
let previousRefInfo = this.getReferenceMetaInfo(
|
|
1034
|
-
previousRefUrlInSession
|
|
1035
|
-
);
|
|
1036
|
-
|
|
1037
|
-
// For spec based reference, We should consider urlData to show same topic when user reloads after navigating to specific topic
|
|
1038
|
-
if (!previousRefInfo) {
|
|
1039
|
-
const currentUrl = window.location.href;
|
|
1040
|
-
const urlReferenceId = this.getReferenceIdFromUrl(currentUrl);
|
|
1041
|
-
if (urlReferenceId && this.isSpecBasedReference(urlReferenceId)) {
|
|
1042
|
-
if (
|
|
1043
|
-
!this.isProjectRootPath() &&
|
|
1044
|
-
!this.isParentReferencePath(currentUrl)
|
|
1045
|
-
) {
|
|
1046
|
-
previousRefInfo = this.getReferenceMetaInfo(currentUrl);
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
717
|
let referenceId: string;
|
|
1052
718
|
let topicId = "";
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
)
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
if (specBasedReference) {
|
|
1066
|
-
// Wait till the AMF is loaded.
|
|
1067
|
-
this.amfFetchPromiseMap[referenceId].then(() => {
|
|
1068
|
-
let selectedItemMetaData = this.getMetadataByIdentifier(
|
|
1069
|
-
referenceId,
|
|
1070
|
-
topicId
|
|
1071
|
-
);
|
|
1072
|
-
if (!selectedItemMetaData) {
|
|
1073
|
-
// Doesn't exist, let's use the summary.
|
|
1074
|
-
selectedItemMetaData = this.getMetadataByType(
|
|
1075
|
-
referenceId,
|
|
1076
|
-
"summary"
|
|
1077
|
-
);
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
if (selectedItemMetaData) {
|
|
1081
|
-
this.loadSpecReferenceContent(
|
|
1082
|
-
selectedItemMetaData.parentReferencePath,
|
|
1083
|
-
selectedItemMetaData.referenceId,
|
|
1084
|
-
selectedItemMetaData.amfId,
|
|
1085
|
-
selectedItemMetaData.type,
|
|
1086
|
-
"",
|
|
1087
|
-
selectedItemMetaData.meta
|
|
1088
|
-
);
|
|
1089
|
-
this.updateUrlWithSelected(
|
|
1090
|
-
selectedItemMetaData.parentReferencePath,
|
|
1091
|
-
selectedItemMetaData.meta
|
|
1092
|
-
);
|
|
1093
|
-
this.updateNavTitleMetaTag(selectedItemMetaData.navTitle);
|
|
1094
|
-
}
|
|
1095
|
-
});
|
|
1096
|
-
} else {
|
|
1097
|
-
let invalidTopicReferenceUrl = "";
|
|
1098
|
-
if (topicId) {
|
|
1099
|
-
const referenceDetails = this.getRefDetailsForGivenTopicMeta(
|
|
1100
|
-
referenceId,
|
|
1101
|
-
topicId
|
|
1102
|
-
);
|
|
1103
|
-
const selectedItemUrl = referenceDetails?.referenceUrl;
|
|
1104
|
-
if (!selectedItemUrl) {
|
|
1105
|
-
invalidTopicReferenceUrl = previousRefUrlInSession;
|
|
1106
|
-
}
|
|
719
|
+
const previousRefMetaInSession = window.sessionStorage.getItem(
|
|
720
|
+
this.docsReferenceMetaSessionKey
|
|
721
|
+
);
|
|
722
|
+
window.sessionStorage.removeItem(this.docsReferenceMetaSessionKey);
|
|
723
|
+
const currentMeta = this.getCurrentRefMeta(previousRefMetaInSession);
|
|
724
|
+
if (currentMeta) {
|
|
725
|
+
referenceId = currentMeta.referenceId;
|
|
726
|
+
topicId = currentMeta.topicId;
|
|
727
|
+
if (!this.amfFetchPromiseMap[referenceId]) {
|
|
728
|
+
// This could happen if they specify a bad query value.
|
|
729
|
+
// In this case, we'll do the logic below to use the default amf
|
|
730
|
+
referenceId = null;
|
|
1107
731
|
}
|
|
1108
|
-
this.loadMarkdownBasedReference(invalidTopicReferenceUrl);
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
|
|
1112
|
-
/**
|
|
1113
|
-
* Navigates to reference of the given URL
|
|
1114
|
-
* @param url
|
|
1115
|
-
*/
|
|
1116
|
-
private loadNewReferenceItem(url: string): void {
|
|
1117
|
-
const referenceId = this.getReferenceIdFromUrl(url);
|
|
1118
|
-
const referenceItem = this.getAmfConfigWithId(referenceId);
|
|
1119
|
-
if (referenceItem) {
|
|
1120
|
-
window.location.href = referenceItem.href;
|
|
1121
732
|
}
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
|
-
/**
|
|
1125
|
-
* @param referenceUrl to which user wants to navigate
|
|
1126
|
-
* Redirect to first sub item if it's root level item, otherwise content will be loaded
|
|
1127
|
-
* Push the history as a first child item
|
|
1128
|
-
* set selected sidebar value as a pathname
|
|
1129
|
-
*/
|
|
1130
733
|
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
* CASE1: This case is to consider when the user navigates to references by clicking a project card
|
|
1137
|
-
* Ex: /docs/example-project/references should navigate to the first topic in the first reference
|
|
1138
|
-
*/
|
|
1139
|
-
referenceId = this._currentReferenceId;
|
|
1140
|
-
} else if (this.isParentReferencePath(referenceUrl)) {
|
|
1141
|
-
/**
|
|
1142
|
-
* CASE2: This case is to navigate to respective reference when the user clicked on root item
|
|
1143
|
-
* Ex: .../references/markdown-ref should navigate to first topic.
|
|
1144
|
-
*/
|
|
1145
|
-
referenceId = this.getReferenceIdFromUrl(referenceUrl);
|
|
1146
|
-
} else if (this.isParentReferencePath(currentUrl)) {
|
|
1147
|
-
/**
|
|
1148
|
-
* CASE3: This case is to navigate to respective reference when the user entered url with reference id
|
|
1149
|
-
* Ex: .../references/markdown-ref should navigate to first topic.
|
|
1150
|
-
*/
|
|
1151
|
-
referenceId = this.getReferenceIdFromUrl(currentUrl);
|
|
1152
|
-
} else if (referenceUrl) {
|
|
1153
|
-
/**
|
|
1154
|
-
* CASE4: This case is to navigate to first item when we don't have topic in the selected version
|
|
1155
|
-
* Ex: .../references/markdown-ref/not-existed-topic-url should navigate to first topic.
|
|
1156
|
-
*/
|
|
1157
|
-
const referenceMeta = this.getMarkdownReferenceMeta(referenceUrl);
|
|
1158
|
-
const selectedItemRefId = this.getReferenceIdFromUrl(referenceUrl);
|
|
1159
|
-
const referenceDetails = this.getRefDetailsForGivenTopicMeta(
|
|
1160
|
-
selectedItemRefId,
|
|
1161
|
-
referenceMeta
|
|
1162
|
-
);
|
|
1163
|
-
const selectedItemUrl = referenceDetails?.referenceUrl;
|
|
1164
|
-
if (!selectedItemUrl) {
|
|
1165
|
-
referenceId = this.getReferenceIdFromUrl(referenceUrl);
|
|
734
|
+
if (!referenceId) {
|
|
735
|
+
referenceId = this._amfConfig[0].id;
|
|
736
|
+
if (!this.amfFetchPromiseMap[referenceId]) {
|
|
737
|
+
// This should never happen.
|
|
738
|
+
referenceId = Object.keys(this.amfFetchPromiseMap)[0];
|
|
1166
739
|
}
|
|
1167
740
|
}
|
|
1168
741
|
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
if (childrenItems.length > 0) {
|
|
1176
|
-
redirectReferenceUrl = childrenItems[0].link.href;
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
if (redirectReferenceUrl) {
|
|
1180
|
-
if (this.isParentReferencePath(referenceUrl)) {
|
|
1181
|
-
// This is for CASE2 mentioned above, Where we need to navigate user to respective href
|
|
1182
|
-
isRedirecting = true;
|
|
1183
|
-
window.location.href = redirectReferenceUrl;
|
|
1184
|
-
} else {
|
|
1185
|
-
// This is for CASE 1,3 and 4 mentioned above, Where we need to update the browser history
|
|
1186
|
-
window.history.replaceState({}, "", redirectReferenceUrl);
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
|
-
if (!isRedirecting) {
|
|
1191
|
-
const currentReferenceUrl = window.location.href;
|
|
1192
|
-
const referenceMeta =
|
|
1193
|
-
this.getMarkdownReferenceMeta(currentReferenceUrl);
|
|
1194
|
-
const selectedItemRefId =
|
|
1195
|
-
this.getReferenceIdFromUrl(currentReferenceUrl);
|
|
1196
|
-
const referenceDetails = this.getRefDetailsForGivenTopicMeta(
|
|
1197
|
-
selectedItemRefId,
|
|
1198
|
-
referenceMeta
|
|
1199
|
-
);
|
|
1200
|
-
if (referenceDetails) {
|
|
1201
|
-
this.updateNavTitleMetaTag(referenceDetails.topicTitle);
|
|
742
|
+
// Wait till the AMF is loaded.
|
|
743
|
+
this.amfFetchPromiseMap[referenceId].then(() => {
|
|
744
|
+
let topic = this.getMetadataByIdentifier(referenceId, topicId);
|
|
745
|
+
if (!topic) {
|
|
746
|
+
// Doesn't exist, let's use the summary.
|
|
747
|
+
topic = this.getMetadataByType(referenceId, "summary");
|
|
1202
748
|
}
|
|
1203
749
|
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
750
|
+
if (topic) {
|
|
751
|
+
this.loadContent(
|
|
752
|
+
topic.referenceId,
|
|
753
|
+
topic.amfId,
|
|
754
|
+
topic.type,
|
|
755
|
+
"",
|
|
756
|
+
topic.meta
|
|
757
|
+
);
|
|
758
|
+
}
|
|
759
|
+
});
|
|
1208
760
|
}
|
|
1209
761
|
|
|
1210
762
|
/**
|
|
1211
|
-
* Currently, used to handle the version change and
|
|
763
|
+
* Currently, used to handle the version change and storing the current meta query param to the session storage.
|
|
1212
764
|
*/
|
|
1213
765
|
handleVersionChange(): void {
|
|
1214
|
-
const
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
// this is required to update the nav title meta tag.
|
|
1223
|
-
// eslint-disable-next-line @lwc/lwc/no-document-query
|
|
1224
|
-
const metaNavTitle = document.querySelector('meta[name="nav-title"]');
|
|
1225
|
-
if (metaNavTitle && navTitle) {
|
|
1226
|
-
metaNavTitle.setAttribute("content", navTitle);
|
|
766
|
+
const path = window.location.search;
|
|
767
|
+
const urlParams = this.parseParams(path);
|
|
768
|
+
const meta = urlParams.meta as string;
|
|
769
|
+
if (meta) {
|
|
770
|
+
window.sessionStorage.setItem(
|
|
771
|
+
this.docsReferenceMetaSessionKey,
|
|
772
|
+
meta
|
|
773
|
+
);
|
|
1227
774
|
}
|
|
1228
775
|
}
|
|
1229
776
|
|
|
1230
777
|
onNavSelect(event: CustomEvent): void {
|
|
1231
778
|
const name = event.detail.name;
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
const currentSelectedMeta = this.selectedTopic
|
|
1239
|
-
? this.selectedTopic.meta
|
|
1240
|
-
: "";
|
|
1241
|
-
|
|
1242
|
-
if (metaVal && metaVal === currentSelectedMeta) {
|
|
1243
|
-
// selecting the same nav item, skip update
|
|
1244
|
-
return;
|
|
1245
|
-
}
|
|
779
|
+
const indexOfQueryParam = name.indexOf("?");
|
|
780
|
+
const urlPath = name.substring(
|
|
781
|
+
indexOfQueryParam >= 0 ? indexOfQueryParam : name.length
|
|
782
|
+
);
|
|
783
|
+
const metaVal = this.parseParams(urlPath).meta as string;
|
|
784
|
+
const currentSelectedMeta = this.selectedTopic.meta;
|
|
1246
785
|
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
parentReferencePath,
|
|
1251
|
-
referenceId,
|
|
1252
|
-
amfId,
|
|
1253
|
-
type,
|
|
1254
|
-
elementId
|
|
1255
|
-
} = metadata;
|
|
1256
|
-
this.loadSpecReferenceContent(
|
|
1257
|
-
parentReferencePath,
|
|
1258
|
-
referenceId,
|
|
1259
|
-
amfId,
|
|
1260
|
-
type,
|
|
1261
|
-
elementId,
|
|
1262
|
-
metaVal
|
|
1263
|
-
);
|
|
1264
|
-
this.updateUrlWithSelected(parentReferencePath, metaVal);
|
|
1265
|
-
this.updateNavTitleMetaTag(metadata.navTitle);
|
|
1266
|
-
} else {
|
|
1267
|
-
if (this.isParentReferencePath(name)) {
|
|
1268
|
-
this.loadNewReferenceItem(name);
|
|
1269
|
-
}
|
|
1270
|
-
}
|
|
1271
|
-
} else {
|
|
1272
|
-
this.loadMarkdownBasedReference(name);
|
|
1273
|
-
}
|
|
786
|
+
if (metaVal === currentSelectedMeta) {
|
|
787
|
+
// selecting the same nav item, skip update
|
|
788
|
+
return;
|
|
1274
789
|
}
|
|
1275
|
-
}
|
|
1276
790
|
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
const currentReferenceId = this.getReferenceIdFromUrl(currentUrl);
|
|
1283
|
-
//No need to do anything if user is expanding currently selected reference
|
|
1284
|
-
if (referenceId !== currentReferenceId) {
|
|
1285
|
-
const isSpecBasedReference =
|
|
1286
|
-
this.isSpecBasedReference(referenceId);
|
|
1287
|
-
if (isSpecBasedReference) {
|
|
1288
|
-
// Perform functionality same as item selection
|
|
1289
|
-
this.onNavSelect(event);
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
791
|
+
const metadata = this.metadata[metaVal];
|
|
792
|
+
if (metadata) {
|
|
793
|
+
const { referenceId, amfId, type, elementId } = metadata;
|
|
794
|
+
this.loadContent(referenceId, amfId, type, elementId, metaVal);
|
|
795
|
+
this.updateUrlWithSelected(metaVal);
|
|
1292
796
|
}
|
|
1293
797
|
}
|
|
1294
798
|
|