@stackoverflow/stacks 1.1.0 → 1.3.1

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 (40) hide show
  1. package/dist/controllers/s-expandable-control.d.ts +1 -1
  2. package/dist/controllers/s-tooltip.d.ts +16 -1
  3. package/dist/css/stacks.css +887 -708
  4. package/dist/css/stacks.min.css +1 -1
  5. package/dist/js/stacks.js +174 -91
  6. package/dist/js/stacks.min.js +1 -1
  7. package/lib/css/atomic/misc.less +1 -1
  8. package/lib/css/atomic/typography.less +0 -6
  9. package/lib/css/atomic/width-height.less +1 -1
  10. package/lib/css/components/activity-indicator.less +18 -17
  11. package/lib/css/components/avatars.less +51 -131
  12. package/lib/css/components/badges.less +47 -0
  13. package/lib/css/components/breadcrumbs.less +4 -4
  14. package/lib/css/components/buttons.less +38 -54
  15. package/lib/css/components/empty-states.less +15 -0
  16. package/lib/css/components/{collapsible.less → expandable.less} +0 -0
  17. package/lib/css/components/inputs.less +44 -110
  18. package/lib/css/components/labels.less +98 -0
  19. package/lib/css/components/notices.less +190 -163
  20. package/lib/css/components/post-summary.less +34 -99
  21. package/lib/css/components/progress-bars.less +1 -1
  22. package/lib/css/components/prose.less +4 -4
  23. package/lib/css/components/spinner.less +39 -1
  24. package/lib/css/components/tables.less +1 -5
  25. package/lib/css/components/topbar.less +4 -1
  26. package/lib/css/components/uploader.less +70 -84
  27. package/lib/css/exports/constants-colors.less +63 -49
  28. package/lib/css/stacks-dynamic.less +0 -1
  29. package/lib/css/stacks-static.less +3 -2
  30. package/lib/ts/controllers/s-expandable-control.ts +23 -19
  31. package/lib/ts/controllers/s-modal.ts +16 -16
  32. package/lib/ts/controllers/s-navigation-tablist.ts +13 -13
  33. package/lib/ts/controllers/s-popover.ts +26 -18
  34. package/lib/ts/controllers/s-table.ts +31 -29
  35. package/lib/ts/controllers/s-tooltip.ts +62 -23
  36. package/lib/ts/controllers/s-uploader.ts +26 -12
  37. package/lib/ts/stacks.ts +8 -4
  38. package/package.json +25 -25
  39. package/lib/css/components/banners.less +0 -80
  40. package/lib/css/components/blank-states.less +0 -26
