@salesforcedevs/dx-components 1.40.6-tlv-alpha-1 → 1.40.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,12 @@
1
+ Copyright (c) 2020, Salesforce.com, Inc.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
+
6
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7
+
8
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9
+
10
+ * Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/lwc.config.json CHANGED
@@ -140,7 +140,6 @@
140
140
  "dxUtils/lwc",
141
141
  "dxUtils/urlWatcher",
142
142
  "dxUtils/normalizers",
143
- "dxUtils/topicVersion",
144
143
  "dxUtils/queryCoordinator",
145
144
  "dxUtils/recentSearches",
146
145
  "dxUtils/regexps",
package/package.json CHANGED
@@ -1,48 +1,48 @@
1
1
  {
2
- "name": "@salesforcedevs/dx-components",
3
- "version": "1.40.6-tlv-alpha-1",
4
- "description": "DX Lightning web components",
5
- "license": "MIT",
6
- "engines": {
7
- "node": "22.x"
8
- },
9
- "publishConfig": {
10
- "access": "public"
11
- },
12
- "dependencies": {
13
- "@coveo/headless": "3.22.2",
14
- "@floating-ui/dom": "1.5.1",
15
- "@optimizely/optimizely-sdk": "5.3.0",
16
- "@shikijs/colorized-brackets": "^3.12.2",
17
- "@types/throttle-debounce": "5.0.2",
18
- "@vimeo/player": "2.22.0",
19
- "classnames": "2.5.1",
20
- "composed-offset-position": "0.0.4",
21
- "coveo-search-ui": "2.10113.0",
22
- "debounce": "1.2.1",
23
- "js-cookie": "3.0.5",
24
- "lodash.defaults": "4.2.0",
25
- "lodash.get": "4.4.2",
26
- "lodash.kebabcase": "4.1.1",
27
- "memoize-one": "6.0.0",
28
- "microtip": "0.2.2",
29
- "shiki": "^3.12.2",
30
- "throttle-debounce": "5.0.0",
31
- "uuid": "9.0.1"
32
- },
33
- "devDependencies": {
34
- "@types/classnames": "2.3.1",
35
- "@types/debounce": "1.2.4",
36
- "@types/js-cookie": "3.0.6",
37
- "@types/lodash.defaults": "4.2.9",
38
- "@types/lodash.get": "4.4.9",
39
- "@types/lodash.kebabcase": "4.1.9",
40
- "@types/luxon": "3.4.2",
41
- "@types/uuid": "8.3.4",
42
- "@types/vimeo__player": "2.18.3",
43
- "eventsourcemock": "2.0.0",
44
- "luxon": "3.4.4",
45
- "msw": "^2.12.4"
46
- },
47
- "stableVersion": "1.40.5"
48
- }
2
+ "name": "@salesforcedevs/dx-components",
3
+ "version": "1.40.6",
4
+ "description": "DX Lightning web components",
5
+ "license": "MIT",
6
+ "engines": {
7
+ "node": "22.x"
8
+ },
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "dependencies": {
13
+ "@coveo/headless": "3.22.2",
14
+ "@floating-ui/dom": "1.5.1",
15
+ "@optimizely/optimizely-sdk": "5.3.0",
16
+ "@shikijs/colorized-brackets": "^3.12.2",
17
+ "@types/throttle-debounce": "5.0.2",
18
+ "@vimeo/player": "2.22.0",
19
+ "classnames": "2.5.1",
20
+ "composed-offset-position": "0.0.4",
21
+ "coveo-search-ui": "2.10113.0",
22
+ "debounce": "1.2.1",
23
+ "js-cookie": "3.0.5",
24
+ "lodash.defaults": "4.2.0",
25
+ "lodash.get": "4.4.2",
26
+ "lodash.kebabcase": "4.1.1",
27
+ "memoize-one": "6.0.0",
28
+ "microtip": "0.2.2",
29
+ "shiki": "^3.12.2",
30
+ "throttle-debounce": "5.0.0",
31
+ "uuid": "9.0.1"
32
+ },
33
+ "devDependencies": {
34
+ "@types/classnames": "2.3.1",
35
+ "@types/debounce": "1.2.4",
36
+ "@types/js-cookie": "3.0.6",
37
+ "@types/lodash.defaults": "4.2.9",
38
+ "@types/lodash.get": "4.4.9",
39
+ "@types/lodash.kebabcase": "4.1.9",
40
+ "@types/luxon": "3.4.2",
41
+ "@types/uuid": "8.3.4",
42
+ "@types/vimeo__player": "2.18.3",
43
+ "eventsourcemock": "2.0.0",
44
+ "luxon": "3.4.4",
45
+ "msw": "^2.12.4"
46
+ },
47
+ "gitHead": "4fd9e541d6670ba80769d42f64e0bf70e342a743"
48
+ }
@@ -86,11 +86,11 @@
86
86
  }
