PageSourceSearch

https://cdnweb.fakturoid.cz/assets/javascripts/controllers/tooltip…6f4bc9cd3aaa0e3612796def6c41f442854d1d4d.js

js fakturoid.cz collected 2026-10-03 21:47:01 UTC 3,843 bytes, 143 lines download raw bytes

1import { Controller } from "stimulus"
2import { setDataActions } from "helpers/stimulus_helpers"
3import { computePosition, shift, flip, offset } from "@floating-ui/dom"
4import { arrow } from "@floating-ui/core"
5
6export default class extends Controller {
7  static targets = ["button", "content", "arrow"]
8
9  static values = {
10    showOnHover: { type: Boolean, default: false },
11    timeout: { type: Number, default: 200 },
12    hideTimeout: { type: Number, default: 100 },
13    placement: { type: String, default: "top" }
14  }
15
16  #contentActions = [
17    "toggle->tooltip#toggled"
18  ]
19
20  #repositionActions = [
21    "resize@window->tooltip#reposition",
22    "scroll@window->tooltip#reposition"
23  ]
24
25  #buttonHoverActions = [
26    "mouseenter->tooltip#showAfterDelay",
27    "mouseleave->tooltip#hideAfterDelay",
28    "focus->tooltip#showAfterDelay",
29    "blur->tooltip#hideAfterDelay",
30  ]
31
32  #contentHoverActions = [
33    "mouseenter->tooltip#cancelHide",
34    "mouseleave->tooltip#hideAfterDelay"
35  ]
36
37  #timeout
38  #hideTimeout
39
40  connect() {
41    setDataActions(this.contentTarget, this.#contentActions)
42    if (this.showOnHoverValue) {
43      setDataActions(this.buttonTarget, this.#buttonHoverActions)
44      setDataActions(this.contentTarget, this.#contentHoverActions)
45    }
46  }
47
48  disconnect() {
49    clearTimeout(this.#timeout)
50    clearTimeout(this.#hideTimeout)
51  }
52
53  async toggled(event) {
54    if (event.newState === "open") {
55      await this.#computePosition()
56      this.buttonTarget.setAttribute("aria-describedby", this.contentTarget.id)
57      this.contentTarget.classList.add("is-visible")
58      this.#addRepositionListeners()
59    } else {
60      this.buttonTarget.removeAttribute("aria-describedby")
61      this.contentTarget.classList.remove("is-visible")
62      this.#removeRepositionListeners()
63    }
64  }
65  show() {
66    this.contentTarget.showPopover()
67  }
68
69  showAfterDelay() {
70    clearTimeout(this.#hideTimeout)
71    this.#timeout = setTimeout(() => this.show(), this.timeoutValue)
72  }
73
74  hide() {
75    clearTimeout(this.#timeout)
76    clearTimeout(this.#hideTimeout)
77    this.contentTarget.hidePopover()
78  }
79
80  hideAfterDelay(event) {
81    // Don't hide tooltip when user navigates by keyboard - relatedTarget is inside content element.
82    if (this.contentTarget.contains(event.relatedTarget)) return
83
84    clearTimeout(this.#timeout)
85    clearTimeout(this.#hideTimeout)
86    this.#hideTimeout = setTimeout(() => this.hide(), this.hideTimeoutValue)
87  }
88
89  cancelHide() {
90    clearTimeout(this.#hideTimeout)
91  }
92
93  reposition() {
94    this.#computePosition()
95  }
96
97  #addRepositionListeners() {
98    setDataActions(this.element, this.#repositionActions)
99  }
100
101  #removeRepositionListeners() {
102    setDataActions(this.element, this.#repositionActions, { remove: true })
103  }
104
105  #computePosition() {
106    let middleware = [
107      offset(12),
108      shift({ mainAxis: true }),
109      flip({ crossAxis: 'alignment', fallbackAxisSideDirection: 'end', padding: 10 })
110    ]
111    const content = this.contentTarget
112
113    if (this.hasArrowTarget) middleware.push(arrow({ element: this.arrowTarget }))
114
115    return computePosition(this.buttonTarget, content, {
116      placement: this.placementValue,
117      middleware: middleware,
118    }).then(({ x, y, middlewareData, placement }) => {
119      Object.assign(content.style, {
120        left: `${x}px`,
121        top: `${y}px`,
122      })
123
124      const side = placement.split("-")[0]
125
126      const staticSide = {
127        top: "bottom",
128        right: "left",
129        bottom: "top",
130        left: "right"
131      }[side]
132
133      if (this.hasArrowTarget) {
134        const { x, y } = middlewareData.arrow
135        Object.assign(this.arrowTarget.style, {
136          left: x != null ? `${x}px` : "",
137          top: y != null ? `${y}px` : "",
138          [staticSide]: `${-this.arrowTarget.offsetWidth / 2}px`
139        })
140      }
141    })
142  }
143}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.