@@ -6,12 +6,12 @@ export class ModalController extends Stacks.StacksController {
6
6
  private modalTarget!: HTMLElement;
7
7
  private initialFocusTargets!: HTMLElement[];
8
8
 
9
- private _boundClickFn!: any;
10
- private _boundKeypressFn!: any;
9
+ private _boundClickFn!: (event: MouseEvent) => void;
10
+ private _boundKeypressFn!: (event: KeyboardEvent) => void;
11
11
 
12
12
  private returnElement!: HTMLElement;
13
13
 
14
- private _boundTabTrap!: any;
14
+ private _boundTabTrap!: (event: KeyboardEvent) => void;
15
15
 
16
16
  connect () {
17
17
  this.validate();
@@ -50,7 +50,7 @@ export class ModalController extends Stacks.StacksController {
50
50
  */
51
51
  private validate() {
52
52
  // check for returnElement support
53
- var returnElementSelector = this.data.get("return-element");
53
+ const returnElementSelector = this.data.get("return-element");
54
54
  if (returnElementSelector) {
55
55
  this.returnElement = <HTMLElement>document.querySelector(returnElementSelector);
56
56
 
@@ -65,8 +65,8 @@ export class ModalController extends Stacks.StacksController {
65
65
  * @param show Optional parameter that force shows/hides the element or toggles it if left undefined
66
66
  */
67
67
  private _toggle (show?: boolean | undefined, dispatcher: Event|Element|null = null) {
68
- var toShow = show;
69
- var isVisible = this.modalTarget.getAttribute("aria-hidden") === "false";
68
+ let toShow = show;
69
+ const isVisible = this.modalTarget.getAttribute("aria-hidden") === "false";
70
70
 
71
71
  // if we're letting the class toggle, we need to figure out if the popover is visible manually
72
72
  if (typeof toShow === "undefined") {
@@ -78,10 +78,10 @@ export class ModalController extends Stacks.StacksController {
78
78
  return;
79
79
  }
80
80
 
81
- let dispatchingElement = this.getDispatcher(dispatcher);
81
+ const dispatchingElement = this.getDispatcher(dispatcher);
82
82
 
83
83
  // show/hide events trigger before toggling the class
84
- var triggeredEvent = this.triggerEvent(toShow ? "show" : "hide", {
84
+ const triggeredEvent = this.triggerEvent(toShow ? "show" : "hide", {
85
85
  returnElement: this.returnElement,
86
86
  dispatcher: this.getDispatcher(dispatchingElement)
87
87
  }, this.modalTarget);
@@ -105,7 +105,7 @@ export class ModalController extends Stacks.StacksController {
105
105
  }
106
106
 
107
107
  // check for transitionend support
108
- var supportsTransitionEnd = (<HTMLElement>this.modalTarget).ontransitionend !== undefined;
108
+ const supportsTransitionEnd = (this.modalTarget).ontransitionend !== undefined;
109
109
 
110
110
  // shown/hidden events trigger after toggling the class
111
111
  if (supportsTransitionEnd) {
@@ -182,7 +182,7 @@ export class ModalController extends Stacks.StacksController {
182
182
  */
183
183
  private focusInsideModal() {
184
184
  this.modalTarget.addEventListener("s-modal:shown", () => {
185
- var initialFocus = this.firstVisible(this.initialFocusTargets) ?? this.firstVisible(this.getAllTabbables());
185
+ const initialFocus = this.firstVisible(this.initialFocusTargets) ?? this.firstVisible(this.getAllTabbables());
186
186
  initialFocus?.focus();
187
187
  }, {once: true });
188
188
  }
@@ -194,7 +194,7 @@ export class ModalController extends Stacks.StacksController {
194
194
 
195
195
  // If somehow the user has tabbed out of the modal or if focus started outside the modal, push them to the first item.
196
196
  if (!this.modalTarget.contains(<Element>e.target)) {
197
- var focusTarget = this.firstVisible(this.getAllTabbables());
197
+ const focusTarget = this.firstVisible(this.getAllTabbables());
198
198
  if (focusTarget) {
199
199
  e.preventDefault();
200
200
  focusTarget.focus();
@@ -205,10 +205,10 @@ export class ModalController extends Stacks.StacksController {
205
205
 
206
206
  // If we observe a tab keydown and we're on an edge, cycle the focus to the other side.
207
207
  if (e.key === "Tab") {
208
- var tabbables = this.getAllTabbables();
208
+ const tabbables = this.getAllTabbables();
209
209
 
210
- var firstTabbable = this.firstVisible(tabbables);
211
- var lastTabbable = this.lastVisible(tabbables);
210
+ const firstTabbable = this.firstVisible(tabbables);
211
+ const lastTabbable = this.lastVisible(tabbables);
212
212
 
213
213
  if (firstTabbable && lastTabbable) {
214
214
  if (firstTabbable === lastTabbable) {
@@ -252,7 +252,7 @@ export class ModalController extends Stacks.StacksController {
252
252
  * Forces the popover to hide if a user clicks outside of it or its reference element
253
253
  */
254
254
  private hideOnOutsideClick (e: Event) {
255
- var target = <Node>e.target;
255
+ const target = <Node>e.target;
256
256
  // check if the document was clicked inside either the toggle element or the modal itself
257
257
  // note: .contains also returns true if the node itself matches the target element
258
258
  if (!this.modalTarget.querySelector(".s-modal--dialog")!.contains(target) && document.body.contains(target)) {
@@ -311,7 +311,7 @@ export function hideModal(element: HTMLElement) {
311
311
  * @param show whether to force show/hide the modal; toggles the modal if left undefined
312
312
  */
313
313
  function toggleModal(element: HTMLElement, show?: boolean | undefined) {
314
- var controller = Stacks.application.getControllerForElementAndIdentifier(element, "s-modal") as ModalController;
314
+ const controller = Stacks.application.getControllerForElementAndIdentifier(element, "s-modal") as ModalController;
315
315
 
316
316
  if (!controller) {
317
317
  throw "Unable to get s-modal controller from element";
@@ -2,8 +2,8 @@ import * as Stacks from "../stacks";
2
2
 
3
3
  export class TabListController extends Stacks.StacksController {
4
4
 
5
- private boundSelectTab: any; // (event: MouseEvent) => void;
6
- private boundHandleKeydown: any // (event: KeyboardEvent) => void;
5
+ private boundSelectTab!: (event: MouseEvent) => void;
6
+ private boundHandleKeydown!: (event: KeyboardEvent) => void;
7
7
 
8
8
  connect() {
9
9
  super.connect();
@@ -11,7 +11,7 @@ export class TabListController extends Stacks.StacksController {
11
11
  this.boundSelectTab = this.selectTab.bind(this);
12
12
  this.boundHandleKeydown = this.handleKeydown.bind(this);
13
13
 
14
- for (let tab of this.tabTargets) {
14
+ for (const tab of this.tabTargets) {
15
15
  tab.addEventListener("click", this.boundSelectTab);
16
16
  tab.addEventListener("keydown", this.boundHandleKeydown);
17
17
  }
@@ -20,7 +20,7 @@ export class TabListController extends Stacks.StacksController {
20
20
  disconnect() {
21
21
  super.disconnect();
22
22
 
23
- for (let tab of this.tabTargets) {
23
+ for (const tab of this.tabTargets) {
24
24
  tab.removeEventListener("click", this.boundSelectTab);
25
25
  tab.removeEventListener("keydown", this.boundHandleKeydown);
26
26
  }
@@ -29,8 +29,8 @@ export class TabListController extends Stacks.StacksController {
29
29
  /**
30
30
  * Gets all tabs within the controller.
31
31
  */
32
- get tabTargets() {
33
- return <HTMLElement[]>Array.from(this.element.querySelectorAll("[role=tab]"));
32
+ get tabTargets(): HTMLElement[] {
33
+ return Array.from(this.element.querySelectorAll("[role=tab]"));
34
34
  }
35
35
 
36
36
  /**
@@ -47,8 +47,8 @@ export class TabListController extends Stacks.StacksController {
47
47
  handleKeydown(event: KeyboardEvent) {
48
48
  let tabElement = <HTMLElement>event.currentTarget;
49
49
 
50
- var tabs = this.tabTargets;
51
- var tabIndex = tabs.indexOf(tabElement);
50
+ const tabs = this.tabTargets;
51
+ let tabIndex = tabs.indexOf(tabElement);
52
52
 
53
53
  if (event.key === "ArrowRight") {
54
54
  tabIndex++;
@@ -62,7 +62,7 @@ export class TabListController extends Stacks.StacksController {
62
62
  if (tabIndex < 0) { tabIndex = tabs.length - 1; }
63
63
  if (tabIndex >= tabs.length) { tabIndex = 0; }
64
64
 
65
- tabElement = <HTMLElement>tabs[tabIndex];
65
+ tabElement = tabs[tabIndex];
66
66
  this.switchToTab(tabElement);
67
67
 
68
68
  // Focus the newly selected tab so it can receive keyboard events.
@@ -75,7 +75,7 @@ export class TabListController extends Stacks.StacksController {
75
75
  */
76
76
  private switchToTab(newTab: HTMLElement) {
77
77
 
78
- var oldTab = this.selectedTab;
78
+ const oldTab = this.selectedTab;
79
79
  if (oldTab === newTab) { return; }
80
80
 
81
81
  if (this.triggerEvent("select", { oldTab, newTab }).defaultPrevented) { return; }
@@ -98,9 +98,9 @@ export class TabListController extends Stacks.StacksController {
98
98
  * is not a valid tab, all tabs will be unselected.
99
99
  */
100
100
  public set selectedTab(selectedTab: HTMLElement | null) {
101
- for (let tab of this.tabTargets) {
102
- let panelId = tab.getAttribute('aria-controls');
103
- let panel = panelId ? document.getElementById(panelId) : null;
101
+ for (const tab of this.tabTargets) {
102
+ const panelId = tab.getAttribute('aria-controls');
103
+ const panel = panelId ? document.getElementById(panelId) : null;
104
104
 
105
105
  if (tab === selectedTab) {
106
106
  tab.classList.add('is-selected');
@@ -1,11 +1,11 @@
1
1
  import { createPopper, Placement } from '@popperjs/core';
2
+ import type * as Popper from '@popperjs/core';
2
3
  import * as Stacks from "../stacks";
3
4
 
4
5
  type OutsideClickBehavior = "always" | "never" | "if-in-viewport" | "after-dismissal";
5
6
 
6
7
  export abstract class BasePopoverController extends Stacks.StacksController {
7
- // @ts-ignore
8
- private popper!: Popper;
8
+ private popper!: Popper.Instance;
9
9
 
10
10
  protected popoverElement!: HTMLElement;
11
11
 
@@ -87,6 +87,8 @@ export abstract class BasePopoverController extends Stacks.StacksController {
87
87
  this.hide();
88
88
  if (this.popper) {
89
89
  this.popper.destroy();
90
+ // eslint-disable-next-line
91
+ // @ts-ignore The operand of a 'delete' operator must be optional .ts(2790)
90
92
  delete this.popper;
91
93
  }
92
94
  super.disconnect();
@@ -105,7 +107,7 @@ export abstract class BasePopoverController extends Stacks.StacksController {
105
107
  show(dispatcher: Event|Element|null = null) {
106
108
  if (this.isVisible) { return; }
107
109
 
108
- let dispatcherElement = this.getDispatcher(dispatcher);
110
+ const dispatcherElement = this.getDispatcher(dispatcher);
109
111
 
110
112
  if (this.triggerEvent("show", {
111
113
  dispatcher: dispatcherElement
@@ -115,7 +117,7 @@ export abstract class BasePopoverController extends Stacks.StacksController {
115
117
  this.initializePopper();
116
118
  }
117
119
 
118
- this.popoverElement!.classList.add("is-visible");
120
+ this.popoverElement.classList.add("is-visible");
119
121
 
120
122
  // ensure the popper has been positioned correctly
121
123
  this.scheduleUpdate();
@@ -129,7 +131,7 @@ export abstract class BasePopoverController extends Stacks.StacksController {
129
131
  hide(dispatcher: Event|Element|null = null) {
130
132
  if (!this.isVisible) { return; }
131
133
 
132
- let dispatcherElement = this.getDispatcher(dispatcher);
134
+ const dispatcherElement = this.getDispatcher(dispatcher);
133
135
 
134
136
  if (this.triggerEvent("hide", {
135
137
  dispatcher: dispatcherElement
@@ -140,6 +142,8 @@ export abstract class BasePopoverController extends Stacks.StacksController {
140
142
  if (this.popper) {
141
143
  // completely destroy the popper on hide; this is in line with Popper.js's performance recommendations
142
144
  this.popper.destroy();
145
+ // eslint-disable-next-line
146
+ // @ts-ignore The operand of a 'delete' operator must be optional .ts(2790)
143
147
  delete this.popper;
144
148
  }
145
149
 
@@ -182,7 +186,6 @@ export abstract class BasePopoverController extends Stacks.StacksController {
182
186
  * Initializes the Popper for this instance
183
187
  */
184
188
  private initializePopper() {
185
- // @ts-ignore
186
189
  this.popper = createPopper(this.referenceElement, this.popoverElement, {
187
190
  placement: this.data.get("placement") as Placement || "bottom",
188
191
  modifiers: [
@@ -206,7 +209,7 @@ export abstract class BasePopoverController extends Stacks.StacksController {
206
209
  * Validates the popover settings and attempts to set necessary internal variables
207
210
  */
208
211
  private validate() {
209
- var referenceSelector = this.data.get("reference-selector");
212
+ const referenceSelector = this.data.get("reference-selector");
210
213
 
211
214
  this.referenceElement = <HTMLElement>this.element;
212
215
 
@@ -221,7 +224,7 @@ export abstract class BasePopoverController extends Stacks.StacksController {
221
224
 
222
225
  const popoverId = this.referenceElement.getAttribute(this.popoverSelectorAttribute);
223
226
 
224
- var popoverElement = null;
227
+ let popoverElement: HTMLElement | null = null;
225
228
 
226
229
  // if the popover is named, attempt to fetch it (and throw an error if it doesn't exist)
227
230
  if (popoverId) {
@@ -264,7 +267,7 @@ export abstract class BasePopoverController extends Stacks.StacksController {
264
267
  */
265
268
  protected scheduleUpdate() {
266
269
  if (this.popper && this.isVisible) {
267
- this.popper.update();
270
+ void this.popper.update();
268
271
  }
269
272
  }
270
273
  }
@@ -274,8 +277,8 @@ export class PopoverController extends BasePopoverController {
274
277
 
275
278
  protected popoverSelectorAttribute = "aria-controls";
276
279
 
277
- private boundHideOnOutsideClick!: any;
278
- private boundHideOnEscapePress!: any;
280
+ private boundHideOnOutsideClick!: (event: MouseEvent) => void;
281
+ private boundHideOnEscapePress!: (event: KeyboardEvent) => void;
279
282
 
280
283
  /**
281
284
  * Toggles optional classes and accessibility attributes in addition to BasePopoverController.shown
@@ -332,7 +335,7 @@ export class PopoverController extends BasePopoverController {
332
335
  const target = <Node>e.target;
333
336
  // check if the document was clicked inside either the reference element or the popover itself
334
337
  // note: .contains also returns true if the node itself matches the target element
335
- if (this.shouldHideOnOutsideClick && !this.referenceElement.contains(target) && !this.popoverElement!.contains(target) && document.body.contains(target)) {
338
+ if (this.shouldHideOnOutsideClick && !this.referenceElement.contains(target) && !this.popoverElement.contains(target) && document.body.contains(target)) {
336
339
  this.hide(e);
337
340
  }
338
341
  };
@@ -349,7 +352,7 @@ export class PopoverController extends BasePopoverController {
349
352
 
350
353
  // check if the target was inside the popover element and refocus the triggering element
351
354
  // note: .contains also returns true if the node itself matches the target element
352
- if (this.popoverElement!.contains(<Node>e.target)) {
355
+ if (this.popoverElement.contains(<Node>e.target)) {
353
356
  this.referenceElement.focus();
354
357
  }
355
358
 
@@ -364,8 +367,10 @@ export class PopoverController extends BasePopoverController {
364
367
  if (!this.data.has("toggle-class")) {
365
368
  return;
366
369
  }
367
- var cl = this.referenceElement.classList;
368
- this.data.get("toggle-class")!.split(/\s+/).forEach(function (cls: string) {
370
+
371
+ const toggleClass = this.data.get("toggle-class") || "";
372
+ const cl = this.referenceElement.classList;
373
+ toggleClass.split(/\s+/).forEach(function (cls: string) {
369
374
  cl.toggle(cls, show);
370
375
  });
371
376
  }
@@ -375,7 +380,9 @@ export class PopoverController extends BasePopoverController {
375
380
  * @param {boolean=} show - A boolean indicating whether this is being triggered by a show or hide.
376
381
  */
377
382
  private toggleAccessibilityAttributes(show?: boolean) {
378
- this.referenceElement.ariaExpanded = show?.toString() || this.referenceElement.ariaExpanded || 'false';
383
+ const expandedValue = show?.toString() || this.referenceElement.ariaExpanded || "false";
384
+ this.referenceElement.ariaExpanded = expandedValue;
385
+ this.referenceElement.setAttribute("aria-expanded", expandedValue);
379
386
  }
380
387
  }
381
388
 
@@ -453,6 +460,7 @@ export function attachPopover(element: Element, popover: Element | string, optio
453
460
  }
454
461
 
455
462
  if (typeof popover === 'string') {
463
+ // eslint-disable-next-line no-unsanitized/method
456
464
  const elements = document.createRange().createContextualFragment(popover).children;
457
465
  if (elements.length !== 1) {
458
466
  throw "popover should contain a single element";
@@ -461,7 +469,7 @@ export function attachPopover(element: Element, popover: Element | string, optio
461
469
  }
462
470
 
463
471
  const existingId = referenceElement.getAttribute("aria-controls");
464
- var popoverId = popover.id;
472
+ let popoverId = popover.id;
465
473
 
466
474
  if (!popover.classList.contains('s-popover')) {
467
475
  throw `popover should have the "s-popover" class but had class="${popover.className}"`;
@@ -557,7 +565,7 @@ function getPopover(element: Element): GetPopoverResult {
557
565
  * @param include Whether to add the controllerName value
558
566
  */
559
567
  function toggleController(el: Element, controllerName: string, include: boolean) {
560
- var controllers = new Set(el.getAttribute('data-controller')?.split(/\s+/));
568
+ const controllers = new Set(el.getAttribute('data-controller')?.split(/\s+/));
561
569
  if (include) {
562
570
  controllers.add(controllerName);
563
571
  } else {
@@ -9,14 +9,15 @@ export class TableController extends Stacks.StacksController {
9
9
  if (["asc", "desc", "none"].indexOf(direction) < 0) {
10
10
  throw "direction must be one of asc, desc, or none"
11
11
  }
12
- var controller = this;
12
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
13
+ const controller = this;
13
14
  this.columnTargets.forEach(function (target) {
14
- var isCurrrent = target === headElem;
15
+ const isCurrrent = target === headElem;
15
16
 
16
17
  target.classList.toggle("is-sorted", isCurrrent && direction !== "none");
17
18
 
18
19
  target.querySelectorAll(".js-sorting-indicator").forEach(function (icon) {
19
- var visible = isCurrrent ? direction : "none";
20
+ const visible = isCurrrent ? direction : "none";
20
21
  icon.classList.toggle("d-none", !icon.classList.contains("js-sorting-indicator-" + visible));
21
22
  });
22
23
 
@@ -29,16 +30,17 @@ export class TableController extends Stacks.StacksController {
29
30
  };
30
31
 
31
32
  sort(evt: Event) {
32
- var controller = this;
33
- var colHead = evt.currentTarget;
33
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
34
+ const controller = this;
35
+ const colHead = evt.currentTarget;
34
36
  if (!(colHead instanceof HTMLTableCellElement)) {
35
37
  throw "invalid event target";
36
38
  }
37
- var table = this.element as HTMLTableElement;
38
- var tbody = table.tBodies[0];
39
+ const table = this.element as HTMLTableElement;
40
+ const tbody = table.tBodies[0];
39
41
 
40
42
  // the column slot number of the clicked header
41
- var colno = getCellSlot(colHead);
43
+ const colno = getCellSlot(colHead);
42
44
 
43
45
  if (colno < 0) { // this shouldn't happen if the clicked element is actually a column head
44
46
  return;
@@ -46,23 +48,23 @@ export class TableController extends Stacks.StacksController {
46
48
 
47
49
  // an index of the <tbody>, so we can find out for each row which <td> element is
48
50
  // in the same column slot as the header
49
- var slotIndex = buildIndex(tbody);
51
+ const slotIndex = buildIndex(tbody);
50
52
 
51
53
  // the default behavior when clicking a header is to sort by this column in ascending
52
54
  // direction, *unless* it is already sorted that way
53
- var direction = this.getElementData(colHead, "sort-direction") === "asc" ? -1 : 1;
55
+ const direction = this.getElementData(colHead, "sort-direction") === "asc" ? -1 : 1;
54
56
 
55
- var rows = Array.from(table.tBodies[0].rows);
57
+ const rows = Array.from(table.tBodies[0].rows);
56
58
 
57
59
  // if this is still false after traversing the data, that means all values are integers (or empty)
58
60
  // and thus we'll sort numerically.
59
- var anyNonInt = false;
61
+ let anyNonInt = false;
60
62
 
61
63
  // data will be a list of tuples [value, rowNum], where value is what we're sorting by
62
- var data: [string | number, number][] = [];
63
- var firstBottomRow: HTMLTableRowElement;
64
+ const data: [string | number, number][] = [];
65
+ let firstBottomRow: HTMLTableRowElement;
64
66
  rows.forEach(function (row, index) {
65
- var force = controller.getElementData(row, "sort-to");
67
+ const force = controller.getElementData(row, "sort-to");
66
68
  if (force === "top") {
67
69
  return; // rows not added to the list will automatically end up at the top
68
70
  } else if (force === "bottom") {
@@ -71,7 +73,7 @@ export class TableController extends Stacks.StacksController {
71
73
  }
72
74
  return;
73
75
  }
74
- var cell = slotIndex[index][colno];
76
+ const cell = slotIndex[index][colno];
75
77
  if (!cell) {
76
78
  data.push(["", index]);
77
79
  return;
@@ -79,10 +81,10 @@ export class TableController extends Stacks.StacksController {
79
81
 
80
82
  // unless the to-be-sorted-by value is explicitly provided on the element via this attribute,
81
83
  // the value we're using is the cell's text, trimmed of any whitespace
82
- var explicit = controller.getElementData(cell, "sort-val");
83
- var d = typeof explicit === "string" ? explicit : cell.textContent!.trim();
84
+ const explicit = controller.getElementData(cell, "sort-val");
85
+ const d = typeof explicit === "string" ? explicit : cell.textContent!.trim();
84
86
 
85
- if ((d !== "") && (parseInt(d, 10) + "" !== d)) {
87
+ if ((d !== "") && (`${parseInt(d, 10)}` !== d)) {
86
88
  anyNonInt = true;
87
89
  }
88
90
  data.push([d, index]);
@@ -114,7 +116,7 @@ export class TableController extends Stacks.StacksController {
114
116
 
115
117
  // this is the actual reordering of the table rows
116
118
  data.forEach(function (tup) {
117
- var row = rows[tup[1]];
119
+ const row = rows[tup[1]];
118
120
  row.parentElement!.removeChild(row);
119
121
  if (firstBottomRow) {
120
122
  tbody.insertBefore(row, firstBottomRow);
@@ -165,29 +167,29 @@ function getCellSlot(cell: HTMLTableCellElement): number {
165
167
  // If the second argument is given, it's a <td> or <th> that we're trying to find, and the algorithm
166
168
  // stops as soon as it has found it and the function returns its slot number.
167
169
  function buildIndexOrGetCellSlot(section: HTMLTableSectionElement, findCell?: HTMLTableCellElement) {
168
- var index = [];
169
- var curRow = section.children[0];
170
+ const index = [];
171
+ let curRow = section.children[0];
170
172
 
171
173
  // the elements of these two arrays are synchronized; the first array contains table cell elements,
172
174
  // the second one contains a number that indicates for how many more rows this elements will
173
175
  // exist (i.e. the value is initially one less than the cell's rowspan, and will be decreased for each row)
174
- var growing: HTMLTableCellElement[] = [];
175
- var growingRowsLeft: number[] = [];
176
+ const growing: HTMLTableCellElement[] = [];
177
+ const growingRowsLeft: number[] = [];
176
178
 
177
179
  // continue while we have actual <tr>'s left *or* we still have rowspan'ed elements that aren't done
178
180
  while (curRow || growingRowsLeft.some(function (e) { return e !== 0; })) {
179
- var curIndexRow: HTMLTableCellElement[] = [];
181
+ const curIndexRow: HTMLTableCellElement[] = [];
180
182
  index.push(curIndexRow);
181
183
 
182
- var curSlot = 0;
184
+ let curSlot = 0;
183
185
  if (curRow) {
184
- for (var curCellInd = 0; curCellInd < curRow.children.length; curCellInd++) {
186
+ for (let curCellInd = 0; curCellInd < curRow.children.length; curCellInd++) {
185
187
  while (growingRowsLeft[curSlot]) {
186
188
  growingRowsLeft[curSlot]--;
187
189
  curIndexRow[curSlot] = growing[curSlot];
188
190
  curSlot++;
189
191
  }
190
- var cell = curRow.children[curCellInd];
192
+ const cell = curRow.children[curCellInd];
191
193
  if (!(cell instanceof HTMLTableCellElement)) {
192
194
  throw "invalid table"
193
195
  }
@@ -197,7 +199,7 @@ function buildIndexOrGetCellSlot(section: HTMLTableSectionElement, findCell?: HT
197
199
  if (cell === findCell) {
198
200
  return curSlot;
199
201
  }
200
- var nextFreeSlot = curSlot + cell.colSpan;
202
+ const nextFreeSlot = curSlot + cell.colSpan;
201
203
  for (; curSlot < nextFreeSlot; curSlot++) {
202
204
  growingRowsLeft[curSlot] = cell.rowSpan - 1; // if any of these is already growing, the table is broken -- no guarantees of anything
203
205
  growing[curSlot] = cell;