{"version":3,"file":"discourse-tooltips.js","names":["define","_exports","Object","defineProperty","value","setEventFrom","eventFrom","recentTouchTimeoutId","recentEventFrom","recentFocusFrom","recentTouch","recentMouse","recentWindowFocus","setRecentEventFromTouch","touchDelay","window","clearTimeout","setTimeout","recentMouseTimeoutId","setRecentEventFromMouse","handleTouchEvent","handlePointerEvent","e","pointerType","handleMouseEvent","handleKeyEvent","recentWindowFocusTimeoutId","handleWindowFocusEvent","target","document","listenerOptions","capture","passive","documentListeners","forEach","_ref","eventName","eventHandler","addEventListener","process","env","NODE_ENV","Error","event","test","type","_pluginApi","_topicHoverExtension","default","_default","name","initialize","withPluginApi","api","modifyClass","hoverExtension","_ajax","_object","_eventFrom","_runloop","selector","pluginId","didInsertElement","this","_super","arguments","cancel","$","element","on","$this","$parentTopicId","currentTarget","attr","parents","last","topicId","parseInt","_inside","_cached","renderTooltip","excerpt","tooltipsRateLimited","topicIds","nextAll","READ_AHEAD","each","idx","s","siblingId","getAttribute","push","_promise","ajax","data","topic_ids","cache","then","r","excerpts","deepMerge","catch","xhr","jqXHR","status","tryAfter","getResponseHeader","rateLimiter","later","cleanDom","willDestroyElement","find","off","remove","abort","text","after","$dTooltip","tooltipWidth","outerWidth","elementWidth","width","elementHeight","height","elementPos","position","elementX","left","y","top","x","hasClass","offset","css","fadeIn"],"sources":["discourse/plugins/discourse-tooltips/discourse/lib/event-from.js","discourse/plugins/discourse-tooltips/initializers/attach-hover-event.js","discourse/plugins/discourse-tooltips/mixins/topic-hover-extension.js"],"sourcesContent":["define(\"discourse/plugins/discourse-tooltips/discourse/lib/event-from\", [\"exports\"], function (_exports) {\n  \"use strict\";\n\n  Object.defineProperty(_exports, \"__esModule\", {\n    value: true\n  });\n  _exports.setEventFrom = _exports.eventFrom = void 0;\n  0; //eaimeta@70e063a35619d71feaimeta@70e063a35619d71f\n  /* eslint-disable */\n  // prettier-ignore\n\n  // Source: event-from ^1.0.0 package\n\n  let recentEventFrom = \"key\";\n  let recentFocusFrom = recentEventFrom;\n  let recentTouch = false;\n  let recentMouse = false;\n  let recentWindowFocus = false;\n  // To determine if there was a recentTouch event\n  // use setTimeout instead of a Date.now() comparison because\n  // in the case of a long running/blocking process from a touch event,\n  // the browser will push the corresponding mouse event (created by the touch interaction)\n  // onto the callback queue at the time it should be executed,\n  // and then push the timeout function onto the queue after the timer expires,\n  // even if the the main thread is still blocked (because the browser is multi-threaded).\n  // This results in the mouse event being moved to the callstack and called\n  // before the timeout function so recentTouch is still true\n  // regardless of how many Date.now() seconds have gone by.\n  // Also, if subsequent touch events occur while the blocking process is running,\n  // the browser will push the touch events onto the queue when the touch happens,\n  // and if one of them is in queue before the previous touch event's timer expires,\n  // it will be called before the timeout's function (so it can reset the timer),\n  // and, this is the key part, if the previous timer has finished and it's callback is added to the queue,\n  // the call to clearTimeout(recentTouchTimeoutId) will remove the timeout's function from the callback queue.\n  let recentTouchTimeoutId;\n  const setRecentEventFromTouch = touchDelay => {\n    recentTouch = true;\n    recentEventFrom = \"touch\";\n    window.clearTimeout(recentTouchTimeoutId);\n    recentTouchTimeoutId = window.setTimeout(() => {\n      recentTouch = false;\n    }, touchDelay);\n  };\n  let recentMouseTimeoutId;\n  const setRecentEventFromMouse = () => {\n    recentMouse = true;\n    recentEventFrom = \"mouse\";\n    window.clearTimeout(recentMouseTimeoutId);\n    recentMouseTimeoutId = window.setTimeout(() => {\n      recentMouse = false;\n    }, 200);\n  };\n  const handleTouchEvent = touchDelay => () => setRecentEventFromTouch(touchDelay);\n  const handlePointerEvent = touchDelay => e => {\n    switch (e.pointerType) {\n      case \"mouse\":\n        setRecentEventFromMouse();\n        break;\n      case \"pen\":\n      case \"touch\":\n        setRecentEventFromTouch(touchDelay);\n        break;\n    }\n  };\n  const handleMouseEvent = () => {\n    if (!recentTouch) {\n      setRecentEventFromMouse();\n    }\n  };\n  const handleKeyEvent = () => {\n    recentEventFrom = \"key\";\n  };\n  // recentFocusFrom tracking\n  // set document focus event capture listener which sets recentFocusFrom equal to recentEventFrom\n  // except if there is a recent window focus event where the window is the target (unless there is also a recent mouse or touch event),\n  // in which case leave recentFocusFrom unchanged to maintain correct recentFocusFrom after switching apps/windows/tabs/etc,\n  // if/when the focus event is passed into eventFrom later in the cycle, just return recentFocusFrom.\n  // for tracking recent window focus, set window focus capture event listener,\n  // if the target is window (or document on firefox), then track recentWindowFocus with setTimeout 300\n  let recentWindowFocusTimeoutId;\n  const handleWindowFocusEvent = e => {\n    if (e.target === window || e.target === document) {\n      recentWindowFocus = true;\n      window.clearTimeout(recentWindowFocusTimeoutId);\n      recentWindowFocusTimeoutId = window.setTimeout(() => {\n        recentWindowFocus = false;\n      }, 300);\n    }\n  };\n  const handleDocumentFocusEvent = () => {\n    if (!recentWindowFocus || recentMouse || recentTouch) {\n      recentFocusFrom = recentEventFrom;\n    }\n  };\n  const listenerOptions = {\n    capture: true,\n    passive: true\n  };\n  const documentListeners = [[\"touchstart\", handleTouchEvent(750)], [\"touchend\", handleTouchEvent(300)], [\"touchcancel\", handleTouchEvent(300)], [\"pointerenter\", handlePointerEvent(300)], [\"pointerover\", handlePointerEvent(300)], [\"pointerout\", handlePointerEvent(300)], [\"pointerleave\", handlePointerEvent(300)], [\"pointerdown\", handlePointerEvent(750)], [\"pointerup\", handlePointerEvent(300)], [\"pointercancel\", handlePointerEvent(300)], [\"mouseenter\", handleMouseEvent], [\"mouseover\", handleMouseEvent], [\"mouseout\", handleMouseEvent], [\"mouseleave\", handleMouseEvent], [\"mousedown\", handleMouseEvent], [\"mouseup\", handleMouseEvent], [\"keydown\", handleKeyEvent], [\"keyup\", handleKeyEvent], [\"focus\", handleDocumentFocusEvent]];\n  if (typeof window !== \"undefined\" && typeof document !== \"undefined\") {\n    documentListeners.forEach(_ref => {\n      let [eventName, eventHandler] = _ref;\n      // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n      // @ts-ignore not sure how to get TS to match the handler type to the specific eventName\n      document.addEventListener(eventName, eventHandler, listenerOptions);\n    });\n    window.addEventListener(\"focus\", handleWindowFocusEvent, listenerOptions);\n  }\n  // temporarily set the return value for eventFrom(e)\n  // note that the eventFrom(e) value will change when new events come in\n  // useful when manually generating events, e.g. el.focus() or el.click()\n  // and you want eventFrom(e) to treat that event as occurring from a specific input\n  const setEventFrom = value => {\n    if (process.env.NODE_ENV !== \"production\") {\n      if (value !== \"mouse\" && value !== \"touch\" && value !== \"key\") {\n        throw Error(`setEventFrom function requires argument of \"mouse\" | \"touch\" | \"key\", argument received: ${value}`);\n      }\n    }\n    if (value === \"mouse\" || value === \"touch\" || value === \"key\") {\n      recentEventFrom = value;\n      recentFocusFrom = value;\n    }\n  };\n  // use any instead of unknown b/c unknown causes type error when passing a react synthetic event\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  _exports.setEventFrom = setEventFrom;\n  const eventFrom = event => {\n    // use the incoming event to help determine recentEventFrom\n    // in the same manner as the document event listeners\n    // this helps catch edge cases especially when a move event is passed to eventFrom\n    // because move event listeners are not set by Event From\n    switch (event.pointerType) {\n      case \"mouse\":\n        setRecentEventFromMouse();\n        break;\n      case \"pen\":\n      case \"touch\":\n        if (!recentTouch) {\n          setRecentEventFromTouch(300);\n        } else {\n          recentEventFrom = \"touch\";\n        }\n        break;\n    }\n    if (/mouse/.test(event.type) && !recentTouch) {\n      setRecentEventFromMouse();\n    }\n    if (/touch/.test(event.type)) {\n      if (!recentTouch) {\n        setRecentEventFromTouch(300);\n      } else {\n        recentEventFrom = \"touch\";\n      }\n    }\n    // focus events return recentFocusFrom, see recentFocusFrom tracking note above\n    if (/focus/.test(event.type)) {\n      return recentFocusFrom;\n    }\n    return recentEventFrom;\n  };\n  // note that edge cases exist for scroll and wheel events where eventFrom will return the wrong input,\n  // to fix this, event-from would need to set a 'wheel' event listener on the document (see below),\n  // but decided not to add it because 'wheel' is a high frequency event (like move events)\n  // and don't currently have a use case for eventFrom(scrollEvent)\n  // to add support:\n  //   document.addEventListener(\n  //     'wheel',\n  //     () => {\n  //       // might need to track wheel event separately and use it just for eventFrom(scroll)\n  //       // because the wheel event is elastic, it continues to fire after the user interaction has finished\n  //       recentEventFrom = 'mouse';\n  //     },\n  //     listenerOptions,\n  //   );\n  _exports.eventFrom = eventFrom;\n});","define(\"discourse/plugins/discourse-tooltips/initializers/attach-hover-event\", [\"exports\", \"discourse/lib/plugin-api\", \"discourse/plugins/discourse-tooltips/mixins/topic-hover-extension\"], function (_exports, _pluginApi, _topicHoverExtension) {\n  \"use strict\";\n\n  Object.defineProperty(_exports, \"__esModule\", {\n    value: true\n  });\n  _exports.default = void 0;\n  0; //eaimeta@70e063a35619d71f0,\"discourse/lib/plugin-api\",0,\"discourse/plugins/discourse-tooltips/mixins/topic-hover-extension\"eaimeta@70e063a35619d71f\n  var _default = {\n    name: \"attach-hover-event\",\n    initialize() {\n      (0, _pluginApi.withPluginApi)(\"0.8.9\", api => {\n        api.modifyClass(\"component:topic-list\", (0, _topicHoverExtension.hoverExtension)(\".raw-topic-link\"));\n        api.modifyClass(\"component:categories-topic-list\", (0, _topicHoverExtension.hoverExtension)(\".main-link a.title\"));\n      });\n    }\n  };\n  _exports.default = _default;\n});","define(\"discourse/plugins/discourse-tooltips/mixins/topic-hover-extension\", [\"exports\", \"discourse/lib/ajax\", \"discourse-common/lib/object\", \"discourse/plugins/discourse-tooltips/discourse/lib/event-from\", \"@ember/runloop\"], function (_exports, _ajax, _object, _eventFrom, _runloop) {\n  \"use strict\";\n\n  Object.defineProperty(_exports, \"__esModule\", {\n    value: true\n  });\n  _exports.hoverExtension = hoverExtension;\n  0; //eaimeta@70e063a35619d71f0,\"discourse/lib/ajax\",0,\"discourse-common/lib/object\",0,\"discourse/plugins/discourse-tooltips/discourse/lib/event-from\",0,\"@ember/runloop\"eaimeta@70e063a35619d71f\n  // How many extra post excerpts to retrieve\n  const READ_AHEAD = 4;\n  let _cached = {};\n  let _promise;\n  let _inside = false;\n  function cleanDom() {\n    $(\".d-tooltip\").remove();\n    _inside = false;\n  }\n  function cancel() {\n    if (_promise) {\n      _promise.abort();\n      _promise = null;\n    }\n    cleanDom();\n  }\n  function renderTooltip($this, text) {\n    $this.after(`<div class='d-tooltip'><div class='d-tooltip-pointer'></div><div class='d-tooltip-content'>${text}</div></div></div>`);\n    let $dTooltip = $(\".d-tooltip\");\n    let tooltipWidth = $dTooltip.outerWidth();\n    let elementWidth = $this.width();\n    let elementHeight = $this.height();\n    let elementPos = $this.position();\n    let elementX = elementPos.left;\n    let y = elementPos.top + elementHeight;\n    let x = elementX + elementWidth / 2 - tooltipWidth / 2;\n\n    // make sure left side of the tooltip is not out of the screen\n    let $mainLink = $this.hasClass(\"main-link\") ? $this : $this.parents(\".main-link\");\n    let mainLinkLeftOffset = $mainLink.offset().left;\n    if (mainLinkLeftOffset + x < 0) {\n      x = elementX;\n    }\n    $dTooltip.css({\n      left: `${x}px`,\n      top: `${y}px`\n    });\n    $dTooltip.fadeIn(200);\n  }\n  let tooltipsRateLimited = false;\n  function hoverExtension(selector) {\n    return {\n      pluginId: \"discourse-tooltips\",\n      didInsertElement() {\n        this._super(...arguments);\n        cancel();\n        $(this.element).on(\"mouseenter.discourse-tooltips\", selector, function (e) {\n          if ((0, _eventFrom.eventFrom)(e) !== \"mouse\") {\n            return;\n          }\n          let $this = $(this);\n          let $parentTopicId = $(e.currentTarget);\n          if (typeof $parentTopicId.attr(\"data-topic-id\") === \"undefined\") {\n            $parentTopicId = $parentTopicId.parents(\"[data-topic-id]\").last();\n          }\n          let topicId = parseInt($parentTopicId.attr(\"data-topic-id\"), 10);\n          if (topicId) {\n            cancel();\n            _inside = true;\n            if (_cached[topicId]) {\n              return renderTooltip($this, _cached[topicId].excerpt);\n            }\n            if (tooltipsRateLimited) {\n              return;\n            }\n            let topicIds = [topicId];\n\n            // Let's actually fetch the next few topic ids too, assuming the user will\n            // mouse over more below\n            let $siblings = $parentTopicId.nextAll(`[data-topic-id]:lt(${READ_AHEAD})`);\n            $siblings.each((idx, s) => {\n              let siblingId = parseInt(s.getAttribute(\"data-topic-id\"), 10);\n              if (!_cached[siblingId]) {\n                topicIds.push(siblingId);\n              }\n            });\n            _promise = (0, _ajax.ajax)(\"/tooltip-previews\", {\n              data: {\n                topic_ids: topicIds\n              },\n              cache: true\n            });\n            _promise.then(r => {\n              if (r && r.excerpts) {\n                (0, _object.deepMerge)(_cached, r.excerpts);\n              }\n              if (_inside) {\n                renderTooltip($this, _cached[topicId].excerpt);\n              }\n            }).catch(event => {\n              const xhr = event.jqXHR;\n              if (xhr && xhr.status === 429) {\n                tooltipsRateLimited = true;\n                let tryAfter = parseInt(xhr.getResponseHeader && xhr.getResponseHeader(\"Retry-After\"), 10) || 0;\n                tryAfter = tryAfter || 0;\n                if (tryAfter < 15) {\n                  tryAfter = 15;\n                }\n                this.rateLimiter = (0, _runloop.later)(this, () => {\n                  tooltipsRateLimited = false;\n                }, tryAfter * 1000);\n              }\n\n              // swallow errors - was probably aborted!\n            });\n          }\n        });\n\n        $(this.element).on(\"mouseleave.discourse-tooltips\", selector, e => {\n          if ((0, _eventFrom.eventFrom)(e) !== \"mouse\") {\n            return;\n          }\n          cleanDom();\n        });\n      },\n      willDestroyElement() {\n        (0, _runloop.cancel)(this.rateLimiter);\n        tooltipsRateLimited = false;\n        this._super(...arguments);\n        cancel();\n        $(this.element).find(selector).off(\"mouseenter.discourse-tooltips, mouseleave.discourse-tooltips\", selector);\n      }\n    };\n  }\n});"],"mappings":"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"}