@salesforcedevs/docs-components 0.56.2-seo-test16 → 0.56.2-snyk

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.
Files changed (76) hide show
  1. package/lwc.config.json +10 -2
  2. package/package.json +13 -12
  3. package/src/modules/doc/{amfReference/utils.ts → amfModelParser/amfModelParser.ts} +10 -5
  4. package/src/modules/doc/amfReference/amfReference.css +23 -3
  5. package/src/modules/doc/amfReference/amfReference.html +34 -21
  6. package/src/modules/doc/amfReference/amfReference.ts +264 -73
  7. package/src/modules/doc/amfReference/types.ts +4 -12
  8. package/src/modules/doc/amfTopic/amfTopic.css +20 -0
  9. package/src/modules/doc/amfTopic/amfTopic.ts +35 -18
  10. package/src/modules/doc/amfTopic/types.ts +15 -13
  11. package/src/modules/doc/amfTopic/utils.ts +12 -6
  12. package/src/modules/doc/breadcrumbItem/breadcrumbItem.css +2 -1
  13. package/src/modules/doc/breadcrumbItem/breadcrumbItem.html +1 -1
  14. package/src/modules/doc/breadcrumbItem/breadcrumbItem.ts +22 -0
  15. package/src/modules/doc/breadcrumbs/breadcrumbs.css +9 -1
  16. package/src/modules/doc/breadcrumbs/breadcrumbs.html +44 -34
  17. package/src/modules/doc/breadcrumbs/breadcrumbs.ts +62 -23
  18. package/src/modules/doc/componentPlayground/componentPlayground.css +22 -0
  19. package/src/modules/doc/componentPlayground/componentPlayground.html +15 -0
  20. package/src/modules/doc/componentPlayground/componentPlayground.ts +20 -0
  21. package/src/modules/doc/content/content.css +70 -76
  22. package/src/modules/doc/content/content.ts +20 -16
  23. package/src/modules/doc/contentCallout/contentCallout.css +15 -7
  24. package/src/modules/doc/contentCallout/contentCallout.html +13 -4
  25. package/src/modules/doc/contentCallout/contentCallout.ts +14 -2
  26. package/src/modules/doc/contentLayout/contentLayout.css +1 -100
  27. package/src/modules/doc/contentLayout/contentLayout.html +26 -17
  28. package/src/modules/doc/contentLayout/contentLayout.ts +312 -70
  29. package/src/modules/doc/doDont/doDont.css +47 -0
  30. package/src/modules/doc/doDont/doDont.html +27 -0
  31. package/src/modules/doc/doDont/doDont.ts +17 -0
  32. package/src/modules/doc/header/header.css +65 -36
  33. package/src/modules/doc/header/header.html +40 -139
  34. package/src/modules/doc/header/header.ts +32 -77
  35. package/src/modules/doc/heading/heading.css +16 -37
  36. package/src/modules/doc/heading/heading.html +4 -4
  37. package/src/modules/doc/heading/heading.ts +12 -10
  38. package/src/modules/doc/headingAnchor/headingAnchor.css +2 -2
  39. package/src/modules/doc/headingAnchor/headingAnchor.ts +2 -2
  40. package/src/modules/doc/headingContent/headingContent.css +6 -8
  41. package/src/modules/doc/headingContent/headingContent.html +9 -15
  42. package/src/modules/doc/headingContent/headingContent.ts +2 -14
  43. package/src/modules/doc/lwcContentLayout/lwcContentLayout.css +1 -0
  44. package/src/modules/doc/lwcContentLayout/lwcContentLayout.html +64 -0
  45. package/src/modules/doc/lwcContentLayout/lwcContentLayout.ts +168 -0
  46. package/src/modules/doc/overview/overview.css +40 -0
  47. package/src/modules/doc/overview/overview.html +34 -0
  48. package/src/modules/doc/overview/overview.ts +12 -0
  49. package/src/modules/doc/phase/phase.css +18 -3
  50. package/src/modules/doc/phase/phase.html +15 -3
  51. package/src/modules/doc/phase/phase.ts +44 -8
  52. package/src/modules/doc/specificationContent/specificationContent.css +31 -0
  53. package/src/modules/doc/specificationContent/specificationContent.html +164 -0
  54. package/src/modules/doc/specificationContent/specificationContent.ts +121 -0
  55. package/src/modules/doc/sprigSurvey/sprigSurvey.html +20 -0
  56. package/src/modules/doc/sprigSurvey/sprigSurvey.scoped.css +16 -0
  57. package/src/modules/doc/sprigSurvey/sprigSurvey.ts +16 -0
  58. package/src/modules/doc/toc/toc.ts +1 -1
  59. package/src/modules/doc/versionPicker/versionPicker.css +64 -0
  60. package/src/modules/doc/versionPicker/versionPicker.html +38 -0
  61. package/src/modules/doc/versionPicker/versionPicker.ts +65 -0
  62. package/src/modules/doc/xmlContent/types.ts +12 -3
  63. package/src/modules/doc/xmlContent/utils.ts +17 -12
  64. package/src/modules/doc/xmlContent/xmlContent.css +32 -3
  65. package/src/modules/doc/xmlContent/xmlContent.html +33 -15
  66. package/src/modules/doc/xmlContent/xmlContent.ts +278 -88
  67. package/src/modules/docHelpers/amfStyle/amfStyle.css +10 -45
  68. package/src/modules/docHelpers/contentLayoutStyle/contentLayoutStyle.css +131 -0
  69. package/src/modules/docHelpers/imgStyle/imgStyle.css +59 -0
  70. package/src/modules/docHelpers/status/status.css +1 -1
  71. package/src/modules/docUtils/{SearchSyncer/SearchSyncer.ts → searchSyncer/searchSyncer.ts} +1 -0
  72. package/src/modules/docUtils/utils/__mocks__/coveo.analytics.ts +16 -0
  73. package/src/modules/docUtils/utils/coveo.analytics.d.ts +10 -0
  74. package/src/modules/docUtils/utils/utils.ts +32 -0
  75. package/src/modules/docBaseElements/lightningElementWithState/lightningElementWithState.ts +0 -93
  76. package/src/modules/docHelpers/phaseContentLayout/phaseContentLayout.css +0 -39
