sidebar_hover.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // TODO: This file was created by bulk-decaffeinate.
  2. // Sanity-check the conversion and remove this comment.
  3. /*
  4. * decaffeinate suggestions:
  5. * DS002: Fix invalid constructor
  6. * DS102: Remove unnecessary code created because of implicit returns
  7. * DS103: Rewrite code to no longer use __guard__, or convert again using --optional-chaining
  8. * DS206: Consider reworking classes to avoid initClass
  9. * DS207: Consider shorter variations of null checks
  10. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
  11. */
  12. app.views.SidebarHover = class SidebarHover extends app.View {
  13. static initClass() {
  14. this.itemClass = "_list-hover";
  15. this.events = {
  16. focus: "onFocus",
  17. blur: "onBlur",
  18. mouseover: "onMouseover",
  19. mouseout: "onMouseout",
  20. scroll: "onScroll",
  21. click: "onClick",
  22. };
  23. this.routes = { after: "onRoute" };
  24. }
  25. constructor(el) {
  26. this.position = this.position.bind(this);
  27. this.onFocus = this.onFocus.bind(this);
  28. this.onBlur = this.onBlur.bind(this);
  29. this.onMouseover = this.onMouseover.bind(this);
  30. this.onMouseout = this.onMouseout.bind(this);
  31. this.onScroll = this.onScroll.bind(this);
  32. this.onClick = this.onClick.bind(this);
  33. this.onRoute = this.onRoute.bind(this);
  34. this.el = el;
  35. if (!isPointerEventsSupported()) {
  36. delete this.constructor.events.mouseover;
  37. }
  38. super(...arguments);
  39. }
  40. show(el) {
  41. if (el !== this.cursor) {
  42. this.hide();
  43. if (this.isTarget(el) && this.isTruncated(el.lastElementChild || el)) {
  44. this.cursor = el;
  45. this.clone = this.makeClone(this.cursor);
  46. $.append(document.body, this.clone);
  47. if (this.offsetTop == null) {
  48. this.offsetTop = this.el.offsetTop;
  49. }
  50. this.position();
  51. }
  52. }
  53. }
  54. hide() {
  55. if (this.cursor) {
  56. $.remove(this.clone);
  57. this.cursor = this.clone = null;
  58. }
  59. }
  60. position() {
  61. if (this.cursor) {
  62. const rect = $.rect(this.cursor);
  63. if (rect.top >= this.offsetTop) {
  64. this.clone.style.top = rect.top + "px";
  65. this.clone.style.left = rect.left + "px";
  66. } else {
  67. this.hide();
  68. }
  69. }
  70. }
  71. makeClone(el) {
  72. const clone = el.cloneNode(true);
  73. clone.classList.add("clone");
  74. return clone;
  75. }
  76. isTarget(el) {
  77. return __guard__(el != null ? el.classList : undefined, (x) =>
  78. x.contains(this.constructor.itemClass),
  79. );
  80. }
  81. isSelected(el) {
  82. return el.classList.contains("active");
  83. }
  84. isTruncated(el) {
  85. return el.scrollWidth > el.offsetWidth;
  86. }
  87. onFocus(event) {
  88. this.focusTime = Date.now();
  89. this.show(event.target);
  90. }
  91. onBlur() {
  92. this.hide();
  93. }
  94. onMouseover(event) {
  95. if (
  96. this.isTarget(event.target) &&
  97. !this.isSelected(event.target) &&
  98. this.mouseActivated()
  99. ) {
  100. this.show(event.target);
  101. }
  102. }
  103. onMouseout(event) {
  104. if (this.isTarget(event.target) && this.mouseActivated()) {
  105. this.hide();
  106. }
  107. }
  108. mouseActivated() {
  109. // Skip mouse events caused by focus events scrolling the sidebar.
  110. return !this.focusTime || Date.now() - this.focusTime > 500;
  111. }
  112. onScroll() {
  113. this.position();
  114. }
  115. onClick(event) {
  116. if (event.target === this.clone) {
  117. $.click(this.cursor);
  118. }
  119. }
  120. onRoute() {
  121. this.hide();
  122. }
  123. };
  124. app.views.SidebarHover.initClass();
  125. var isPointerEventsSupported = function () {
  126. const el = document.createElement("div");
  127. el.style.cssText = "pointer-events: auto";
  128. return el.style.pointerEvents === "auto";
  129. };
  130. function __guard__(value, transform) {
  131. return typeof value !== "undefined" && value !== null
  132. ? transform(value)
  133. : undefined;
  134. }