@salesforcedevs/docs-components 0.56.2-seo-test16 → 0.57.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.
@@ -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 { normalizeBoolean } from "dxUtils/normalizers";
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
- import {
23
- NAVIGATION_ITEMS,
24
- URL_CONFIG,
25
- REFERENCE_TYPES,
26
- oldReferenceIdNewReferenceIdMap
27
- } from "./constants";
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 | null | undefined = null;
31
- @api sidebarHeader!: string;
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!: 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
- * If current selected is markdown based reference,
98
- * We will assign versions once the selected item url is updated
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.updateAmfConfigInView();
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 _amfConfigList: AmfConfig[] = [];
138
- protected _amfConfigMap: Map<string, AmfConfig> = new Map();
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?: AmfMetaTopicType = undefined;
163
+ protected selectedTopic: AmfMetaTopicType = undefined;
164
+ protected navigation = [];
147
165
  protected selectedSidebarValue = undefined;
148
-
149
- protected selectedVersion: ReferenceVersion | null = null;
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 | null = null;
155
- private _expandChildren?: boolean = false;
175
+ private selectedReferenceDocPhase?: string = null;
156
176
 
157
177
  /**
158
- * Key for storing the currently selected reference url. This will be used to save the
159
- * previously selected reference url and restoring it when changing between reference versions.
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 docsReferenceUrlSessionKey: string = "docsReferenceUrl";
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.onApiNavigationChanged.bind(this);
170
- this._boundUpdateSelectedItemFromUrlQuery =
171
- this.updateSelectedItemFromUrlQuery.bind(this);
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._amfConfigList && this._amfConfigList.length) {
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._amfConfigList && this._amfConfigList.length) {
250
+ if (this._amfConfig && this._amfConfig.length) {
324
251
  // fetch AMF Json as soon as config is set
325
- this.populateReferenceItems();
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
- * Returns whether current location is project root path like ../example-project/references
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 isParentReferencePath(urlPath: string): boolean {
355
- if (!urlPath) {
356
- return false;
357
- }
358
- const parentReferenceIndex = this.parentReferenceUrls.findIndex(
359
- (referenceUrl: string) => {
360
- return urlPath.endsWith(referenceUrl);
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 are compatible with dx-sidebar.
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,38 +326,22 @@ export default class AmfReference extends LightningElement {
452
326
 
453
327
  items.forEach((item) => {
454
328
  item.methods?.forEach((method) => {
455
- const title =
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
- parentReferencePath,
468
- meta
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
- * Gives URL path for reference items, Which can be used to push to the history
480
- */
481
- private getReferencePathWithMeta(
482
- parentReferencePath: string,
483
- meta: string
484
- ): string {
485
- const encodedMeta = meta ? this.getUrlEncoded(meta) : "";
486
- return encodedMeta ? `${parentReferencePath}?meta=${encodedMeta}` : "";
343
+ private getReferencePathWithMeta(meta: string): string {
344
+ return meta ? `${window.location.pathname}?meta=${meta}` : "";
487
345
  }
488
346
 
489
347
  /**
@@ -493,15 +351,12 @@ export default class AmfReference extends LightningElement {
493
351
  * The 'endpoint' nav item may have nested children.
494
352
  */
495
353
  private assignNavigationItemsFromAmf(
496
- amfConfig: AmfConfig,
354
+ referenceId: string,
497
355
  amfIdx: number
498
356
  ): void {
499
- const referenceId = amfConfig.id;
500
- const parentReferencePath = amfConfig.href;
501
357
  const model = this.amfMap[referenceId].parser.parsedModel;
502
358
 
503
359
  const children = [];
504
- const expandChildren = this.isExpandChildrenEnabled(referenceId);
505
360
 
506
361
  NAVIGATION_ITEMS.forEach(
507
362
  ({ label, name, childrenPropertyName, type }) => {
@@ -510,18 +365,13 @@ export default class AmfReference extends LightningElement {
510
365
  case "summary": {
511
366
  const summary = model[type];
512
367
  const meta = this.addToMetadata(
513
- parentReferencePath,
514
368
  referenceId,
515
369
  type,
516
- summary,
517
- label
370
+ summary
518
371
  );
519
372
  children.push({
520
373
  label,
521
- name: this.getReferencePathWithMeta(
522
- parentReferencePath,
523
- meta
524
- )
374
+ name: this.getReferencePathWithMeta(meta)
525
375
  });
526
376
  break;
527
377
  }
@@ -535,17 +385,15 @@ export default class AmfReference extends LightningElement {
535
385
  indexedName
536
386
  );
537
387
  const childTopics = this.assignEndpointNavItems(
538
- parentReferencePath,
539
388
  referenceId,
540
389
  model[childrenPropertyName]
541
390
  );
542
391
  children.push({
543
392
  label,
544
393
  name: this.getReferencePathWithMeta(
545
- parentReferencePath,
546
394
  this.metadata[amfTopicId]?.meta
547
395
  ),
548
- isExpanded: expandChildren,
396
+ isExpanded: false,
549
397
  children: childTopics
550
398
  });
551
399
  }
@@ -577,23 +425,19 @@ export default class AmfReference extends LightningElement {
577
425
  children.push({
578
426
  label,
579
427
  name: this.getReferencePathWithMeta(
580
- parentReferencePath,
581
428
  this.metadata[amfTopicId]?.meta
582
429
  ),
583
- isExpanded: expandChildren,
430
+ isExpanded: false,
584
431
  children: model[childrenPropertyName].map(
585
432
  (topic) => {
586
433
  const meta = this.addToMetadata(
587
- parentReferencePath,
588
434
  referenceId,
589
435
  type,
590
- topic,
591
- topic.label
436
+ topic
592
437
  );
593
438
  return {
594
439
  label: topic.label,
595
440
  name: this.getReferencePathWithMeta(
596
- parentReferencePath,
597
441
  meta
598
442
  )
599
443
  };
@@ -605,41 +449,46 @@ export default class AmfReference extends LightningElement {
605
449
  }
606
450
  );
607
451
 
608
- this.navigation[amfIdx] = {
609
- ...this.navigation[amfIdx],
610
- children,
611
- isChildrenLoading: false
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
612
458
  };
613
- this.navigation = [...this.navigation];
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;
614
469
  }
615
470
 
616
471
  protected addToMetadata(
617
- parentReferencePath: string,
618
472
  referenceId: string,
619
473
  type: string,
620
- topic: { id: string; domId: string },
621
- navTitle: string
622
- ): string | undefined {
474
+ topic: { id: string; domId: string }
475
+ ): string {
623
476
  const { urlIdentifer, prefix } = URL_CONFIG[type];
624
477
 
625
478
  // encodeURI to avoid special characters in the URL meta.
626
479
  const identifier =
627
480
  topic[urlIdentifer] && this.encodeIdentifier(topic[urlIdentifer]);
628
- let meta;
629
- // Assuming that there will be an identifier always
630
- if (identifier) {
631
- meta = prefix ? `${prefix}${identifier}` : `${identifier}`;
632
- this.metadata[meta] = {
633
- parentReferencePath,
634
- meta,
635
- referenceId,
636
- amfId: topic.id,
637
- elementId: topic.domId,
638
- identifier,
639
- type,
640
- navTitle
641
- };
642
- }
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
+ };
643
492
  return meta;
644
493
  }
645
494
 
@@ -698,25 +547,54 @@ export default class AmfReference extends LightningElement {
698
547
  }
699
548
 
700
549
  /**
701
- * Parses URL query params without decoding of params
550
+ * Parses url query params without decoding of params
702
551
  */
703
- private parseParams(params: string): qs.ParsedQuery<string> {
704
- if (!params) {
552
+ private parseParams(path: string): qs.ParsedQuery<string> {
553
+ if (!path) {
705
554
  return {};
706
555
  }
707
- return qs.parse(params, {
556
+ return qs.parse(path, {
708
557
  decode: false
709
558
  });
710
559
  }
711
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
+
712
590
  /**
713
591
  * Normalizes topic identifier by replacing spaces with '+'
714
592
  * and running encodeURI() on it
715
- * @param identifier raw identifier for a topic as parsed from the spec file
593
+ * @param identifer raw identifer for a topic as parsed from the spec file
716
594
  * @returns normalized and encoded identifier
717
595
  */
718
- protected encodeIdentifier(identifier: string): string {
719
- let result = identifier.trim();
596
+ protected encodeIdentifier(identifer: string): string {
597
+ let result = identifer.trim();
720
598
  result = result.replace(new RegExp(/\s+/, "g"), "+");
721
599
  return encodeURI(result);
722
600
  }
@@ -728,132 +606,86 @@ export default class AmfReference extends LightningElement {
728
606
  return `${referenceId}:${id}`;
729
607
  }
730
608
 
731
- protected updateUrlWithSelected(
732
- parentReferencePath: string,
733
- meta?: string
734
- ): void {
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 {
735
644
  if (meta) {
736
- const encodedMeta = this.getUrlEncoded(meta);
737
645
  window.history.pushState(
738
646
  {},
739
647
  "",
740
- `${parentReferencePath}?meta=${encodedMeta}`
648
+ `${window.location.pathname}?meta=${meta}`
741
649
  );
742
650
  }
743
651
  }
744
652
 
745
653
  /**
746
- * Does a replace on the URL meta, so it does not create a history entry.
654
+ * Does a replace on the url meta, so it does not create a history entry.
747
655
  */
748
- protected replaceUrlWithSelected(
749
- parentReferencePath: string,
750
- meta?: string
751
- ): void {
656
+ protected replaceUrlWithSelected(meta?: string): void {
752
657
  if (meta) {
753
- const encodedMeta = this.getUrlEncoded(meta);
754
658
  window.history.replaceState(
755
659
  {},
756
660
  "",
757
- `${parentReferencePath}?meta=${encodedMeta}`
661
+ `${window.location.pathname}?meta=${meta}`
758
662
  );
759
663
  }
760
664
  }
761
665
 
762
- /**
763
- * This method gets called when the user navigates back and forth using browser arrows
764
- * Updates content depending on the type of reference - spec based or markdown
765
- */
766
- protected updateSelectedItemFromUrlQuery(): void {
767
- const specBasedReference = this.isSpecBasedReference(
768
- this._currentReferenceId
769
- );
770
- if (specBasedReference) {
771
- const currentMeta: RouteMeta | null = this.getReferenceMetaInfo(
772
- window.location.href
773
- );
774
- const metadata =
775
- currentMeta && this.getMetadataByUrlQuery(currentMeta);
776
- if (metadata) {
777
- const {
778
- parentReferencePath,
779
- referenceId,
780
- amfId,
781
- type,
782
- elementId
783
- }: AmfMetadataTopic = metadata;
784
- this.loadSpecReferenceContent(
785
- parentReferencePath,
786
- referenceId,
787
- amfId,
788
- type,
789
- elementId,
790
- currentMeta.meta
791
- );
792
- }
793
- } else {
794
- this.loadMarkdownBasedReference();
795
- }
796
- }
797
-
798
- /**
799
- * The API Navigation event will always intend to navigate within the current reference
800
- * @param event
801
- */
802
- protected onApiNavigationChanged(): void {
803
- const specBasedReference = this.isSpecBasedReference(
804
- this._currentReferenceId
805
- );
806
- if (specBasedReference) {
807
- const { meta } = this.selectedTopic;
808
- const metadata = this.metadata[meta];
809
- if (metadata) {
810
- const {
811
- parentReferencePath,
812
- referenceId,
813
- amfId,
814
- type,
815
- elementId
816
- }: AmfMetadataTopic = metadata;
817
- this.loadSpecReferenceContent(
818
- parentReferencePath,
819
- referenceId,
820
- amfId,
821
- type,
822
- elementId,
823
- metadata.meta
824
- );
825
- }
826
- } else {
827
- this.loadMarkdownBasedReference();
828
- }
829
- }
830
-
831
666
  /**
832
667
  * Updates the currently selected amf and topic
833
668
  */
834
- protected loadSpecReferenceContent(
835
- parentReferencePath: string,
669
+ protected loadContent(
836
670
  referenceId: string,
837
671
  amfId: string,
838
672
  type: string,
839
- elementId: string,
840
- meta: string
673
+ elementId = "",
674
+ meta = ""
841
675
  ): void {
842
676
  this.selectedTopic = {
843
677
  referenceId,
844
- parentReferencePath,
845
678
  amfId,
846
679
  elementId,
847
680
  type,
848
681
  meta
849
682
  };
850
- this.selectedSidebarValue = this.getReferencePathWithMeta(
851
- parentReferencePath,
852
- meta
853
- );
683
+ this.selectedSidebarValue = this.getReferencePathWithMeta(meta);
854
684
 
855
685
  this.handleSelectedItem();
856
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);
857
689
  this.updateDocPhase();
858
690
  }
859
691
 
@@ -864,9 +696,10 @@ export default class AmfReference extends LightningElement {
864
696
  /* If parent level doc phase is enabled, Individual reference level doc phase should not be considered */
865
697
 
866
698
  if (!this.isParentLevelDocPhaseEnabled) {
867
- const selectedReference = this._amfConfigList.find(
699
+ const referenceId = this.selectedTopic?.referenceId;
700
+ const selectedReference = this._amfConfig.find(
868
701
  (referenceItem: AmfConfig) => {
869
- return referenceItem.id === this._currentReferenceId;
702
+ return referenceItem.id === referenceId;
870
703
  }
871
704
  );
872
705
  if (selectedReference) {
@@ -878,411 +711,88 @@ export default class AmfReference extends LightningElement {
878
711
  }
879
712
 
880
713
  /**
881
- * @returns meta query param from given Url
882
- */
883
- getMetaFromUrl(referenceUrl: string): string {
884
- const indexOfQueryParam = referenceUrl.indexOf("?");
885
- const urlPath = referenceUrl.substring(
886
- indexOfQueryParam >= 0 ? indexOfQueryParam : referenceUrl.length
887
- );
888
- const meta = this.parseParams(urlPath).meta as string;
889
- // Always get the meta query param encoded and decode it and store it for internal use
890
- // This has 2 advantages,
891
- // 1. Supports backward compatible meta query param, so there is no need for redirects.
892
- // 2. Supports Prerender and Coveo for their crawling.
893
- const encodedMeta = meta && this.getUrlEncoded(meta);
894
- const decodedMeta = encodedMeta && decodeURIComponent(encodedMeta);
895
- return decodedMeta || "";
896
- }
897
-
898
- /**
899
- *
900
- * @returns meta for given markdown based referenceUrl
901
- * Consider last topic url in ../references/reference-name/example.html
902
- */
903
- getMarkdownReferenceMeta(referenceUrl: string): string {
904
- let meta = "";
905
- if (referenceUrl) {
906
- const slashSeparatorItems = referenceUrl.split("/");
907
- const lastItem =
908
- slashSeparatorItems[slashSeparatorItems.length - 1];
909
- if (lastItem.endsWith(".html")) {
910
- meta = lastItem;
911
- }
912
- }
913
- return meta;
914
- }
915
-
916
- /**
917
- * Gets the encoded url.
918
- */
919
- getUrlEncoded(url: string) {
920
- // if url matches, then return the encoded url.
921
- if (decodeURIComponent(url) === url) {
922
- return encodeURIComponent(url);
923
- }
924
- // return the encoded url.
925
- return this.getUrlEncoded(decodeURIComponent(url));
926
- }
927
-
928
- /**
929
- *
930
- * @returns RouteMeta object for given referenceUrl
931
- * referenceId - gets referenceId from url
932
- * For spec based references gets meta parm from url and then topicId & type from meta
933
- * For markdown based references gets topicId as last html path in the name, meta & type will be empty
934
- */
935
- getReferenceMetaInfo(referenceUrl: string): RouteMeta | undefined {
936
- let metaReferenceInfo;
937
- if (referenceUrl) {
938
- const referenceId = this.getReferenceIdFromUrl(referenceUrl);
939
- let meta = "";
940
- let topicId = "";
941
- let type = "";
942
- if (this.isSpecBasedReference(referenceId)) {
943
- meta = this.getMetaFromUrl(referenceUrl);
944
- if (meta) {
945
- if (meta.includes(":")) {
946
- const metaInfo = meta.split(":");
947
- type = metaInfo[0];
948
- topicId = metaInfo[1] || type;
949
- } else {
950
- topicId = meta;
951
- }
952
- }
953
- } else {
954
- topicId = this.getMarkdownReferenceMeta(referenceUrl);
955
- }
956
- metaReferenceInfo = {
957
- referenceId,
958
- meta,
959
- topicId,
960
- type
961
- };
962
- }
963
- return metaReferenceInfo;
964
- }
965
-
966
- /**
967
- * Finds and returns referenceUrl and topicTitle if given topic url matches
968
- */
969
- getReferenceDetailsInGivenTopics(
970
- topics: ParsedMarkdownTopic[],
971
- topicMeta: string
972
- ): { referenceUrl: string; topicTitle: string } {
973
- let referenceUrl = "";
974
- let topicTitle = "";
975
- for (let i = 0; i < topics.length; i++) {
976
- const topic = topics[i];
977
- const meta = this.getMarkdownReferenceMeta(topic.link.href);
978
- const childTopics = topic.children;
979
- if (meta === topicMeta) {
980
- referenceUrl = topic.link.href;
981
- topicTitle = topic.label;
982
- } else if (childTopics && childTopics.length) {
983
- const referenceDetails = this.getReferenceDetailsInGivenTopics(
984
- childTopics,
985
- topicMeta
986
- );
987
- referenceUrl = referenceDetails.referenceUrl;
988
- topicTitle = referenceDetails.topicTitle;
989
- }
990
- if (referenceUrl && topicTitle) {
991
- break;
992
- }
993
- }
994
- return {
995
- referenceUrl,
996
- topicTitle
997
- };
998
- }
999
-
1000
- /**
1001
- * Gives referenceUrl and topicTitle for given markdown topic url
1002
- */
1003
- getRefDetailsForGivenTopicMeta(
1004
- referenceId: string,
1005
- topicMeta: string
1006
- ): { referenceUrl: string; topicTitle: string } | undefined {
1007
- const amfConfig = this.getAmfConfigWithId(referenceId);
1008
- let referenceDetails;
1009
- if (amfConfig) {
1010
- const topics = amfConfig.topic?.children || [];
1011
- referenceDetails = this.getReferenceDetailsInGivenTopics(
1012
- topics,
1013
- topicMeta
1014
- );
1015
- }
1016
- return referenceDetails;
1017
- }
1018
-
1019
- /**
1020
- * Updates the DOM on the first load
714
+ * Updates the DOM on first load
1021
715
  */
1022
716
  updateView(): void {
1023
- const previousRefUrlInSession = window.sessionStorage.getItem(
1024
- this.docsReferenceUrlSessionKey
1025
- );
1026
- window.sessionStorage.removeItem(this.docsReferenceUrlSessionKey);
1027
- let previousRefInfo = this.getReferenceMetaInfo(
1028
- previousRefUrlInSession
1029
- );
1030
-
1031
- // For spec based reference, We should consider urlData to show same topic when user reloads after navigating to specific topic
1032
- if (!previousRefInfo) {
1033
- const currentUrl = window.location.href;
1034
- const urlReferenceId = this.getReferenceIdFromUrl(currentUrl);
1035
- if (urlReferenceId && this.isSpecBasedReference(urlReferenceId)) {
1036
- if (
1037
- !this.isProjectRootPath() &&
1038
- !this.isParentReferencePath(currentUrl)
1039
- ) {
1040
- previousRefInfo = this.getReferenceMetaInfo(currentUrl);
1041
- }
1042
- }
1043
- }
1044
-
1045
717
  let referenceId: string;
1046
718
  let topicId = "";
1047
-
1048
- if (
1049
- previousRefInfo &&
1050
- this._amfConfigMap.has(previousRefInfo.referenceId)
1051
- ) {
1052
- referenceId = previousRefInfo.referenceId;
1053
- topicId = previousRefInfo.topicId;
1054
- } else {
1055
- referenceId = this._currentReferenceId;
1056
- }
1057
-
1058
- const specBasedReference = this.isSpecBasedReference(referenceId);
1059
- if (specBasedReference) {
1060
- // Wait till the AMF is loaded.
1061
- this.amfFetchPromiseMap[referenceId].then(() => {
1062
- let selectedItemMetaData = this.getMetadataByIdentifier(
1063
- referenceId,
1064
- topicId
1065
- );
1066
- if (!selectedItemMetaData) {
1067
- // Doesn't exist, let's use the summary.
1068
- selectedItemMetaData = this.getMetadataByType(
1069
- referenceId,
1070
- "summary"
1071
- );
1072
- }
1073
-
1074
- if (selectedItemMetaData) {
1075
- this.loadSpecReferenceContent(
1076
- selectedItemMetaData.parentReferencePath,
1077
- selectedItemMetaData.referenceId,
1078
- selectedItemMetaData.amfId,
1079
- selectedItemMetaData.type,
1080
- "",
1081
- selectedItemMetaData.meta
1082
- );
1083
- this.updateUrlWithSelected(
1084
- selectedItemMetaData.parentReferencePath,
1085
- selectedItemMetaData.meta
1086
- );
1087
- this.updateNavTitleMetaTag(selectedItemMetaData.navTitle);
1088
- }
1089
- });
1090
- } else {
1091
- let invalidTopicReferenceUrl = "";
1092
- if (topicId) {
1093
- const referenceDetails = this.getRefDetailsForGivenTopicMeta(
1094
- referenceId,
1095
- topicId
1096
- );
1097
- const selectedItemUrl = referenceDetails?.referenceUrl;
1098
- if (!selectedItemUrl) {
1099
- invalidTopicReferenceUrl = previousRefUrlInSession;
1100
- }
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;
1101
731
  }
1102
- this.loadMarkdownBasedReference(invalidTopicReferenceUrl);
1103
- }
1104
- }
1105
-
1106
- /**
1107
- * Navigates to reference of the given URL
1108
- * @param url
1109
- */
1110
- private loadNewReferenceItem(url: string): void {
1111
- const referenceId = this.getReferenceIdFromUrl(url);
1112
- const referenceItem = this.getAmfConfigWithId(referenceId);
1113
- if (referenceItem) {
1114
- window.location.href = referenceItem.href;
1115
732
  }
1116
- }
1117
-
1118
- /**
1119
- * @param referenceUrl to which user wants to navigate
1120
- * Redirect to first sub item if it's root level item, otherwise content will be loaded
1121
- * Push the history as a first child item
1122
- * set selected sidebar value as a pathname
1123
- */
1124
733
 
1125
- private loadMarkdownBasedReference(referenceUrl?: string): void {
1126
- let referenceId = "";
1127
- const currentUrl = window.location.href;
1128
- if (this.isProjectRootPath()) {
1129
- /**
1130
- * CASE1: This case is to consider when the user navigates to references by clicking a project card
1131
- * Ex: /docs/example-project/references should navigate to the first topic in the first reference
1132
- */
1133
- referenceId = this._currentReferenceId;
1134
- } else if (this.isParentReferencePath(referenceUrl)) {
1135
- /**
1136
- * CASE2: This case is to navigate to respective reference when the user clicked on root item
1137
- * Ex: .../references/markdown-ref should navigate to first topic.
1138
- */
1139
- referenceId = this.getReferenceIdFromUrl(referenceUrl);
1140
- } else if (this.isParentReferencePath(currentUrl)) {
1141
- /**
1142
- * CASE3: This case is to navigate to respective reference when the user entered url with reference id
1143
- * Ex: .../references/markdown-ref should navigate to first topic.
1144
- */
1145
- referenceId = this.getReferenceIdFromUrl(currentUrl);
1146
- } else if (referenceUrl) {
1147
- /**
1148
- * CASE4: This case is to navigate to first item when we don't have topic in the selected version
1149
- * Ex: .../references/markdown-ref/not-existed-topic-url should navigate to first topic.
1150
- */
1151
- const referenceMeta = this.getMarkdownReferenceMeta(referenceUrl);
1152
- const selectedItemRefId = this.getReferenceIdFromUrl(referenceUrl);
1153
- const referenceDetails = this.getRefDetailsForGivenTopicMeta(
1154
- selectedItemRefId,
1155
- referenceMeta
1156
- );
1157
- const selectedItemUrl = referenceDetails?.referenceUrl;
1158
- if (!selectedItemUrl) {
1159
- 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];
1160
739
  }
1161
740
  }
1162
741
 
1163
- let isRedirecting = false;
1164
- if (referenceId) {
1165
- const amfConfig = this.getAmfConfigWithId(referenceId);
1166
- let redirectReferenceUrl = "";
1167
- if (amfConfig) {
1168
- const childrenItems = amfConfig.topic.children;
1169
- if (childrenItems.length > 0) {
1170
- redirectReferenceUrl = childrenItems[0].link.href;
1171
- }
1172
- }
1173
- if (redirectReferenceUrl) {
1174
- if (this.isParentReferencePath(referenceUrl)) {
1175
- // This is for CASE2 mentioned above, Where we need to navigate user to respective href
1176
- isRedirecting = true;
1177
- window.location.href = redirectReferenceUrl;
1178
- } else {
1179
- // This is for CASE 1,3 and 4 mentioned above, Where we need to update the browser history
1180
- window.history.replaceState({}, "", redirectReferenceUrl);
1181
- }
1182
- }
1183
- }
1184
- if (!isRedirecting) {
1185
- const currentReferenceUrl = window.location.href;
1186
- const referenceMeta =
1187
- this.getMarkdownReferenceMeta(currentReferenceUrl);
1188
- const selectedItemRefId =
1189
- this.getReferenceIdFromUrl(currentReferenceUrl);
1190
- const referenceDetails = this.getRefDetailsForGivenTopicMeta(
1191
- selectedItemRefId,
1192
- referenceMeta
1193
- );
1194
- if (referenceDetails) {
1195
- 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");
1196
748
  }
1197
749
 
1198
- this.versions = this.getVersions();
1199
- this.updateDocPhase();
1200
- this.selectedSidebarValue = window.location.pathname;
1201
- }
750
+ if (topic) {
751
+ this.loadContent(
752
+ topic.referenceId,
753
+ topic.amfId,
754
+ topic.type,
755
+ "",
756
+ topic.meta
757
+ );
758
+ }
759
+ });
1202
760
  }
1203
761
 
1204
762
  /**
1205
- * Currently, used to handle the version change and store the current reference Url.
763
+ * Currently, used to handle the version change and storing the current meta query param to the session storage.
1206
764
  */
1207
765
  handleVersionChange(): void {
1208
- const currentUrl = window.location.href;
1209
- window.sessionStorage.setItem(
1210
- this.docsReferenceUrlSessionKey,
1211
- currentUrl
1212
- );
1213
- }
1214
-
1215
- private updateNavTitleMetaTag(navTitle = ""): void {
1216
- // this is required to update the nav title meta tag.
1217
- // eslint-disable-next-line @lwc/lwc/no-document-query
1218
- const metaNavTitle = document.querySelector('meta[name="nav-title"]');
1219
- if (metaNavTitle && navTitle) {
1220
- 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
+ );
1221
774
  }
1222
775
  }
1223
776
 
1224
777
  onNavSelect(event: CustomEvent): void {
1225
778
  const name = event.detail.name;
1226
- if (name) {
1227
- const urlReferenceId = this.getReferenceIdFromUrl(name);
1228
- const specBasedReference =
1229
- this.isSpecBasedReference(urlReferenceId);
1230
- if (specBasedReference) {
1231
- const metaVal = this.getMetaFromUrl(name);
1232
- const currentSelectedMeta = this.selectedTopic
1233
- ? this.selectedTopic.meta
1234
- : "";
1235
-
1236
- if (metaVal && metaVal === currentSelectedMeta) {
1237
- // selecting the same nav item, skip update
1238
- return;
1239
- }
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;
1240
785
 
1241
- const metadata = this.metadata[metaVal];
1242
- if (metadata) {
1243
- const {
1244
- parentReferencePath,
1245
- referenceId,
1246
- amfId,
1247
- type,
1248
- elementId
1249
- } = metadata;
1250
- this.loadSpecReferenceContent(
1251
- parentReferencePath,
1252
- referenceId,
1253
- amfId,
1254
- type,
1255
- elementId,
1256
- metaVal
1257
- );
1258
- this.updateUrlWithSelected(parentReferencePath, metaVal);
1259
- this.updateNavTitleMetaTag(metadata.navTitle);
1260
- } else {
1261
- if (this.isParentReferencePath(name)) {
1262
- this.loadNewReferenceItem(name);
1263
- }
1264
- }
1265
- } else {
1266
- this.loadMarkdownBasedReference(name);
1267
- }
786
+ if (metaVal === currentSelectedMeta) {
787
+ // selecting the same nav item, skip update
788
+ return;
1268
789
  }
1269
- }
1270
790
 
1271
- onExpandCollapse(event: CustomEvent): void {
1272
- const { name, isSelectAction, isExpanded } = event.detail;
1273
- if (!isSelectAction && isExpanded) {
1274
- const referenceId = this.getReferenceIdFromUrl(name);
1275
- const currentUrl = window.location.href;
1276
- const currentReferenceId = this.getReferenceIdFromUrl(currentUrl);
1277
- //No need to do anything if user is expanding currently selected reference
1278
- if (referenceId !== currentReferenceId) {
1279
- const isSpecBasedReference =
1280
- this.isSpecBasedReference(referenceId);
1281
- if (isSpecBasedReference) {
1282
- // Perform functionality same as item selection
1283
- this.onNavSelect(event);
1284
- }
1285
- }
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);
1286
796
  }
1287
797
  }
1288
798