@@ -2,8 +2,9 @@ import { LightningElement, api, track } from "lwc";
2
2
  import { noCase } from "no-case";
3
3
  import { sentenceCase } from "sentence-case";
4
4
  import qs from "query-string";
5
- import { AmfModelParser } from "./utils";
6
- import { normalizeBoolean } from "dxUtils/normalizers";
5
+ import { AmfModelParser } from "doc/amfModelParser";
6
+ import { normalizeBoolean, toJson } from "dxUtils/normalizers";
7
+ import type { OptionWithLink } from "typings/custom";
7
8
  import type {
8
9
  AmfConfig,
9
10
  AmfMetadataTopic,
@@ -25,19 +26,35 @@ import {
25
26
  REFERENCE_TYPES,
26
27
  oldReferenceIdNewReferenceIdMap
27
28
  } from "./constants";
29
+ import { restoreScroll } from "dx/scrollManager";
30
+ import { DocPhaseInfo } from "typings/custom";
31
+ import { logCoveoPageView, oldVersionDocInfo } from "docUtils/utils";
32
+
33
+ type NavigationItem = {
34
+ label: string;
35
+ name: string;
36
+ isExpanded: boolean;
37
+ children: ParsedMarkdownTopic[];
38
+ isChildrenLoading: boolean;
39
+ };
28
40
 
29
41
  export default class AmfReference extends LightningElement {
30
- @api breadcrumbs?: string | null | undefined = null;
42
+ @api breadcrumbs: string | null = null;
31
43
  @api sidebarHeader!: string;
32
44
  @api coveoOrganizationId!: string;
33
45
  @api coveoPublicAccessToken!: string;
34
- @api coveoAdvancedQueryConfig!: string;
46
+ @api coveoAnalyticsToken!: string;
35
47
  @api coveoSearchHub!: string;
36
- @api useOldSidebar?: boolean = false;
48
+ @api useOldSidebar: boolean = false;
37
49
  @api tocTitle?: string;
38
50
  @api tocOptions?: string;
39
- @track navigation = [];
51
+ @api languages!: OptionWithLink[];
52
+ @api language!: string;
53
+ @api hideFooter = false;
54
+ @track navigation = [] as NavigationItem[];
40
55
  @track versions: Array<ReferenceVersion> = [];
56
+ @track showVersionBanner = false;
57
+ @track _coveoAdvancedQueryConfig!: { [key: string]: any };
41
58
 
42
59
  // Update this to update what component gets rendered in the content block
43
60
  @track
@@ -101,6 +118,16 @@ export default class AmfReference extends LightningElement {
101
118
  this.versions = this.getVersions();
102
119
  }
103
120
  this.selectedVersion = selectedVersion;
121
+ if (this.isSpecBasedReference(this._currentReferenceId)) {
122
+ this.isVersionFetched = true;
123
+ if (this.oldVersionInfo) {
124
+ this.showVersionBanner = true;
125
+ } else {
126
+ this.latestVersion = true;
127
+ }
128
+ }
129
+ } else {
130
+ this.isVersionFetched = true;
104
131
  }
105
132
 
106
133
  // This is to check if the url is hash based and redirect if needed
@@ -113,8 +140,8 @@ export default class AmfReference extends LightningElement {
113
140
  }
114
141
 
115
142
  @api
116
- get docPhaseInfo() {
117
- return this.selectedReferenceDocPhase;
143
+ get docPhaseInfo(): string | null {
144
+ return this.selectedReferenceDocPhase || null;
118
145
  }
119
146
 
120
147
  set docPhaseInfo(value: string) {
@@ -133,18 +160,47 @@ export default class AmfReference extends LightningElement {
133
160
  this._expandChildren = normalizeBoolean(value);
134
161
  }
135
162
 
163
+ /*
164
+ * The get coveoAdvancedQueryConfig() method returns this._coveoAdvancedQueryConfig,
165
+ * but before returning it, it checks if there are multiple versions (this.versions.length > 1)
166
+ * and if a version is selected (this.selectedVersion). If both conditions are met,
167
+ * it updates the version property of this._coveoAdvancedQueryConfig with the selected version.
168
+ */
169
+ @api
170
+ get coveoAdvancedQueryConfig(): { [key: string]: any } {
171
+ const coveoConfig = this._coveoAdvancedQueryConfig;
172
+ if (this.versions.length > 1 && this.selectedVersion) {
173
+ const currentGAVersionRef = this.versions[0];
174
+ if (this.selectedVersion.id !== currentGAVersionRef.id) {
175
+ // Currently Coveo only supports query without "v"
176
+ const version = this.selectedVersion.id.replace("v", "");
177
+ coveoConfig.version = version;
178
+ this._coveoAdvancedQueryConfig = coveoConfig;
179
+ }
180
+ }
181
+ return this._coveoAdvancedQueryConfig;
182
+ }
183
+
184
+ set coveoAdvancedQueryConfig(config) {
185
+ this._coveoAdvancedQueryConfig = toJson(config);
186
+ }
187
+
188
+ private get enableFooter(): boolean {
189
+ return !this.hideFooter;
190
+ }
191
+
136
192
  // model
137
193
  protected _amfConfigList: AmfConfig[] = [];
138
194
  protected _amfConfigMap: Map<string, AmfConfig> = new Map();
139
195
  protected _referenceSetConfig!: ReferenceSetConfig;
140
196
  protected _currentReferenceId = "";
141
197
 
142
- protected parentReferenceUrls = [];
198
+ protected parentReferenceUrls = [] as string[];
143
199
  protected amfMap: Record<string, AmfModelRecord> = {};
144
- protected amfFetchPromiseMap = {};
200
+ protected amfFetchPromiseMap = {} as any;
145
201
  protected metadata: { [key: string]: AmfMetadataTopic } = {};
146
202
  protected selectedTopic?: AmfMetaTopicType = undefined;
147
- protected selectedSidebarValue = undefined;
203
+ protected selectedSidebarValue: string | undefined = undefined;
148
204
 
149
205
  protected selectedVersion: ReferenceVersion | null = null;
150
206
 
@@ -153,6 +209,8 @@ export default class AmfReference extends LightningElement {
153
209
  private isParentLevelDocPhaseEnabled = false;
154
210
  private selectedReferenceDocPhase?: string | null = null;
155
211
  private _expandChildren?: boolean = false;
212
+ private isVersionFetched = false;
213
+ private latestVersion = false;
156
214
 
157
215
  /**
158
216
  * Key for storing the currently selected reference url. This will be used to save the
@@ -165,6 +223,7 @@ export default class AmfReference extends LightningElement {
165
223
 
166
224
  constructor() {
167
225
  super();
226
+
168
227
  this._boundOnApiNavigationChanged =
169
228
  this.onApiNavigationChanged.bind(this);
170
229
  this._boundUpdateSelectedItemFromUrlQuery =
@@ -280,6 +339,17 @@ export default class AmfReference extends LightningElement {
280
339
  return referenceId;
281
340
  }
282
341
 
342
+ private get oldVersionInfo(): DocPhaseInfo | null {
343
+ let info = null;
344
+ if (this.versions.length > 1 && this.selectedVersion) {
345
+ const currentGAVersionRef = this.versions[0];
346
+ if (this.selectedVersion.id !== currentGAVersionRef.id) {
347
+ info = oldVersionDocInfo(currentGAVersionRef.link.href);
348
+ }
349
+ }
350
+ return info;
351
+ }
352
+
283
353
  /**
284
354
  * @returns versions to be shown in the dropdown
285
355
  * For markdown based specs, Adds selected markdown topic url to same references
@@ -310,13 +380,13 @@ export default class AmfReference extends LightningElement {
310
380
  /**
311
381
  * Returns the selected version or the first available version.
312
382
  */
313
- private getSelectedVersion(): ReferenceVersion {
383
+ private getSelectedVersion(): ReferenceVersion | null {
314
384
  const versions = this._referenceSetConfig?.versions || [];
315
385
  const selectedVersion = versions.find(
316
386
  (v: ReferenceVersion) => v.selected
317
387
  );
318
388
  // return a selected version if there is one, else return the first one.
319
- return selectedVersion || (versions.length && versions[0]);
389
+ return selectedVersion || (versions.length && versions[0]) || null;
320
390
  }
321
391
 
322
392
  private updateAmfConfigInView(): void {
@@ -330,9 +400,11 @@ export default class AmfReference extends LightningElement {
330
400
  }
331
401
  }
332
402
 
333
- private async fetchAmf(amfConfig): Promise<AmfModel | AmfModel[]> {
403
+ private async fetchAmf(
404
+ amfConfig: AmfConfig
405
+ ): Promise<AmfModel | AmfModel[]> {
334
406
  const { amf } = amfConfig;
335
- const response = await fetch(amf, {
407
+ const response = await fetch(amf!, {
336
408
  headers: {
337
409
  "Cache-Control": `max-age=86400`
338
410
  }
@@ -351,7 +423,7 @@ export default class AmfReference extends LightningElement {
351
423
  /**
352
424
  * Returns whether given url is parent reference path like ../example-project/references/reference-id
353
425
  */
354
- private isParentReferencePath(urlPath: string): boolean {
426
+ private isParentReferencePath(urlPath?: string | null): boolean {
355
427
  if (!urlPath) {
356
428
  return false;
357
429
  }
@@ -363,13 +435,28 @@ export default class AmfReference extends LightningElement {
363
435
  return parentReferenceIndex !== -1;
364
436
  }
365
437
 
438
+ /**
439
+ * Expands the children of Markdown-based References.
440
+ */
441
+ private expandChildrenForMarkdownReferences(
442
+ children: ParsedMarkdownTopic[]
443
+ ): void {
444
+ if (!children) {
445
+ return;
446
+ }
447
+ for (const childNode of children) {
448
+ childNode.isExpanded = true;
449
+ this.expandChildrenForMarkdownReferences(childNode.children);
450
+ }
451
+ }
452
+
366
453
  /**
367
454
  * Populates reference Items from amfConfigList and assigns it to navigation for sidebar
368
455
  */
369
456
  private populateReferenceItems(): void {
370
- const navAmfOrder = [];
457
+ const navAmfOrder = [] as NavigationItem[];
371
458
  for (const [index, amfConfig] of this._amfConfigList.entries()) {
372
- let navItemChildren = [];
459
+ let navItemChildren = [] as ParsedMarkdownTopic[];
373
460
  let isChildrenLoading = false;
374
461
  if (amfConfig.referenceType !== REFERENCE_TYPES.markdown) {
375
462
  if (amfConfig.isSelected) {
@@ -383,7 +470,16 @@ export default class AmfReference extends LightningElement {
383
470
  }
384
471
  isChildrenLoading = true;
385
472
  } else {
386
- navItemChildren = amfConfig.topic.children;
473
+ const isExpandChildrenEnabled = this.isExpandChildrenEnabled(
474
+ amfConfig.id
475
+ );
476
+ // check whether we should expand all the child nodes, this is required for Coveo to crawl.
477
+ if (isExpandChildrenEnabled) {
478
+ this.expandChildrenForMarkdownReferences(
479
+ amfConfig.topic!.children
480
+ );
481
+ }
482
+ navItemChildren = amfConfig.topic!.children;
387
483
  }
388
484
  // store nav items for each spec in order
389
485
  navAmfOrder[index] = {
@@ -404,7 +500,9 @@ export default class AmfReference extends LightningElement {
404
500
  * Returns a boolean indicating whether the children should be expanded or not.
405
501
  */
406
502
  private isExpandChildrenEnabled(referenceId: string): boolean {
407
- return this.expandChildren && this._currentReferenceId === referenceId;
503
+ return (
504
+ !!this.expandChildren && this._currentReferenceId === referenceId
505
+ );
408
506
  }
409
507
 
410
508
  /**
@@ -448,12 +546,12 @@ export default class AmfReference extends LightningElement {
448
546
  referenceId: string,
449
547
  items: ParsedTopicModel[]
450
548
  ): NavItem[] {
451
- const methodList = [];
549
+ const methodList = [] as NavItem[];
452
550
 
453
551
  items.forEach((item) => {
454
552
  item.methods?.forEach((method) => {
455
553
  const title =
456
- this.getTitleForLabel(method.label) || method.method;
554
+ this.getTitleForLabel(method.label!) || method.method;
457
555
  const meta = this.addToMetadata(
458
556
  parentReferencePath,
459
557
  referenceId,
@@ -482,6 +580,7 @@ export default class AmfReference extends LightningElement {
482
580
  parentReferencePath: string,
483
581
  meta: string
484
582
  ): string {
583
+ // update the encoded url meta param
485
584
  const encodedMeta = meta ? this.getUrlEncoded(meta) : "";
486
585
  return encodedMeta ? `${parentReferencePath}?meta=${encodedMeta}` : "";
487
586
  }
@@ -500,7 +599,7 @@ export default class AmfReference extends LightningElement {
500
599
  const parentReferencePath = amfConfig.href;
501
600
  const model = this.amfMap[referenceId].parser.parsedModel;
502
601
 
503
- const children = [];
602
+ const children: any[] = [];
504
603
  const expandChildren = this.isExpandChildrenEnabled(referenceId);
505
604
 
506
605
  NAVIGATION_ITEMS.forEach(
@@ -527,8 +626,8 @@ export default class AmfReference extends LightningElement {
527
626
  }
528
627
  case "endpoint":
529
628
  if (
530
- model[childrenPropertyName] &&
531
- model[childrenPropertyName].length
629
+ model[childrenPropertyName!] &&
630
+ model[childrenPropertyName!].length
532
631
  ) {
533
632
  const amfTopicId = this.getFormattedIdentifier(
534
633
  referenceId,
@@ -537,7 +636,7 @@ export default class AmfReference extends LightningElement {
537
636
  const childTopics = this.assignEndpointNavItems(
538
637
  parentReferencePath,
539
638
  referenceId,
540
- model[childrenPropertyName]
639
+ model[childrenPropertyName!]
541
640
  );
542
641
  children.push({
543
642
  label,
@@ -552,23 +651,25 @@ export default class AmfReference extends LightningElement {
552
651
  break;
553
652
  case "security":
554
653
  case "type":
555
- if (model[childrenPropertyName]?.length) {
654
+ if (model[childrenPropertyName!]?.length) {
556
655
  // Sorting the types alphabetically
557
- model[childrenPropertyName].sort((typeA, typeB) => {
558
- const typeALbl = typeA.label.toLowerCase();
559
- const typeBLbl = typeB.label.toLowerCase();
560
- return typeALbl < typeBLbl
561
- ? -1
562
- : typeALbl > typeBLbl
563
- ? 1
564
- : 0;
565
- });
656
+ model[childrenPropertyName!].sort(
657
+ (typeA: any, typeB: any) => {
658
+ const typeALbl = typeA.label.toLowerCase();
659
+ const typeBLbl = typeB.label.toLowerCase();
660
+ return typeALbl < typeBLbl
661
+ ? -1
662
+ : typeALbl > typeBLbl
663
+ ? 1
664
+ : 0;
665
+ }
666
+ );
566
667
  }
567
668
  // eslint-disable-next-line no-fallthrough
568
669
  default:
569
670
  if (
570
- model[childrenPropertyName] &&
571
- model[childrenPropertyName].length
671
+ model[childrenPropertyName!] &&
672
+ model[childrenPropertyName!].length
572
673
  ) {
573
674
  const amfTopicId = this.getFormattedIdentifier(
574
675
  referenceId,
@@ -581,8 +682,8 @@ export default class AmfReference extends LightningElement {
581
682
  this.metadata[amfTopicId]?.meta
582
683
  ),
583
684
  isExpanded: expandChildren,
584
- children: model[childrenPropertyName].map(
585
- (topic) => {
685
+ children: model[childrenPropertyName!].map(
686
+ (topic: any) => {
586
687
  const meta = this.addToMetadata(
587
688
  parentReferencePath,
588
689
  referenceId,
@@ -619,12 +720,18 @@ export default class AmfReference extends LightningElement {
619
720
  type: string,
620
721
  topic: { id: string; domId: string },
621
722
  navTitle: string
622
- ): string | undefined {
623
- const { urlIdentifer, prefix } = URL_CONFIG[type];
723
+ ): string {
724
+ const config = URL_CONFIG[type as keyof typeof URL_CONFIG];
725
+ const urlIdentifer = config.urlIdentifer;
726
+ let prefix = null;
727
+ if ("prefix" in config) {
728
+ prefix = config.prefix;
729
+ }
624
730
 
625
731
  // encodeURI to avoid special characters in the URL meta.
626
732
  const identifier =
627
- topic[urlIdentifer] && this.encodeIdentifier(topic[urlIdentifer]);
733
+ urlIdentifer in topic &&
734
+ this.encodeIdentifier(topic[urlIdentifer as keyof typeof topic]);
628
735
  let meta;
629
736
  // Assuming that there will be an identifier always
630
737
  if (identifier) {
@@ -640,7 +747,7 @@ export default class AmfReference extends LightningElement {
640
747
  navTitle
641
748
  };
642
749
  }
643
- return meta;
750
+ return meta!;
644
751
  }
645
752
 
646
753
  /**
@@ -651,7 +758,7 @@ export default class AmfReference extends LightningElement {
651
758
  (metadata: AmfMetadataTopic) => {
652
759
  return routeMeta.meta === metadata.meta;
653
760
  }
654
- );
761
+ )!;
655
762
  }
656
763
 
657
764
  /**
@@ -665,7 +772,7 @@ export default class AmfReference extends LightningElement {
665
772
  return Object.values(this.metadata).find(
666
773
  (metadata: AmfMetadataTopic) =>
667
774
  referenceId === metadata.referenceId && amfId === metadata.amfId
668
- );
775
+ )!;
669
776
  }
670
777
 
671
778
  /**
@@ -680,7 +787,7 @@ export default class AmfReference extends LightningElement {
680
787
  (metadata: AmfMetadataTopic) =>
681
788
  referenceId === metadata.referenceId &&
682
789
  identifier === metadata.identifier
683
- );
790
+ )!;
684
791
  }
685
792
 
686
793
  /**
@@ -694,7 +801,7 @@ export default class AmfReference extends LightningElement {
694
801
  return Object.values(this.metadata).find(
695
802
  (metadata: AmfMetadataTopic) =>
696
803
  referenceId === metadata.referenceId && type === metadata.type
697
- );
804
+ )!;
698
805
  }
699
806
 
700
807
  /**
@@ -733,7 +840,9 @@ export default class AmfReference extends LightningElement {
733
840
  meta?: string
734
841
  ): void {
735
842
  if (meta) {
843
+ // update the encoded url meta param
736
844
  const encodedMeta = this.getUrlEncoded(meta);
845
+
737
846
  window.history.pushState(
738
847
  {},
739
848
  "",
@@ -750,9 +859,11 @@ export default class AmfReference extends LightningElement {
750
859
  meta?: string
751
860
  ): void {
752
861
  if (meta) {
862
+ // update the encoded url meta param
753
863
  const encodedMeta = this.getUrlEncoded(meta);
864
+
754
865
  window.history.replaceState(
755
- {},
866
+ window.history.state,
756
867
  "",
757
868
  `${parentReferencePath}?meta=${encodedMeta}`
758
869
  );
@@ -768,9 +879,8 @@ export default class AmfReference extends LightningElement {
768
879
  this._currentReferenceId
769
880
  );
770
881
  if (specBasedReference) {
771
- const currentMeta: RouteMeta | null = this.getReferenceMetaInfo(
772
- window.location.href
773
- );
882
+ const currentMeta: RouteMeta | undefined =
883
+ this.getReferenceMetaInfo(window.location.href);
774
884
  const metadata =
775
885
  currentMeta && this.getMetadataByUrlQuery(currentMeta);
776
886
  if (metadata) {
@@ -793,6 +903,8 @@ export default class AmfReference extends LightningElement {
793
903
  } else {
794
904
  this.loadMarkdownBasedReference();
795
905
  }
906
+
907
+ restoreScroll(); // don't try this at home kids
796
908
  }
797
909
 
798
910
  /**
@@ -804,7 +916,7 @@ export default class AmfReference extends LightningElement {
804
916
  this._currentReferenceId
805
917
  );
806
918
  if (specBasedReference) {
807
- const { meta } = this.selectedTopic;
919
+ const { meta } = this.selectedTopic!;
808
920
  const metadata = this.metadata[meta];
809
921
  if (metadata) {
810
922
  const {
@@ -878,7 +990,7 @@ export default class AmfReference extends LightningElement {
878
990
  }
879
991
 
880
992
  /**
881
- * @returns meta query param from given Url
993
+ * Returns the decoded meta query param from given Url as it is being used internally.
882
994
  */
883
995
  getMetaFromUrl(referenceUrl: string): string {
884
996
  const indexOfQueryParam = referenceUrl.indexOf("?");
@@ -915,8 +1027,11 @@ export default class AmfReference extends LightningElement {
915
1027
 
916
1028
  /**
917
1029
  * Gets the encoded url.
1030
+ * This method will return the encoded url for 2 cases,
1031
+ * 1. If the url is encoded already
1032
+ * 2. If the url is decoded
918
1033
  */
919
- getUrlEncoded(url: string) {
1034
+ getUrlEncoded(url: string): string {
920
1035
  // if url matches, then return the encoded url.
921
1036
  if (decodeURIComponent(url) === url) {
922
1037
  return encodeURIComponent(url);
@@ -932,7 +1047,7 @@ export default class AmfReference extends LightningElement {
932
1047
  * For spec based references gets meta parm from url and then topicId & type from meta
933
1048
  * For markdown based references gets topicId as last html path in the name, meta & type will be empty
934
1049
  */
935
- getReferenceMetaInfo(referenceUrl: string): RouteMeta | undefined {
1050
+ getReferenceMetaInfo(referenceUrl: string | null): RouteMeta | undefined {
936
1051
  let metaReferenceInfo;
937
1052
  if (referenceUrl) {
938
1053
  const referenceId = this.getReferenceIdFromUrl(referenceUrl);
@@ -974,10 +1089,10 @@ export default class AmfReference extends LightningElement {
974
1089
  let topicTitle = "";
975
1090
  for (let i = 0; i < topics.length; i++) {
976
1091
  const topic = topics[i];
977
- const meta = this.getMarkdownReferenceMeta(topic.link.href);
1092
+ const meta = this.getMarkdownReferenceMeta(topic.link!.href);
978
1093
  const childTopics = topic.children;
979
1094
  if (meta === topicMeta) {
980
- referenceUrl = topic.link.href;
1095
+ referenceUrl = topic.link!.href;
981
1096
  topicTitle = topic.label;
982
1097
  } else if (childTopics && childTopics.length) {
983
1098
  const referenceDetails = this.getReferenceDetailsInGivenTopics(
@@ -1080,15 +1195,16 @@ export default class AmfReference extends LightningElement {
1080
1195
  "",
1081
1196
  selectedItemMetaData.meta
1082
1197
  );
1198
+
1083
1199
  this.updateUrlWithSelected(
1084
1200
  selectedItemMetaData.parentReferencePath,
1085
1201
  selectedItemMetaData.meta
1086
1202
  );
1087
- this.updateNavTitleMetaTag(selectedItemMetaData.navTitle);
1203
+ this.updateTags(selectedItemMetaData.navTitle);
1088
1204
  }
1089
1205
  });
1090
1206
  } else {
1091
- let invalidTopicReferenceUrl = "";
1207
+ let invalidTopicReferenceUrl: string | null = "";
1092
1208
  if (topicId) {
1093
1209
  const referenceDetails = this.getRefDetailsForGivenTopicMeta(
1094
1210
  referenceId,
@@ -1122,7 +1238,10 @@ export default class AmfReference extends LightningElement {
1122
1238
  * set selected sidebar value as a pathname
1123
1239
  */
1124
1240
 
1125
- private loadMarkdownBasedReference(referenceUrl?: string): void {
1241
+ private loadMarkdownBasedReference(referenceUrl?: string | null): void {
1242
+ // MILES TODO: figure out if we ever need to log a coveo page view in here
1243
+ // this would be the case if at some point we 'load' a new 'markdown based reference'
1244
+ // without actually triggering a page load
1126
1245
  let referenceId = "";
1127
1246
  const currentUrl = window.location.href;
1128
1247
  if (this.isProjectRootPath()) {
@@ -1136,7 +1255,7 @@ export default class AmfReference extends LightningElement {
1136
1255
  * CASE2: This case is to navigate to respective reference when the user clicked on root item
1137
1256
  * Ex: .../references/markdown-ref should navigate to first topic.
1138
1257
  */
1139
- referenceId = this.getReferenceIdFromUrl(referenceUrl);
1258
+ referenceId = this.getReferenceIdFromUrl(referenceUrl!);
1140
1259
  } else if (this.isParentReferencePath(currentUrl)) {
1141
1260
  /**
1142
1261
  * CASE3: This case is to navigate to respective reference when the user entered url with reference id
@@ -1165,9 +1284,9 @@ export default class AmfReference extends LightningElement {
1165
1284
  const amfConfig = this.getAmfConfigWithId(referenceId);
1166
1285
  let redirectReferenceUrl = "";
1167
1286
  if (amfConfig) {
1168
- const childrenItems = amfConfig.topic.children;
1287
+ const childrenItems = amfConfig.topic!.children;
1169
1288
  if (childrenItems.length > 0) {
1170
- redirectReferenceUrl = childrenItems[0].link.href;
1289
+ redirectReferenceUrl = childrenItems[0].link!.href;
1171
1290
  }
1172
1291
  }
1173
1292
  if (redirectReferenceUrl) {
@@ -1177,7 +1296,11 @@ export default class AmfReference extends LightningElement {
1177
1296
  window.location.href = redirectReferenceUrl;
1178
1297
  } else {
1179
1298
  // This is for CASE 1,3 and 4 mentioned above, Where we need to update the browser history
1180
- window.history.replaceState({}, "", redirectReferenceUrl);
1299
+ window.history.replaceState(
1300
+ window.history.state,
1301
+ "",
1302
+ redirectReferenceUrl
1303
+ );
1181
1304
  }
1182
1305
  }
1183
1306
  }
@@ -1192,10 +1315,17 @@ export default class AmfReference extends LightningElement {
1192
1315
  referenceMeta
1193
1316
  );
1194
1317
  if (referenceDetails) {
1195
- this.updateNavTitleMetaTag(referenceDetails.topicTitle);
1318
+ this.updateTags(referenceDetails.topicTitle);
1196
1319
  }
1197
1320
 
1198
1321
  this.versions = this.getVersions();
1322
+ if (this.oldVersionInfo) {
1323
+ this.showVersionBanner = true;
1324
+ } else {
1325
+ this.latestVersion = true;
1326
+ }
1327
+
1328
+ this.isVersionFetched = true;
1199
1329
  this.updateDocPhase();
1200
1330
  this.selectedSidebarValue = window.location.pathname;
1201
1331
  }
@@ -1212,13 +1342,63 @@ export default class AmfReference extends LightningElement {
1212
1342
  );
1213
1343
  }
1214
1344
 
1215
- private updateNavTitleMetaTag(navTitle = ""): void {
1345
+ handleDismissVersionBanner() {
1346
+ this.showVersionBanner = false;
1347
+ }
1348
+
1349
+ private updateTags(navTitle = ""): void {
1350
+ if (!navTitle) {
1351
+ return;
1352
+ }
1353
+
1216
1354
  // this is required to update the nav title meta tag.
1217
1355
  // eslint-disable-next-line @lwc/lwc/no-document-query
1218
1356
  const metaNavTitle = document.querySelector('meta[name="nav-title"]');
1219
- if (metaNavTitle && navTitle) {
1357
+ // eslint-disable-next-line @lwc/lwc/no-document-query
1358
+ const titleTag = document.querySelector("title");
1359
+ const TITLE_SEPARATOR = " | ";
1360
+
1361
+ if (metaNavTitle) {
1220
1362
  metaNavTitle.setAttribute("content", navTitle);
1221
1363
  }
1364
+
1365
+ /**
1366
+ * Right now, the title tag only changes when you pick a Ref spec,
1367
+ * not every time you choose a subsection of the Ref spec.
1368
+ * This update aims to refresh the title tag with each selection.
1369
+ * If a Ref spec is chosen, we add the value of the <selected topic> to the title.
1370
+ * If a subsection is selected, we update the first part of the current
1371
+ * title with the new <selected topic>.
1372
+ * Example: Following is a sample project structure.
1373
+ * - Project Name
1374
+ * - Ref Spec1
1375
+ * - Summary
1376
+ * - Endpoints
1377
+ * - E1
1378
+ * - E2
1379
+ * - Ref Spec2
1380
+ * - Summary
1381
+ * - Endpoints
1382
+ * - E1 (Selected)
1383
+ * - E2
1384
+ * Previous Title: Ref Spec2 | Project Name | Salesforce Developer
1385
+ * New Title: E1 | Ref Spec2 | Project Name | Salesforce Developer
1386
+ *
1387
+ */
1388
+ if (titleTag) {
1389
+ let titleTagValue = titleTag.textContent;
1390
+ const titleTagSectionValues: string[] =
1391
+ titleTagValue?.split(TITLE_SEPARATOR);
1392
+ if (titleTagSectionValues) {
1393
+ if (titleTagSectionValues.length <= 3) {
1394
+ titleTagValue = navTitle + TITLE_SEPARATOR + titleTagValue;
1395
+ } else {
1396
+ titleTagSectionValues[0] = navTitle;
1397
+ titleTagValue = titleTagSectionValues.join(TITLE_SEPARATOR);
1398
+ }
1399
+ }
1400
+ titleTag.textContent = titleTagValue;
1401
+ }
1222
1402
  }
1223
1403
 
1224
1404
  onNavSelect(event: CustomEvent): void {
@@ -1255,8 +1435,13 @@ export default class AmfReference extends LightningElement {
1255
1435
  elementId,
1256
1436
  metaVal
1257
1437
  );
1438
+
1439
+ logCoveoPageView(
1440
+ this.coveoOrganizationId,
1441
+ this.coveoAnalyticsToken
1442
+ );
1258
1443
  this.updateUrlWithSelected(parentReferencePath, metaVal);
1259
- this.updateNavTitleMetaTag(metadata.navTitle);
1444
+ this.updateTags(metadata.navTitle);
1260
1445
  } else {
1261
1446
  if (this.isParentReferencePath(name)) {
1262
1447
  this.loadNewReferenceItem(name);
@@ -1288,16 +1473,22 @@ export default class AmfReference extends LightningElement {
1288
1473
 
1289
1474
  handleSelectedItem(): void {
1290
1475
  // update topic view
1291
- const { referenceId, amfId, type } = this.selectedTopic;
1476
+ const { referenceId, amfId, type } = this.selectedTopic!;
1477
+
1478
+ // Adding stringify inside try/catch
1479
+ let amfModelString = "";
1480
+ try {
1481
+ amfModelString = JSON.stringify(this.amfMap[referenceId].model);
1482
+ } catch (error) {
1483
+ console.error(`Error stringifying amf model: ${error}`);
1484
+ }
1292
1485
 
1293
1486
  // This updates the component in the content section.
1294
1487
  this.topicModel = {
1295
1488
  type,
1296
- amf: this.amfMap[referenceId].model,
1489
+ amf: amfModelString,
1297
1490
  parser: this.amfMap[referenceId].parser,
1298
1491
  id: amfId
1299
1492
  };
1300
-
1301
- window.scrollTo({ top: 0, behavior: "smooth" });
1302
1493
  }
1303
1494
  }