@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.
@@ -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,39 +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
- // 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
- amfConfig: AmfConfig,
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: expandChildren,
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: expandChildren,
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
- this.navigation[amfIdx] = {
610
- ...this.navigation[amfIdx],
611
- children,
612
- 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
613
458
  };
614
- 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;
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
- navTitle: string
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
- let meta;
630
- // Assuming that there will be an identifier always
631
- if (identifier) {
632
- meta = prefix ? `${prefix}${identifier}` : `${identifier}`;
633
- this.metadata[meta] = {
634
- parentReferencePath,
635
- meta,
636
- referenceId,
637
- amfId: topic.id,
638
- elementId: topic.domId,
639
- identifier,
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 URL query params without decoding of params
550
+ * Parses url query params without decoding of params
703
551
  */
704
- private parseParams(params: string): qs.ParsedQuery<string> {
705
- if (!params) {
552
+ private parseParams(path: string): qs.ParsedQuery<string> {
553
+ if (!path) {
706
554
  return {};
707
555
  }
708
- return qs.parse(params, {
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 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
717
594
  * @returns normalized and encoded identifier
718
595
  */
719
- protected encodeIdentifier(identifier: string): string {
720
- let result = identifier.trim();
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 updateUrlWithSelected(
733
- parentReferencePath: string,
734
- meta?: string
735
- ): 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 {
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
- `${parentReferencePath}?meta=${encodedMeta}`
648
+ `${window.location.pathname}?meta=${meta}`
743
649
  );
744
650
  }
745
651
  }
746
652
 
747
653
  /**
748
- * 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.
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
- `${parentReferencePath}?meta=${encodedMeta}`
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 loadSpecReferenceContent(
838
- parentReferencePath: string,
669
+ protected loadContent(
839
670
  referenceId: string,
840
671
  amfId: string,
841
672
  type: string,
842
- elementId: string,
843
- meta: string
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 selectedReference = this._amfConfigList.find(
699
+ const referenceId = this.selectedTopic?.referenceId;
700
+ const selectedReference = this._amfConfig.find(
871
701
  (referenceItem: AmfConfig) => {
872
- return referenceItem.id === this._currentReferenceId;
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
- * Returns the decoded meta query param from given Url as it is being used internally.
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
- if (
1055
- previousRefInfo &&
1056
- this._amfConfigMap.has(previousRefInfo.referenceId)
1057
- ) {
1058
- referenceId = previousRefInfo.referenceId;
1059
- topicId = previousRefInfo.topicId;
1060
- } else {
1061
- referenceId = this._currentReferenceId;
1062
- }
1063
-
1064
- const specBasedReference = this.isSpecBasedReference(referenceId);
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
- private loadMarkdownBasedReference(referenceUrl?: string): void {
1132
- let referenceId = "";
1133
- const currentUrl = window.location.href;
1134
- if (this.isProjectRootPath()) {
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
- let isRedirecting = false;
1170
- if (referenceId) {
1171
- const amfConfig = this.getAmfConfigWithId(referenceId);
1172
- let redirectReferenceUrl = "";
1173
- if (amfConfig) {
1174
- const childrenItems = amfConfig.topic.children;
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
- this.versions = this.getVersions();
1205
- this.updateDocPhase();
1206
- this.selectedSidebarValue = window.location.pathname;
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 store the current reference Url.
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 currentUrl = window.location.href;
1215
- window.sessionStorage.setItem(
1216
- this.docsReferenceUrlSessionKey,
1217
- currentUrl
1218
- );
1219
- }
1220
-
1221
- private updateNavTitleMetaTag(navTitle = ""): void {
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
- if (name) {
1233
- const urlReferenceId = this.getReferenceIdFromUrl(name);
1234
- const specBasedReference =
1235
- this.isSpecBasedReference(urlReferenceId);
1236
- if (specBasedReference) {
1237
- const metaVal = this.getMetaFromUrl(name);
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
- const metadata = this.metadata[metaVal];
1248
- if (metadata) {
1249
- const {
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
- onExpandCollapse(event: CustomEvent): void {
1278
- const { name, isSelectAction, isExpanded } = event.detail;
1279
- if (!isSelectAction && isExpanded) {
1280
- const referenceId = this.getReferenceIdFromUrl(name);
1281
- const currentUrl = window.location.href;
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