87
87
 
88
88
  .button.icon-right:not(.slot-empty) > *:nth-child(2) {
89
- margin-left: var(--dx-c-button-icon-gap, var(--dx-g-spacing-sm));
89
+ margin-left: var(--dx-g-spacing-sm);
90
90
  }
91
91
 
92
92
  .button.icon-left:not(.slot-empty) > *:nth-child(2) {
93
- margin-right: var(--dx-c-button-icon-gap, var(--dx-g-spacing-sm));
93
+ margin-right: var(--dx-g-spacing-sm);
94
94
  }
95
95
 
96
96
  .button.style-icon.slot-empty {
@@ -15,9 +15,6 @@ import { normalizeBoolean } from "dxUtils/normalizers";
15
15
  - SQL Documentation -> SQL
16
16
  */
17
17
 
18
- // Used for remove enclosing <pre> tag's (if occurs)
19
- const preTagRegexp: RegExp = /^<pre.*?>(.*)<\/pre>$/is;
20
-
21
18
  export const LIGHT = "light";
22
19
  export const DARK = "dark";
23
20
  export const EVENT_NAME = "dx-codeblock-theme";
@@ -87,12 +84,7 @@ export default class CodeBlock extends LightningElement {
87
84
  set codeBlock(value: string) {
88
85
  this._codeBlockRendered = false;
89
86
  this._isCbHeightCalculated = false;
90
- let match;
91
- this._codeBlock = (
92
- (match = preTagRegexp.exec(value.trim())) === null
93
- ? value.trim()
94
- : match[1]
95
- ).trim();
87
+ this._codeBlock = value.trim();
96
88
  }
97
89
 
98
90
  @api
@@ -14,40 +14,12 @@
14
14
  display: none;
15
15
  }
16
16
 
17
- /* Opt-in fit-content menu: hugs the labels (so it can be as narrow as the
18
- shortest one) and stops at --dx-c-dropdown-menu-max-width. Defaults still
19
- truncate; set --dx-c-dropdown-fit-white-space: normal to wrap instead. */
20
- .menu-fit-content::part(content) {
21
- box-sizing: border-box;
22
- width: max-content;
23
- max-width: var(
24
- --dx-c-dropdown-menu-max-width,
25
- calc(100vw - var(--dx-g-spacing-lg))
26
- );
27
- }
28
-
29
17
  .menu-fit-content {
30
- --dx-c-dropdown-option-min-width: 0;
31
- --dx-c-dropdown-option-label-display: block;
32
- --dx-c-dropdown-option-white-space: var(
33
- --dx-c-dropdown-fit-white-space,
34
- nowrap
35
- );
36
- --dx-c-dropdown-option-overflow: var(--dx-c-dropdown-fit-overflow, hidden);
37
- --dx-c-dropdown-option-text-overflow: var(
38
- --dx-c-dropdown-fit-text-overflow,
39
- ellipsis
40
- );
41
- }
42
-
43
- /* Nested fit-content menus (content action toolbar). Flat fit-content menus,
44
- including the version picker, keep the option rules above. */
45
- .menu-fit-content.menu-nested {
46
18
  --dx-c-popover-width: max-content;
47
19
  --dx-c-popover-padding: var(--dx-g-spacing-sm) 0;
48
20
  }
49
21
 
50
- .menu-fit-content.menu-nested .menu_list {
22
+ .menu-fit-content .menu_list {
51
23
  width: 100%;
52
24
  align-items: flex-start;
53
25
  gap: var(--dx-g-spacing-sm);
@@ -9,7 +9,7 @@
9
9
  open-on-hover={openOnHover}
10
10
  open={open}
11
11
  page-padding={pagePadding}
12
- placement={effectivePlacement}
12
+ placement={placement}
13
13
  small={small}
14
14
  width={effectiveWidth}
15
15
  >
@@ -82,35 +82,20 @@ export default class Dropdown extends LightningElement {
82
82
  return this.areOptionsEmpty ? null : "menu";
83
83
  }
84
84
 
85
- // "fit-end" is fit-content, aligned to the trigger's end edge.
86
- // "full" matches the trigger width. "fixed" and "fit-content" are unchanged.
87
85
  private get isFitContent() {
88
- return this.widthMode === "fit-content" || this.widthMode === "fit-end";
86
+ return this.widthMode === "fit-content";
89
87
  }
90
88
 
91
- private get effectivePlacement(): PopperPlacement | undefined {
92
- return this.widthMode === "fit-end" ? "bottom-end" : this.placement;
93
- }
94
-
95
- // fit-content takes precedence; the misuse is surfaced in className() below.
96
89
  private get effectiveWidth() {
97
90
  return this.isFitContent ? null : this.width;
98
91
  }
99
92
 
100
93
  private get effectiveFullWidth() {
101
- if (this.widthMode === "full") {
102
- return true;
103
- }
104
94
  return this.isFitContent ? false : this.fullWidth;
105
95
  }
106
96
 
107
97
  private get className() {
108
98
  const fitContent = this.isFitContent;
109
- if (fitContent && (this.width || this.fullWidth)) {
110
- console.error(
111
- 'The "width-mode=fit-content" and "width"/"full-width" properties cannot be provided simultaneously. "width-mode=fit-content" is prioritized; "width"/"full-width" are ignored.'
112
- );
113
- }
114
99
  return cx(
115
100
  this.isNested && "menu-nested",
116
101
  this.isNested &&
@@ -25,14 +25,8 @@
25
25
  display: flex;
26
26
  font-family: var(--dx-g-font-sans);
27
27
  width: 100%;
28
-
29
- /* Opt-in hooks; defaults preserve today's look. */
30
- padding: var(--dx-c-dropdown-option-padding, var(--dx-g-spacing-sm));
31
- font-size: var(--dx-c-dropdown-option-font-size, var(--dx-g-text-sm));
32
- border-radius: var(
33
- --dx-c-dropdown-option-border-radius,
34
- var(--dx-g-spacing-xs)
35
- );
28
+ padding: var(--dx-g-spacing-sm);
29
+ font-size: var(--dx-g-text-sm);
36
30
  transition: var(--dx-g-transition-hue-1x);
37
31
  align-items: center;
38
32
  outline: none !important;
@@ -53,10 +47,7 @@
53
47
  }
54
48
 
55
49
  .option-active {
56
- --dx-c-dropdown-option-label-color: var(
57
- --dx-c-dropdown-option-active-label-color,
58
- var(--dx-g-blue-vibrant-50)
59
- );
50
+ --dx-c-dropdown-option-label-color: var(--dx-g-blue-vibrant-50);
60
51
 
61
52
  background: var(--dx-g-cloud-blue-vibrant-95);
62
53
  }
@@ -66,12 +57,8 @@
66
57
  flex-direction: column;
67
58
  justify-content: center;
68
59
  font-family: var(--dx-g-font-sans);
69
- font-size: var(--dx-c-dropdown-option-font-size, var(--dx-g-text-sm));
70
- color: var(--dx-c-dropdown-option-label-color, inherit);
60
+ font-size: var(--dx-g-text-sm);
71
61
  text-align: left;
72
-
73
- /* Opt-in: set to 0 to let a long label truncate instead of overflow. */
74
- min-width: var(--dx-c-dropdown-option-min-width, auto);
75
62
  }
76
63
 
77
64
  .option-indented .option_details {
@@ -81,20 +68,10 @@
81
68
 
82
69
  .option_label {
83
70
  color: var(--dx-c-dropdown-option-label-color, var(--dx-g-blue-vibrant-50));
84
-
85
- /* Opt-in: set to block so text-overflow:ellipsis applies (ignored on flex). */
86
- display: var(--dx-c-dropdown-option-label-display, flex);
71
+ display: flex;
87
72
  align-items: center;
88
73
  font-weight: var(--dx-c-dropdown-option-font-weight, var(--dx-g-font-bold));
89
74
  font-size: var(--dx-c-dropdown-option-font-size, var(--dx-g-text-base));
90
-
91
- /* Opt-in truncation: consumers set --dx-c-dropdown-option-white-space:
92
- nowrap to truncate labels with an ellipsis instead of wrapping.
93
- Defaults preserve today's wrapping behavior. */
94
- white-space: var(--dx-c-dropdown-option-white-space, normal);
95
- overflow: var(--dx-c-dropdown-option-overflow, visible);
96
- overflow-wrap: var(--dx-c-dropdown-option-overflow-wrap, normal);
97
- text-overflow: var(--dx-c-dropdown-option-text-overflow, clip);
98
75
  }
99
76
 
100
77
  .option-indented .option_label {
@@ -153,10 +130,7 @@
153
130
  }
154
131
 
155
132
  .option-fit-content.option-active .option_label {
156
- color: var(
157
- --dx-c-dropdown-option-active-label-color,
158
- var(--dx-g-blue-vibrant-50)
159
- );
133
+ color: var(--dx-g-blue-vibrant-50);
160
134
  }
161
135
 
162
136
  .option-fit-content .option_icon {
@@ -89,15 +89,7 @@ export default class Popover extends LightningElement {
89
89
 
90
90
  this.dispatchEvent(new CustomEvent("open"));
91
91
 
92
- this.clearOpenListenersTimer();
93
- // Defer so the opening click is not treated as an outside click.
94
- // Drop the callback if the popover closes before it runs, or the
95
- // document listeners attach with nothing left to remove them.
96
- this.openListenersTimer = setTimeout(() => {
97
- this.openListenersTimer = undefined;
98
- if (!this._open) {
99
- return;
100
- }
92
+ setTimeout(() => {
101
93
  this.setPosition();
102
94
  this.attachListenersTopopover();
103
95
  });
@@ -106,15 +98,7 @@ export default class Popover extends LightningElement {
106
98
 
107
99
  @api
108
100
  closePopover(focusControl: boolean = false) {
109
- this.clearOpenListenersTimer();
110
- if (!this._open) {
111
- return;
112
- }
113
101
  this._open = false;
114
- // Hide before aria-expanded changes. :has([aria-expanded]) / :focus-within
115
- // stacking rules would otherwise drop position:relative while this menu
116
- // is still visible, flashing it against a different offset parent.
117
- this.popover?.classList.remove("popover-container_open");
118
102
  this.autoUpdateCleanup?.();
119
103
  if (focusControl && this.control && this.control.focus) {
120
104
  this.control.focus();
@@ -122,28 +106,20 @@ export default class Popover extends LightningElement {
122
106
  if (this.control) {
123
107
  this.control.setAttribute("aria-expanded", "false");
124
108
  }
125
- document.removeEventListener(
126
- "click",
127
- this.interactOutsideListener,
128
- true
129
- );
109
+ document.removeEventListener("click", this.interactOutsideListener);
130
110
  document.removeEventListener("focusout", this.interactOutsideListener);
131
- document.removeEventListener("keydown", this.onDocumentKeydown, true);
132
111
  if (this.openOnHover) {
133
112
  document.removeEventListener(
134
113
  "mousemove",
135
114
  this.interactOutsideListener
136
115
  );
137
116
  }
138
- this.pointerOpened = false;
139
117
  this.dispatchEvent(new CustomEvent("close"));
140
118
  }
141
119
 
142
120
  // PRIVATE VARS
143
121
 
144
122
  private controlled: boolean = false;
145
- private pointerOpened: boolean = false;
146
- private openListenersTimer?: ReturnType<typeof setTimeout>;
147
123
  private _open: boolean = false;
148
124
  private _rendered: boolean = isPrerender();
149
125
  private _role: string | null = null;
@@ -156,15 +132,9 @@ export default class Popover extends LightningElement {
156
132
  // LIFECYCLE METHODS
157
133
 
158
134
  disconnectedCallback() {
159
- this.clearOpenListenersTimer();
160
- document.removeEventListener(
161
- "click",
162
- this.interactOutsideListener,
163
- true
164
- );
135
+ document.removeEventListener("click", this.interactOutsideListener);
165
136
  document.removeEventListener("mousemove", this.interactOutsideListener);
166
137
  document.removeEventListener("focusout", this.interactOutsideListener);
167
- document.removeEventListener("keydown", this.onDocumentKeydown, true);
168
138
  this.removeControlListeners();
169
139
  }
170
140
 
@@ -256,91 +226,17 @@ export default class Popover extends LightningElement {
256
226
  switch (e.key) {
257
227
  case "ArrowDown": {
258
228
  e.preventDefault();
259
- this.pointerOpened = false;
260
229
  if (!this.open) {
261
230
  this.openPopover();
262
231
  }
263
232
  this.dispatchEvent(new CustomEvent("controlarrowdown"));
264
233
  break;
265
234
  }
266
- case "Esc":
267
- case "Escape":
268
- this.closeOnEscape(e);
269
- break;
270
235
  default:
271
236
  }
272
237
  };
273
238
 
274
- // Capture on document: click-open leaves focus on the trigger, and slotted
275
- // menu options live outside this shadow tree, so the panel's onkeydown
276
- // never sees Escape. Only the innermost popover in the event path handles
277
- // it, so Escape in another control does not close this menu or cancel that
278
- // control's own Escape behavior.
279
- private onDocumentKeydown = (e: KeyboardEvent) => {
280
- if ((e.key !== "Escape" && e.key !== "Esc") || !this.handlesEscape(e)) {
281
- return;
282
- }
283
- this.closeOnEscape(e);
284
- };
285
-
286
- private handlesEscape(e: KeyboardEvent): boolean {
287
- if (!this._open || e.defaultPrevented) {
288
- return false;
289
- }
290
- const host = this.template.host;
291
- const path = e.composedPath();
292
- for (const node of path) {
293
- if (node instanceof Element && node.localName === "dx-popover") {
294
- return node === host;
295
- }
296
- }
297
- // A non-composed event fired in this shadow or on the trigger does
298
- // not list the host. The panel and control listeners still apply.
299
- return (
300
- (this.popover !== null && path.includes(this.popover)) ||
301
- (this.control !== null && path.includes(this.control))
302
- );
303
- }
304
-
305
- private clearOpenListenersTimer() {
306
- if (this.openListenersTimer !== undefined) {
307
- clearTimeout(this.openListenersTimer);
308
- this.openListenersTimer = undefined;
309
- }
310
- }
311
-
312
- private closeOnEscape(e: KeyboardEvent) {
313
- if (!this.open) {
314
- return;
315
- }
316
- e.preventDefault();
317
- this.dispatchRequestCloseEvent("keypress-escape");
318
- // Click-open + Escape upgrades :focus-visible on the trigger. Blur so
319
- // the closed picker shows hover (pointer still over it) or default,
320
- // not the keyboard halo. Keyboard-opened menus still restore focus.
321
- const openedWithPointer = this.pointerOpened;
322
- this.closePopover(!openedWithPointer);
323
- if (openedWithPointer) {
324
- this.blurControl();
325
- }
326
- }
327
-
328
- private blurControl() {
329
- const host = this.control;
330
- if (!host) {
331
- return;
332
- }
333
- const inner = host.shadowRoot?.activeElement as HTMLElement | null;
334
- if (inner && typeof inner.blur === "function") {
335
- inner.blur();
336
- return;
337
- }
338
- if (typeof host.blur === "function") {
339
- host.blur();
340
- }
341
- }
342
-
343
- private onControlClick = (e: MouseEvent) => {
239
+ private onControlClick = () => {
344
240
  if (this.controlled && this.open) {
345
241
  this.dispatchRequestCloseEvent("click-control");
346
242
  return;
@@ -361,10 +257,6 @@ export default class Popover extends LightningElement {
361
257
  return;
362
258
  }
363
259
 
364
- // Enter/Space on a button synthesizes a click with detail 0. Only a
365
- // pointer click should blur the trigger on Escape; keyboard activation
366
- // must leave focus on the control.
367
- this.pointerOpened = e.detail > 0;
368
260
  this.openPopover();
369
261
  };
370
262
 
@@ -395,20 +287,16 @@ export default class Popover extends LightningElement {
395
287
  switch (e.key) {
396
288
  case "Esc":
397
289
  case "Escape":
398
- this.closeOnEscape(e);
290
+ this.dispatchRequestCloseEvent("keypress-escape");
291
+ this.closePopover(true);
399
292
  break;
400
293
  default:
401
294
  }
402
295
  }
403
296
 
404
297
  private attachListenersTopopover() {
405
- // Capture so a click still counts as outside when a descendant
406
- // calls stopPropagation (topic version pickers do, so the tree row
407
- // does not navigate). Without this, opening a second picker leaves
408
- // the first menu open.
409
- document.addEventListener("click", this.interactOutsideListener, true);
298
+ document.addEventListener("click", this.interactOutsideListener);
410
299
  document.addEventListener("focusout", this.interactOutsideListener);
411
- document.addEventListener("keydown", this.onDocumentKeydown, true);
412
300
  if (this.openOnHover) {
413
301
  document.addEventListener(
414
302
  "mousemove",
@@ -1,18 +1,6 @@
1
1
  import type { InternalTreeNode, TreeNode } from "typings/custom";
2
- import type { TopicVersionOption } from "dxUtils/topicVersion";
3
- import {
4
- applyVersionToHref,
5
- normalizePath,
6
- resolveSelectedVersion
7
- } from "dxUtils/topicVersion";
8
-
9
- type VersionedTreeNode = TreeNode & { versions?: TopicVersionOption[] };
10
- type VersionedInternalTreeNode = InternalTreeNode & {
11
- versions?: TopicVersionOption[];
12
- };
13
-
14
2
  type MapItem = {
15
- node: VersionedInternalTreeNode;
3
+ node: InternalTreeNode;
16
4
  parent?: MapItem;
17
5
  setExpanded?: Function;
18
6
  };
@@ -33,10 +21,7 @@ export class TreeHandler {
33
21
  }
34
22
 
35
23
  getKeyByName(name: string): string | undefined {
36
- if (!name) {
37
- return undefined;
38
- }
39
- return this._nameKeyMap[name] || this._nameKeyMap[normalizePath(name)];
24
+ return name && this._nameKeyMap[name];
40
25
  }
41
26
 
42
27
  initialize(treeRoot: TreeNode): InternalTreeNode {
@@ -63,41 +48,12 @@ export class TreeHandler {
63
48
  }
64
49
 
65
50
  private convert(
66
- node: VersionedTreeNode,
51
+ node: TreeNode,
67
52
  level: number = 0,
68
53
  parent?: MapItem,
69
- position?: number,
70
- ancestorVersion?: {
71
- selected: TopicVersionOption;
72
- versions: TopicVersionOption[];
73
- }
74
- ): VersionedInternalTreeNode {
75
- const ownSelected = node.versions?.length
76
- ? resolveSelectedVersion(node)
77
- : undefined;
78
- const versionContext =
79
- ownSelected && node.versions
80
- ? { selected: ownSelected, versions: node.versions }
81
- : ancestorVersion;
82
-
83
- let link = node.link;
84
- if (
85
- versionContext &&
86
- !node.versions?.length &&
87
- link?.href &&
88
- link.target !== "_blank"
89
- ) {
90
- const rewritten = applyVersionToHref(
91
- link.href,
92
- versionContext.selected,
93
- versionContext.versions
94
- );
95
- if (rewritten && rewritten !== link.href) {
96
- link = { ...link, href: rewritten };
97
- }
98
- }
99
-
100
- const convertedNode: VersionedInternalTreeNode = {
54
+ position?: number
55
+ ): InternalTreeNode {
56
+ const convertedNode: InternalTreeNode = {
101
57
  label: node.label,
102
58
  name: node.name,
103
59
  key: this.calculateKey(
@@ -107,52 +63,24 @@ export class TreeHandler {
107
63
  level: level,
108
64
  isExpanded: node.isExpanded || false,
109
65
  isChildrenLoading: node.isChildrenLoading || false,
110
- link,
66
+ link: node.link,
111
67
  method: node.method,
112
68
  showForwardArrow: node.showForwardArrow,
113
- redirectToChild: node.redirectToChild,
114
- versions: node.versions
69
+ redirectToChild: node.redirectToChild
115
70
  };
116
71
 
117
72
  const mapItem = { node: convertedNode, parent };
118
73
  if (node.children && node.children.length > 0) {
119
74
  convertedNode.children = node.children.map((child, index) =>
120
- this.convert(child, level + 1, mapItem, index, versionContext)
75
+ this.convert(child, level + 1, mapItem, index)
121
76
  );
122
77
  }
123
78
 
124
79
  this._nodeMap[convertedNode.key] = mapItem;
125
- this.indexName(convertedNode.name, convertedNode.key);
126
- // A redirect parent can carry a child's href. This index runs after
127
- // the child, so recording it would make the parent win selection.
128
- if (!convertedNode.redirectToChild) {
129
- this.indexName(convertedNode.link?.href, convertedNode.key);
130
- }
131
- // Index this topic's own versioned URLs only. Parent-only switching
132
- // URLs point at a child with content and must not steal that child's
133
- // selection.
134
- if (node.name && node.versions) {
135
- for (const version of node.versions) {
136
- this.indexName(
137
- applyVersionToHref(node.name, version, node.versions),
138
- convertedNode.key
139
- );
140
- }
141
- }
80
+ this._nameKeyMap[convertedNode.name] = convertedNode.key;
142
81
  return convertedNode;
143
82
  }
144
83
 
145
- private indexName(name: string | undefined, key: string): void {
146
- if (!name) {
147
- return;
148
- }
149
- this._nameKeyMap[name] = key;
150
- const normalized = normalizePath(name);
151
- if (normalized && normalized !== name) {
152
- this._nameKeyMap[normalized] = key;
153
- }
154
- }
155
-
156
84
  private calculateKey(parentKey: string, position?: number): string {
157
85
  if (position === undefined) {
158
86
  return parentKey;