coupdoeil 1.1.0 → 1.2.0

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 (31) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/README.md +1 -1
  4. data/app/assets/javascripts/coupdoeil.js +154 -53
  5. data/app/assets/javascripts/coupdoeil.min.js +1 -1
  6. data/app/assets/javascripts/coupdoeil.min.js.map +1 -1
  7. data/app/controllers/coupdoeil/popovers_controller.rb +4 -15
  8. data/app/helpers/coupdoeil/application_helper.rb +13 -0
  9. data/app/javascript/coupdoeil/elements/coupdoeil_element.js +41 -1
  10. data/app/javascript/coupdoeil/events/onclick.js +4 -2
  11. data/app/javascript/coupdoeil/events/onmouseover.js +27 -14
  12. data/app/javascript/coupdoeil/popover/attributes.js +6 -2
  13. data/app/javascript/coupdoeil/popover/closing.js +33 -12
  14. data/app/javascript/coupdoeil/popover/config.js +1 -1
  15. data/app/javascript/coupdoeil/popover/lazy_loading.js +36 -0
  16. data/app/javascript/coupdoeil/popover/opening.js +32 -48
  17. data/app/javascript/coupdoeil/popover/options_parser.js +9 -5
  18. data/app/javascript/coupdoeil/popover/utils.js +46 -0
  19. data/app/javascript/coupdoeil/popover.js +11 -0
  20. data/app/models/coupdoeil/popover/lazy_loading.rb +57 -0
  21. data/app/models/coupdoeil/popover/option/loading.rb +1 -1
  22. data/app/models/coupdoeil/popover/option/placement.rb +25 -4
  23. data/app/models/coupdoeil/popover/setup.rb +1 -1
  24. data/app/models/coupdoeil/popover.rb +27 -12
  25. data/app/models/coupdoeil/tag.rb +11 -10
  26. data/lib/coupdoeil/config.rb +7 -0
  27. data/lib/coupdoeil/engine.rb +2 -1
  28. data/lib/coupdoeil/version.rb +1 -1
  29. metadata +6 -8
  30. data/app/javascript/coupdoeil/popover/actions.js +0 -0
  31. data/app/javascript/coupdoeil/popover/state_check.js +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f329a5af0be249fa736d9caa8996bd0e4fccf344edb9b0d4d73882e11f54fa44
4
- data.tar.gz: 625357beec4fa95d14174d7313782764f390b0f1d6124f531be19bc2ad49a7a3
3
+ metadata.gz: 067fc6a0c3e16c460fc8d3a7cce20e4c1077828df4d276f1b53599cc3c8d9561
4
+ data.tar.gz: 776e22b5bab74ea40082e932d806be74a072d5c6f471dfabc18f52d9d4d7f907
5
5
  SHA512:
6
- metadata.gz: 02a44b70b4c7433f1c658398f12b7bb24ddae368ab2f230705a768cfd1a5986189b18d58c1f4def4f39fc1ff0651a84787eba416cffa68cb1f5084dd4332c56b
7
- data.tar.gz: 256162a7854a6614ddb8944b6199ca8bcc9006e936c8988d3f2768bf15974abc8b11d0a75271deddc2fa4a886c4ca6ab13c2f7b3026ac8f008ad3e3ca80fddd6
6
+ metadata.gz: 34bfcaf445cb7c12cd0c4bb230159608227e96d6d3431fd36dd49950199bab18aeb1c529cc20684376757812159867cefdb61860afdbede855b44074cd4ff47d
7
+ data.tar.gz: a9938616c4ddef15eb293891df410cfbd83fa3a6f474cbceef950f36527d4868755e20063b4ad7b838a4328978de0178ce733414aa1112278746d0e6f8311583
data/CHANGELOG.md CHANGED
@@ -2,6 +2,30 @@
2
2
 
3
3
  ### next version
4
4
 
5
+ ### v1.2.0
6
+ - docs: improve documentation (4ca20b7)
7
+ - feat: add dataset syntax (cd73bd4)
8
+ * new syntax using a dataset on any element, without coup-doeil tag [dataset syntax doc](https://coupdoeil.org/options/guides/dataset-syntax.html)
9
+ * coup-doeil tag attributes are now in HTML dataset to unify popover data retrieval
10
+ - refactor: require action_name param in popover controller (a8bf65c)
11
+ - feat: allow array of string for placement option (113295b)
12
+ * Allow string format only for single placement option
13
+ * Deprecate comma separated string of options
14
+ - fix: fix child popovers inconsistent closing behavior (f933d48)
15
+ - refactor: rename cancelCloseRequest to cancelClosingRequest (9e57e3a)
16
+ - refactor: remove popover from current cache when calling closeNow() (92c75bc)
17
+ - fix: fix closeOnHoverNotParentsLater() (e2263c5)
18
+ - fix: remove useless call to 'benchmark' when rendering popover (4997ebf)
19
+ - fix: respond with HTML content-type when requesting popover content (c0576f3)
20
+ - feat: add lazy loading option (51d44f7)
21
+ * Document lazy loading usage on [loading option page](https://coupdoeil.org/options/loading.html)
22
+ * Update [stimulus controller example in documentation](https://coupdoeil.org/case-studies/use-stimulus-and-turbo.html) to handle lazy loading
23
+ * lazy load params to avoid unecessary queries
24
+
25
+ ### v1.1.1
26
+ - fix: fix popover preload after helpers fix/refactoring (cb5ab87)
27
+ - fix: fix other popovers not closing when hovering a popover (c17d7c3)
28
+
5
29
  ### v1.1.0
6
30
  - refactor: remove unused logger (4a39c43)
7
31
  - feat: add ability to configure gem behavior (0b2d085)
data/README.md CHANGED
@@ -78,7 +78,7 @@ While basic popups implementations can be made with simple helpers, data-attribu
78
78
  it tends to get too complex over time and often not handle enough edge-cases to be used everywhere it could improve UX.
79
79
 
80
80
  `Coupdoeil::Popover` offers a way to easily encapsulate and power up popovers rendering logic.
81
- It allows a lot of customization possibilities (see [options](https://coupdoeil.org/opts.html)) and promotes re-usability by using an API similar to
81
+ It allows a lot of customization possibilities (see [options](https://coupdoeil.org/options.html)) and promotes re-usability by using an API similar to
82
82
  parameterized ActionMailer (see [Why does it look like a mailer?](https://coupdoeil.org/architectural-decisions.html#why-does-it-look-like-a-mailer)).
83
83
 
84
84
  This gem also tries to handle all known issues of such popovers, such as
@@ -20,7 +20,7 @@ const POPOVER_SELECTOR = `.${POPOVER_CLASS_NAME}`;
20
20
 
21
21
  const POPOVER_CLOSE_BTN_SELECTOR = "[data-popover-close]";
22
22
 
23
- const CLOSING_DELAY_MS = 75;
23
+ const CLOSING_DELAY_MS = 100;
24
24
 
25
25
  const FETCH_DELAY_MS = 100;
26
26
 
@@ -126,7 +126,8 @@ const popoverOptions = {
126
126
  };
127
127
 
128
128
  function extractOptionsFromElement(coupdoeilElement) {
129
- const optionsInt = coupdoeilElement.popoverController.optionsInt ||= parseOtionsInt(coupdoeilElement);
129
+ const controller = coupdoeilElement.popoverController;
130
+ const optionsInt = controller.optionsInt ||= parseOptionsInt(controller);
130
131
  const options = Object.create(popoverOptions);
131
132
  for (const option of ORDERED_OPTIONS) {
132
133
  options[option] = OPTIONS[option].getter(optionsInt);
@@ -134,22 +135,27 @@ function extractOptionsFromElement(coupdoeilElement) {
134
135
  return options;
135
136
  }
136
137
 
137
- function parseOtionsInt(coupdoeilElement) {
138
- const optionsString = coupdoeilElement.getAttribute("popover-options");
138
+ function parseOptionsInt(controller) {
139
+ const optionsString = getOptions(controller);
139
140
  return parseInt(optionsString, 36);
140
141
  }
141
142
 
142
143
  function extractOptionFromElement(coupdoeilElement, optionName) {
143
- const optionsInt = coupdoeilElement.popoverController.optionsInt ||= parseOtionsInt(coupdoeilElement);
144
+ const controller = coupdoeilElement.popoverController;
145
+ const optionsInt = controller.optionsInt ||= parseOptionsInt(controller);
144
146
  return OPTIONS[optionName].getter(optionsInt);
145
147
  }
146
148
 
147
149
  function getType(controller) {
148
- return controller.coupdoeilElement.getAttribute("popover-type");
150
+ return controller.coupdoeilElement.dataset.popoverType;
149
151
  }
150
152
 
151
153
  function getParams(controller) {
152
- return controller.coupdoeilElement.getAttribute("popover-params");
154
+ return controller.coupdoeilElement.dataset.popoverParams;
155
+ }
156
+
157
+ function getOptions(controller) {
158
+ return controller.coupdoeilElement.dataset.popoverOptions;
153
159
  }
154
160
 
155
161
  function getTrigger(controller) {
@@ -1921,21 +1927,23 @@ function detachFromParent(controller) {
1921
1927
 
1922
1928
  function cancelOpenCloseActions(controller) {
1923
1929
  cancelOpening(controller);
1924
- cancelCloseRequest(controller);
1930
+ cancelClosingRequest(controller);
1925
1931
  }
1926
1932
 
1927
1933
  function cancelOpening(controller) {
1928
1934
  delete controller.coupdoeilElement.openingPopover;
1929
1935
  }
1930
1936
 
1931
- function cancelCloseRequest(controller) {
1932
- clearTimeout(controller.closingRequest);
1933
- controller.closingRequest = null;
1934
- addToCurrents(controller.coupdoeilElement);
1937
+ function cancelClosingRequest(controller) {
1938
+ if (controller.closingRequest) {
1939
+ clearTimeout(controller.closingRequest);
1940
+ controller.closingRequest = null;
1941
+ }
1935
1942
  }
1936
1943
 
1937
1944
  function closeNow(controller, allowAnimation = true) {
1938
1945
  if (controller.closing || controller.isClosed && !controller.coupdoeilElement.openingPopover) return;
1946
+ cancelClosingRequest(controller);
1939
1947
  controller.closing = true;
1940
1948
  cancelOpenCloseActions(controller);
1941
1949
  controller.children.forEach((childController => {
@@ -1943,9 +1951,12 @@ function closeNow(controller, allowAnimation = true) {
1943
1951
  }));
1944
1952
  detachFromParent(controller);
1945
1953
  if (allowAnimation && controller.card && controller.card.dataset.animation) {
1946
- closeWithAnimation(controller);
1954
+ closeWithAnimation(controller).then((() => {
1955
+ removeFromCurrents(controller.coupdoeilElement);
1956
+ }));
1947
1957
  } else {
1948
1958
  closeWithoutAnimation(controller);
1959
+ removeFromCurrents(controller.coupdoeilElement);
1949
1960
  }
1950
1961
  }
1951
1962
 
@@ -1988,17 +1999,28 @@ function closeOnHoverChildrenLater(controller) {
1988
1999
  }));
1989
2000
  }
1990
2001
 
2002
+ function closeOnHoverNotParentsLater(controller) {
2003
+ let topMostParent = controller;
2004
+ while (topMostParent.parent) {
2005
+ topMostParent = topMostParent.parent;
2006
+ }
2007
+ for (const coupdoeilElement of CURRENT_POPOVERS_BY_ID.values()) {
2008
+ if (coupdoeilElement.popoverController.parent !== null || coupdoeilElement.uniqueId === topMostParent.coupdoeilElement.uniqueId || triggeredOnClick(coupdoeilElement.popoverController)) {
2009
+ continue;
2010
+ }
2011
+ closeLater(coupdoeilElement.popoverController);
2012
+ }
2013
+ }
2014
+
1991
2015
  function closeAllNow() {
1992
2016
  for (const coupdoeilElement of CURRENT_POPOVERS_BY_ID.values()) {
1993
2017
  closeNow(coupdoeilElement.popoverController);
1994
- removeFromCurrents(coupdoeilElement);
1995
2018
  }
1996
2019
  }
1997
2020
 
1998
2021
  function clearAll() {
1999
2022
  for (const coupdoeilElement of CURRENT_POPOVERS_BY_ID.values()) {
2000
2023
  clear(coupdoeilElement.popoverController);
2001
- removeFromCurrents(coupdoeilElement);
2002
2024
  }
2003
2025
  }
2004
2026
 
@@ -2006,7 +2028,6 @@ function closeTriggeredOnHoverLater() {
2006
2028
  for (const coupdoeilElement of CURRENT_POPOVERS_BY_ID.values()) {
2007
2029
  if (triggeredOnHover(coupdoeilElement.popoverController)) {
2008
2030
  closeLater(coupdoeilElement.popoverController);
2009
- removeFromCurrents(coupdoeilElement);
2010
2031
  }
2011
2032
  }
2012
2033
  }
@@ -2020,12 +2041,11 @@ function closeTriggeredOnHoverNowUnlessAncestor(controller) {
2020
2041
  for (const coupdoeilElement of CURRENT_POPOVERS_BY_ID.values()) {
2021
2042
  if (coupdoeilElement.uniqueId !== idToSkip && triggeredOnHover(coupdoeilElement.popoverController)) {
2022
2043
  closeNow(coupdoeilElement.popoverController);
2023
- removeFromCurrents(coupdoeilElement);
2024
2044
  }
2025
2045
  }
2026
2046
  }
2027
2047
 
2028
- function fetchPopoverContent(controller) {
2048
+ function fetchPopoverContent(controller, lazy = false) {
2029
2049
  const type = getType(controller);
2030
2050
  const params = getParams(controller);
2031
2051
  const authenticityToken = document.querySelector("meta[name=csrf-token]")?.content;
@@ -2038,7 +2058,8 @@ function fetchPopoverContent(controller) {
2038
2058
  body: JSON.stringify({
2039
2059
  params: params,
2040
2060
  action_name: type,
2041
- authenticity_token: authenticityToken
2061
+ authenticity_token: authenticityToken,
2062
+ lazy: lazy
2042
2063
  })
2043
2064
  };
2044
2065
  return fetch(url, opts).then((response => {
@@ -2049,19 +2070,58 @@ function fetchPopoverContent(controller) {
2049
2070
  }));
2050
2071
  }
2051
2072
 
2073
+ function executeOnNextFrameIfStillOpening(controller, callback) {
2074
+ requestAnimationFrame((() => {
2075
+ const openOrOpening = controller.isOpen || controller.coupdoeilElement.openingPopover;
2076
+ if (controller.card && openOrOpening && !controller.closingRequest) {
2077
+ callback.call();
2078
+ } else {
2079
+ clear(controller);
2080
+ }
2081
+ }));
2082
+ }
2083
+
2084
+ function isElementClosePopoverButton(element) {
2085
+ return element.closest(POPOVER_CLOSE_BTN_SELECTOR) || element.dataset.hasOwnProperty("popoverClose");
2086
+ }
2087
+
2088
+ function isAnyPopoverOpened() {
2089
+ return currentPopoversById().size > 0;
2090
+ }
2091
+
2092
+ const MINIMUM_LAZY_DELAY = 600;
2093
+
2094
+ function lazyLoadPopoverContent(controller, options) {
2095
+ controller.coupdoeilElement.dataset.lazyLoading = "true";
2096
+ const lazyDelay = new Promise((resolve => setTimeout(resolve, MINIMUM_LAZY_DELAY)));
2097
+ fetchPopoverContent(controller).then((async html => {
2098
+ await lazyDelay;
2099
+ setPopoverContentHTML(controller, html);
2100
+ delete controller.coupdoeilElement.dataset.lazyLoading;
2101
+ if (controller.card && !controller.closingRequest) {
2102
+ controller.card.innerHTML = getPopoverContentHTML(controller);
2103
+ executeOnNextFrameIfStillOpening(controller, (() => {
2104
+ positionPopover(controller.coupdoeilElement, controller.card, options);
2105
+ }));
2106
+ }
2107
+ }));
2108
+ }
2109
+
2052
2110
  async function loadPopoverContentHTML(controller, options, delayOptions) {
2053
2111
  return new Promise((resolve => {
2054
2112
  setTimeout((async () => {
2055
- if (!controller.coupdoeilElement.openingPopover) return;
2056
- if (options.cache === false || options.cache && !getPopoverContentHTML(controller)) {
2057
- let html;
2058
- if (options.loading === "preload") {
2059
- html = preloadedContentElement(controller).innerHTML;
2060
- } else {
2061
- html = await fetchPopoverContent(controller);
2062
- }
2063
- setPopoverContentHTML(controller, html);
2113
+ if (!controller.coupdoeilElement.openingPopover) return resolve();
2114
+ if (getPopoverContentHTML(controller) && options.cache) return resolve();
2115
+ let html;
2116
+ if (options.loading === "preload") {
2117
+ html = preloadedContentElement(controller).innerHTML;
2118
+ } else if (options.loading === "lazy") {
2119
+ html = await fetchPopoverContent(controller, options.loading === "lazy");
2120
+ lazyLoadPopoverContent(controller, options);
2121
+ } else if (options.loading === "async") {
2122
+ html = await fetchPopoverContent(controller);
2064
2123
  }
2124
+ setPopoverContentHTML(controller, html);
2065
2125
  resolve();
2066
2126
  }), delayOptions.fetch);
2067
2127
  }));
@@ -2069,7 +2129,7 @@ async function loadPopoverContentHTML(controller, options, delayOptions) {
2069
2129
 
2070
2130
  async function openPopover(controller, {parent: parent, beforeDisplay: beforeDisplay}) {
2071
2131
  if (controller.isOpen) {
2072
- return cancelCloseRequest(controller);
2132
+ return cancelClosingRequest(controller);
2073
2133
  }
2074
2134
  if (parent) {
2075
2135
  controller.parent = parent;
@@ -2088,7 +2148,7 @@ async function openPopover(controller, {parent: parent, beforeDisplay: beforeDis
2088
2148
 
2089
2149
  async function display(controller, options, beforeDisplay) {
2090
2150
  if (controller.isOpen) return;
2091
- cancelCloseRequest(controller);
2151
+ cancelClosingRequest(controller);
2092
2152
  if (controller.card) {
2093
2153
  controller.card.remove();
2094
2154
  }
@@ -2097,14 +2157,14 @@ async function display(controller, options, beforeDisplay) {
2097
2157
  if (options.animation) {
2098
2158
  controller.card.dataset.animation = options.animation;
2099
2159
  }
2100
- executeNextFrameIfStillOpening(controller, (async () => {
2160
+ executeOnNextFrameIfStillOpening(controller, (async () => {
2101
2161
  await positionPopover(controller.coupdoeilElement, controller.card, options);
2102
2162
  if (controller.card === null) {
2103
2163
  return clear(controller);
2104
2164
  }
2105
2165
  controller.card.classList.add("hidden");
2106
2166
  controller.card.style.removeProperty("visibility");
2107
- executeNextFrameIfStillOpening(controller, (async () => {
2167
+ executeOnNextFrameIfStillOpening(controller, (async () => {
2108
2168
  if (beforeDisplay) {
2109
2169
  beforeDisplay(controller);
2110
2170
  }
@@ -2116,16 +2176,6 @@ async function display(controller, options, beforeDisplay) {
2116
2176
  }));
2117
2177
  }
2118
2178
 
2119
- function executeNextFrameIfStillOpening(controller, callback) {
2120
- requestAnimationFrame((() => {
2121
- if (controller.card && controller.coupdoeilElement.openingPopover && !controller.closingRequest) {
2122
- callback.call();
2123
- } else {
2124
- clear(controller);
2125
- }
2126
- }));
2127
- }
2128
-
2129
2179
  function getDelayOptionsForController(controller, options) {
2130
2180
  if (options.openingDelay === false || triggeredOnClick(controller)) {
2131
2181
  return {
@@ -2171,7 +2221,6 @@ class CoupdoeilElement extends HTMLElement {
2171
2221
  if (this.openingPopover || this.popoverController.isOpen || this.disabled) return;
2172
2222
  this.openingPopover = true;
2173
2223
  const parent = this.closest(POPOVER_SELECTOR)?.popoverController;
2174
- addToCurrents(this);
2175
2224
  return openPopover(this.popoverController, {
2176
2225
  parent: parent,
2177
2226
  ...callbacks
@@ -2192,16 +2241,50 @@ class CoupdoeilElement extends HTMLElement {
2192
2241
  }
2193
2242
  }
2194
2243
 
2195
- function isElementClosePopoverButton(element) {
2196
- return element.closest(POPOVER_CLOSE_BTN_SELECTOR) || element.dataset.hasOwnProperty("popoverClose");
2244
+ function upgradeNativeElement(element) {
2245
+ if (element && element.tagName !== "COUP-DOEIL" && !element.customCoupdoeilElement) {
2246
+ element.customCoupdoeilElement = true;
2247
+ element.uniqueId = generateUniqueId();
2248
+ element.popoverController = new PopoverController(element);
2249
+ element.openPopover = function(triggerElement = null, callbacks) {
2250
+ if (this.openingPopover || this.popoverController.isOpen || this.disabled) return;
2251
+ this.openingPopover = true;
2252
+ const parent = this.closest(POPOVER_SELECTOR)?.popoverController;
2253
+ addToCurrents(this);
2254
+ return openPopover(this.popoverController, {
2255
+ parent: parent,
2256
+ ...callbacks
2257
+ });
2258
+ };
2259
+ element.closePopover = function() {
2260
+ closeNow(this.popoverController);
2261
+ };
2262
+ }
2197
2263
  }
2198
2264
 
2199
- function isAnyPopoverOpened() {
2200
- return currentPopoversById().size > 0;
2265
+ function downgradeNativeElement(element, {force: force = false} = {}) {
2266
+ if (element.customCoupdoeilElement || force) {
2267
+ delete element.closePopover;
2268
+ delete element.openPopover;
2269
+ delete element.popoverController;
2270
+ delete element.uniqueId;
2271
+ delete element.customCoupdoeilElement;
2272
+ delete element.dataset.popoverOptions;
2273
+ delete element.dataset.popoverParams;
2274
+ delete element.dataset.popoverType;
2275
+ delete element.dataset.popoverAnimation;
2276
+ delete element.dataset.popoverCache;
2277
+ delete element.dataset.popoverLoading;
2278
+ delete element.dataset.popoverOffset;
2279
+ delete element.dataset.popoverOpeningDelay;
2280
+ delete element.dataset.popoverPlacement;
2281
+ delete element.dataset.popoverTrigger;
2282
+ }
2201
2283
  }
2202
2284
 
2203
2285
  const coupdoeilOnClickEvent = ({target: clickedElement}) => {
2204
- const coupdoeilElement = clickedElement.closest("coup-doeil");
2286
+ const coupdoeilElement = clickedElement.closest("coup-doeil, [data-popover-options]");
2287
+ upgradeNativeElement(coupdoeilElement);
2205
2288
  const popoverElement = clickedElement.closest(POPOVER_SELECTOR);
2206
2289
  if (coupdoeilElement && popoverElement) {
2207
2290
  handleClickedCoupdoeilWithinPopover(coupdoeilElement, popoverElement, clickedElement);
@@ -2249,7 +2332,8 @@ function handleClickOutsideCoupdoeilAndPopover() {
2249
2332
  }
2250
2333
 
2251
2334
  const onMouseOver = ({target: hoveredElement}) => {
2252
- const coupdoeilElement = hoveredElement.closest("coup-doeil");
2335
+ const coupdoeilElement = hoveredElement.closest("coup-doeil, [data-popover-options]");
2336
+ upgradeNativeElement(coupdoeilElement);
2253
2337
  const popoverElement = hoveredElement.closest(POPOVER_SELECTOR);
2254
2338
  if (coupdoeilElement && popoverElement) {
2255
2339
  handleMouseOverCoupdoeilWithinPopover(coupdoeilElement, popoverElement, hoveredElement);
@@ -2268,6 +2352,8 @@ function handleMouseOverCoupdoeilWithinPopover(coupdoeilElement, popoverElement,
2268
2352
  if (notTriggeredOnHover(childPopover)) return;
2269
2353
  if (childPopover.isOpen) {
2270
2354
  closeChildrenNow(childPopover);
2355
+ cancelClosingRequest(childPopover);
2356
+ addToCurrents(childPopover.coupdoeilElement);
2271
2357
  } else {
2272
2358
  closeChildrenNow(parentPopover);
2273
2359
  coupdoeilElement.openPopover(hoveredElement);
@@ -2282,8 +2368,8 @@ function handleMouseOverCoupdoeilOutsidePopover(coupdoeilElement, hoveredElement
2282
2368
  beforeDisplay: closeTriggeredOnHoverNowUnlessAncestor
2283
2369
  });
2284
2370
  } else if (popover.closingRequest) {
2285
- cancelCloseRequest(popover);
2286
- addToCurrents(coupdoeilElement);
2371
+ cancelClosingRequest(popover);
2372
+ addToCurrents(popover.coupdoeilElement);
2287
2373
  }
2288
2374
  }
2289
2375
 
@@ -2296,11 +2382,16 @@ function handleOverOutsideCoupdoeilAndPopover() {
2296
2382
  function handleOverOutsideCoupdoeilButWithinPopover(popoverElement) {
2297
2383
  const popover = popoverElement.popoverController;
2298
2384
  if (popover.closingRequest) {
2299
- cancelCloseRequest(popover);
2300
- addToCurrents(popover.coupdoeilElement);
2385
+ let topMostParent = popover;
2386
+ while (topMostParent) {
2387
+ cancelClosingRequest(topMostParent);
2388
+ addToCurrents(topMostParent.coupdoeilElement);
2389
+ topMostParent = topMostParent.parent;
2390
+ }
2301
2391
  } else if (popover.children.size > 0) {
2302
2392
  closeOnHoverChildrenLater(popover);
2303
2393
  }
2394
+ closeOnHoverNotParentsLater(popover);
2304
2395
  }
2305
2396
 
2306
2397
  document.addEventListener("DOMContentLoaded", (() => {
@@ -2323,3 +2414,13 @@ document.addEventListener("DOMContentLoaded", (() => {
2323
2414
  if (customElements.get("coup-doeil") === undefined) {
2324
2415
  customElements.define("coup-doeil", CoupdoeilElement);
2325
2416
  }
2417
+
2418
+ window.Coupdoeil = {
2419
+ upgradeNativeElement(element) {
2420
+ if (!element.dataset.popoverOptions) {
2421
+ throw "element is missing Coupdoeil popover dataset";
2422
+ }
2423
+ upgradeNativeElement(element);
2424
+ },
2425
+ downgradeNativeElement: downgradeNativeElement
2426
+ };
@@ -1,2 +1,2 @@
1
- class t{constructor(t){this.coupdoeilElement=t,this.card=null,this.children=new Set,this.parent=null,this.closingRequest=null}get isOpen(){return!!this.coupdoeilElement.dataset.popoverOpen}get isClosed(){return!this.isOpen}}const e="coupdoeil--popover",n=`.${e}`,o={animation:{getter:function(t){return l[t>>5&7]}},cache:{getter:function(t){return!(8&~t)}},loading:{getter:function(t){return s[t>>1&3]}},offset:{getter:function(t){const e=Number(BigInt(t)>>BigInt(24));if(0===e)return 0;return function(t){if("number"==typeof t)return t;if(/^(-?\d+\.?\d+)px$/.test(t))return parseFloat(t);if(/^(-?\d*\.?\d+)rem$/.test(t))return parseFloat(t)*parseFloat(getComputedStyle(document.documentElement).fontSize);return 0}(`${1&~e?"":"-"}${e>>12}.${e>>2&1023}${2&~e?"px":"rem"}`)}},openingDelay:{getter:function(t){return 1==(t>>4&1)}},placement:{getter:function(t){const e=t>>8&65535;let n=0,o=null;const i=[];for(;"auto"!==o&&n<16;)o=c[e>>n&15],i.push(o),n+=4;return i}},trigger:{getter:function(t){return r[1&t]}}},i=["trigger","loading","cache","openingDelay","animation","placement","offset"],r=["hover","click"],l=[!1,"slide-in","fade-in","slide-out","custom"],c=["auto","top","top-start","top-end","right","right-start","right-end","bottom","bottom-start","bottom-end","left","left-start","left-end"],s=["async","preload","lazy"];const a={animation:void 0,cache:void 0,loading:void 0,offset:void 0,openingDelay:void 0,placement:void 0,trigger:void 0};function u(t){const e=t.getAttribute("popover-options");return parseInt(e,36)}function f(t){return t.coupdoeilElement.getAttribute("popover-type")}function p(t){return t.coupdoeilElement.getAttribute("popover-params")}function d(t){return function(t,e){const n=t.popoverController.optionsInt||=u(t);return o[e].getter(n)}(t.coupdoeilElement,"trigger")}function m(t){return"click"!==d(t)}function h(t){return"hover"===d(t)}function g(t){return"hover"!==d(t)}function y(t){return t.coupdoeilElement.querySelector(".popover-content")}const v=new Map;function w(t){return y(t)?t.coupdoeilElement.uniqueId:f(t)+p(t)}function x(t){return v.get(w(t))}function b(){v.clear()}const E=["top","right","bottom","left"],C=["start","end"],L=E.reduce(((t,e)=>t.concat(e,e+"-"+C[0],e+"-"+C[1])),[]),P=Math.min,R=Math.max,T=Math.round,O=t=>({x:t,y:t}),A={left:"right",right:"left",bottom:"top",top:"bottom"},D={start:"end",end:"start"};function S(t,e,n){return R(t,P(e,n))}function $(t,e){return"function"==typeof t?t(e):t}function q(t){return t.split("-")[0]}function k(t){return t.split("-")[1]}function F(t){return"x"===t?"y":"x"}function H(t){return"y"===t?"height":"width"}function W(t){return["top","bottom"].includes(q(t))?"y":"x"}function M(t){return F(W(t))}function B(t,e,n){void 0===n&&(n=!1);const o=k(t),i=M(t),r=H(i);let l="x"===i?o===(n?"end":"start")?"right":"left":"start"===o?"bottom":"top";return e.reference[r]>e.floating[r]&&(l=V(l)),[l,V(l)]}function I(t){return t.replace(/start|end/g,(t=>D[t]))}function V(t){return t.replace(/left|right|bottom|top/g,(t=>A[t]))}function N(t){return"number"!=typeof t?function(t){return{top:0,right:0,bottom:0,left:0,...t}}(t):{top:t,right:t,bottom:t,left:t}}function j(t){const{x:e,y:n,width:o,height:i}=t;return{width:o,height:i,top:n,left:e,right:e+o,bottom:n+i,x:e,y:n}}function z(t,e,n){let{reference:o,floating:i}=t;const r=W(e),l=M(e),c=H(l),s=q(e),a="y"===r,u=o.x+o.width/2-i.width/2,f=o.y+o.height/2-i.height/2,p=o[c]/2-i[c]/2;let d;switch(s){case"top":d={x:u,y:o.y-i.height};break;case"bottom":d={x:u,y:o.y+o.height};break;case"right":d={x:o.x+o.width,y:f};break;case"left":d={x:o.x-i.width,y:f};break;default:d={x:o.x,y:o.y}}switch(k(e)){case"start":d[l]-=p*(n&&a?-1:1);break;case"end":d[l]+=p*(n&&a?-1:1)}return d}async function _(t,e){var n;void 0===e&&(e={});const{x:o,y:i,platform:r,rects:l,elements:c,strategy:s}=t,{boundary:a="clippingAncestors",rootBoundary:u="viewport",elementContext:f="floating",altBoundary:p=!1,padding:d=0}=$(e,t),m=N(d),h=c[p?"floating"===f?"reference":"floating":f],g=j(await r.getClippingRect({element:null==(n=await(null==r.isElement?void 0:r.isElement(h)))||n?h:h.contextElement||await(null==r.getDocumentElement?void 0:r.getDocumentElement(c.floating)),boundary:a,rootBoundary:u,strategy:s})),y="floating"===f?{x:o,y:i,width:l.floating.width,height:l.floating.height}:l.reference,v=await(null==r.getOffsetParent?void 0:r.getOffsetParent(c.floating)),w=await(null==r.isElement?void 0:r.isElement(v))&&await(null==r.getScale?void 0:r.getScale(v))||{x:1,y:1},x=j(r.convertOffsetParentRelativeRectToViewportRelativeRect?await r.convertOffsetParentRelativeRectToViewportRelativeRect({elements:c,rect:y,offsetParent:v,strategy:s}):y);return{top:(g.top-x.top+m.top)/w.y,bottom:(x.bottom-g.bottom+m.bottom)/w.y,left:(g.left-x.left+m.left)/w.x,right:(x.right-g.right+m.right)/w.x}}function U(){return"undefined"!=typeof window}function X(t){return G(t)?(t.nodeName||"").toLowerCase():"#document"}function Y(t){var e;return(null==t||null==(e=t.ownerDocument)?void 0:e.defaultView)||window}function J(t){var e;return null==(e=(G(t)?t.ownerDocument:t.document)||window.document)?void 0:e.documentElement}function G(t){return!!U()&&(t instanceof Node||t instanceof Y(t).Node)}function K(t){return!!U()&&(t instanceof Element||t instanceof Y(t).Element)}function Q(t){return!!U()&&(t instanceof HTMLElement||t instanceof Y(t).HTMLElement)}function Z(t){return!(!U()||"undefined"==typeof ShadowRoot)&&(t instanceof ShadowRoot||t instanceof Y(t).ShadowRoot)}function tt(t){const{overflow:e,overflowX:n,overflowY:o,display:i}=lt(t);return/auto|scroll|overlay|hidden|clip/.test(e+o+n)&&!["inline","contents"].includes(i)}function et(t){return["table","td","th"].includes(X(t))}function nt(t){return[":popover-open",":modal"].some((e=>{try{return t.matches(e)}catch(t){return!1}}))}function ot(t){const e=it(),n=K(t)?lt(t):t;return"none"!==n.transform||"none"!==n.perspective||!!n.containerType&&"normal"!==n.containerType||!e&&!!n.backdropFilter&&"none"!==n.backdropFilter||!e&&!!n.filter&&"none"!==n.filter||["transform","perspective","filter"].some((t=>(n.willChange||"").includes(t)))||["paint","layout","strict","content"].some((t=>(n.contain||"").includes(t)))}function it(){return!("undefined"==typeof CSS||!CSS.supports)&&CSS.supports("-webkit-backdrop-filter","none")}function rt(t){return["html","body","#document"].includes(X(t))}function lt(t){return Y(t).getComputedStyle(t)}function ct(t){return K(t)?{scrollLeft:t.scrollLeft,scrollTop:t.scrollTop}:{scrollLeft:t.scrollX,scrollTop:t.scrollY}}function st(t){if("html"===X(t))return t;const e=t.assignedSlot||t.parentNode||Z(t)&&t.host||J(t);return Z(e)?e.host:e}function at(t){const e=st(t);return rt(e)?t.ownerDocument?t.ownerDocument.body:t.body:Q(e)&&tt(e)?e:at(e)}function ut(t,e,n){var o;void 0===e&&(e=[]),void 0===n&&(n=!0);const i=at(t),r=i===(null==(o=t.ownerDocument)?void 0:o.body),l=Y(i);if(r){const t=ft(l);return e.concat(l,l.visualViewport||[],tt(i)?i:[],t&&n?ut(t):[])}return e.concat(i,ut(i,[],n))}function ft(t){return t.parent&&Object.getPrototypeOf(t.parent)?t.frameElement:null}function pt(t){const e=lt(t);let n=parseFloat(e.width)||0,o=parseFloat(e.height)||0;const i=Q(t),r=i?t.offsetWidth:n,l=i?t.offsetHeight:o,c=T(n)!==r||T(o)!==l;return c&&(n=r,o=l),{width:n,height:o,$:c}}function dt(t){return K(t)?t:t.contextElement}function mt(t){const e=dt(t);if(!Q(e))return O(1);const n=e.getBoundingClientRect(),{width:o,height:i,$:r}=pt(e);let l=(r?T(n.width):n.width)/o,c=(r?T(n.height):n.height)/i;return l&&Number.isFinite(l)||(l=1),c&&Number.isFinite(c)||(c=1),{x:l,y:c}}const ht=O(0);function gt(t){const e=Y(t);return it()&&e.visualViewport?{x:e.visualViewport.offsetLeft,y:e.visualViewport.offsetTop}:ht}function yt(t,e,n,o){void 0===e&&(e=!1),void 0===n&&(n=!1);const i=t.getBoundingClientRect(),r=dt(t);let l=O(1);e&&(o?K(o)&&(l=mt(o)):l=mt(t));const c=function(t,e,n){return void 0===e&&(e=!1),!(!n||e&&n!==Y(t))&&e}(r,n,o)?gt(r):O(0);let s=(i.left+c.x)/l.x,a=(i.top+c.y)/l.y,u=i.width/l.x,f=i.height/l.y;if(r){const t=Y(r),e=o&&K(o)?Y(o):o;let n=t,i=ft(n);for(;i&&o&&e!==n;){const t=mt(i),e=i.getBoundingClientRect(),o=lt(i),r=e.left+(i.clientLeft+parseFloat(o.paddingLeft))*t.x,l=e.top+(i.clientTop+parseFloat(o.paddingTop))*t.y;s*=t.x,a*=t.y,u*=t.x,f*=t.y,s+=r,a+=l,n=Y(i),i=ft(n)}}return j({width:u,height:f,x:s,y:a})}function vt(t,e){const n=ct(t).scrollLeft;return e?e.left+n:yt(J(t)).left+n}function wt(t,e,n){void 0===n&&(n=!1);const o=t.getBoundingClientRect();return{x:o.left+e.scrollLeft-(n?0:vt(t,o)),y:o.top+e.scrollTop}}function xt(t,e,n){let o;if("viewport"===e)o=function(t,e){const n=Y(t),o=J(t),i=n.visualViewport;let r=o.clientWidth,l=o.clientHeight,c=0,s=0;if(i){r=i.width,l=i.height;const t=it();(!t||t&&"fixed"===e)&&(c=i.offsetLeft,s=i.offsetTop)}return{width:r,height:l,x:c,y:s}}(t,n);else if("document"===e)o=function(t){const e=J(t),n=ct(t),o=t.ownerDocument.body,i=R(e.scrollWidth,e.clientWidth,o.scrollWidth,o.clientWidth),r=R(e.scrollHeight,e.clientHeight,o.scrollHeight,o.clientHeight);let l=-n.scrollLeft+vt(t);const c=-n.scrollTop;return"rtl"===lt(o).direction&&(l+=R(e.clientWidth,o.clientWidth)-i),{width:i,height:r,x:l,y:c}}(J(t));else if(K(e))o=function(t,e){const n=yt(t,!0,"fixed"===e),o=n.top+t.clientTop,i=n.left+t.clientLeft,r=Q(t)?mt(t):O(1);return{width:t.clientWidth*r.x,height:t.clientHeight*r.y,x:i*r.x,y:o*r.y}}(e,n);else{const n=gt(t);o={x:e.x-n.x,y:e.y-n.y,width:e.width,height:e.height}}return j(o)}function bt(t,e){const n=st(t);return!(n===e||!K(n)||rt(n))&&("fixed"===lt(n).position||bt(n,e))}function Et(t,e,n){const o=Q(e),i=J(e),r="fixed"===n,l=yt(t,!0,r,e);let c={scrollLeft:0,scrollTop:0};const s=O(0);if(o||!o&&!r)if(("body"!==X(e)||tt(i))&&(c=ct(e)),o){const t=yt(e,!0,r,e);s.x=t.x+e.clientLeft,s.y=t.y+e.clientTop}else i&&(s.x=vt(i));const a=!i||o||r?O(0):wt(i,c);return{x:l.left+c.scrollLeft-s.x-a.x,y:l.top+c.scrollTop-s.y-a.y,width:l.width,height:l.height}}function Ct(t){return"static"===lt(t).position}function Lt(t,e){if(!Q(t)||"fixed"===lt(t).position)return null;if(e)return e(t);let n=t.offsetParent;return J(t)===n&&(n=n.ownerDocument.body),n}function Pt(t,e){const n=Y(t);if(nt(t))return n;if(!Q(t)){let e=st(t);for(;e&&!rt(e);){if(K(e)&&!Ct(e))return e;e=st(e)}return n}let o=Lt(t,e);for(;o&&et(o)&&Ct(o);)o=Lt(o,e);return o&&rt(o)&&Ct(o)&&!ot(o)?n:o||function(t){let e=st(t);for(;Q(e)&&!rt(e);){if(ot(e))return e;if(nt(e))return null;e=st(e)}return null}(t)||n}const Rt={convertOffsetParentRelativeRectToViewportRelativeRect:function(t){let{elements:e,rect:n,offsetParent:o,strategy:i}=t;const r="fixed"===i,l=J(o),c=!!e&&nt(e.floating);if(o===l||c&&r)return n;let s={scrollLeft:0,scrollTop:0},a=O(1);const u=O(0),f=Q(o);if((f||!f&&!r)&&(("body"!==X(o)||tt(l))&&(s=ct(o)),Q(o))){const t=yt(o);a=mt(o),u.x=t.x+o.clientLeft,u.y=t.y+o.clientTop}const p=!l||f||r?O(0):wt(l,s,!0);return{width:n.width*a.x,height:n.height*a.y,x:n.x*a.x-s.scrollLeft*a.x+u.x+p.x,y:n.y*a.y-s.scrollTop*a.y+u.y+p.y}},getDocumentElement:J,getClippingRect:function(t){let{element:e,boundary:n,rootBoundary:o,strategy:i}=t;const r=[..."clippingAncestors"===n?nt(e)?[]:function(t,e){const n=e.get(t);if(n)return n;let o=ut(t,[],!1).filter((t=>K(t)&&"body"!==X(t))),i=null;const r="fixed"===lt(t).position;let l=r?st(t):t;for(;K(l)&&!rt(l);){const e=lt(l),n=ot(l);n||"fixed"!==e.position||(i=null),(r?!n&&!i:!n&&"static"===e.position&&i&&["absolute","fixed"].includes(i.position)||tt(l)&&!n&&bt(t,l))?o=o.filter((t=>t!==l)):i=e,l=st(l)}return e.set(t,o),o}(e,this._c):[].concat(n),o],l=r[0],c=r.reduce(((t,n)=>{const o=xt(e,n,i);return t.top=R(o.top,t.top),t.right=P(o.right,t.right),t.bottom=P(o.bottom,t.bottom),t.left=R(o.left,t.left),t}),xt(e,l,i));return{width:c.right-c.left,height:c.bottom-c.top,x:c.left,y:c.top}},getOffsetParent:Pt,getElementRects:async function(t){const e=this.getOffsetParent||Pt,n=this.getDimensions,o=await n(t.floating);return{reference:Et(t.reference,await e(t.floating),t.strategy),floating:{x:0,y:0,width:o.width,height:o.height}}},getClientRects:function(t){return Array.from(t.getClientRects())},getDimensions:function(t){const{width:e,height:n}=pt(t);return{width:e,height:n}},getScale:mt,isElement:K,isRTL:function(t){return"rtl"===lt(t).direction}},Tt=_,Ot=function(t){return void 0===t&&(t=0),{name:"offset",options:t,async fn(e){var n,o;const{x:i,y:r,placement:l,middlewareData:c}=e,s=await async function(t,e){const{placement:n,platform:o,elements:i}=t,r=await(null==o.isRTL?void 0:o.isRTL(i.floating)),l=q(n),c=k(n),s="y"===W(n),a=["left","top"].includes(l)?-1:1,u=r&&s?-1:1,f=$(e,t);let{mainAxis:p,crossAxis:d,alignmentAxis:m}="number"==typeof f?{mainAxis:f,crossAxis:0,alignmentAxis:null}:{mainAxis:f.mainAxis||0,crossAxis:f.crossAxis||0,alignmentAxis:f.alignmentAxis};return c&&"number"==typeof m&&(d="end"===c?-1*m:m),s?{x:d*u,y:p*a}:{x:p*a,y:d*u}}(e,t);return l===(null==(n=c.offset)?void 0:n.placement)&&null!=(o=c.arrow)&&o.alignmentOffset?{}:{x:i+s.x,y:r+s.y,data:{...s,placement:l}}}}},At=function(t){return void 0===t&&(t={}),{name:"autoPlacement",options:t,async fn(e){var n,o,i;const{rects:r,middlewareData:l,placement:c,platform:s,elements:a}=e,{crossAxis:u=!1,alignment:f,allowedPlacements:p=L,autoAlignment:d=!0,...m}=$(t,e),h=void 0!==f||p===L?function(t,e,n){return(t?[...n.filter((e=>k(e)===t)),...n.filter((e=>k(e)!==t))]:n.filter((t=>q(t)===t))).filter((n=>!t||k(n)===t||!!e&&I(n)!==n))}(f||null,d,p):p,g=await _(e,m),y=(null==(n=l.autoPlacement)?void 0:n.index)||0,v=h[y];if(null==v)return{};const w=B(v,r,await(null==s.isRTL?void 0:s.isRTL(a.floating)));if(c!==v)return{reset:{placement:h[0]}};const x=[g[q(v)],g[w[0]],g[w[1]]],b=[...(null==(o=l.autoPlacement)?void 0:o.overflows)||[],{placement:v,overflows:x}],E=h[y+1];if(E)return{data:{index:y+1,overflows:b},reset:{placement:E}};const C=b.map((t=>{const e=k(t.placement);return[t.placement,e&&u?t.overflows.slice(0,2).reduce(((t,e)=>t+e),0):t.overflows[0],t.overflows]})).sort(((t,e)=>t[1]-e[1])),P=(null==(i=C.filter((t=>t[2].slice(0,k(t[0])?2:3).every((t=>t<=0))))[0])?void 0:i[0])||C[0][0];return P!==c?{data:{index:y+1,overflows:b},reset:{placement:P}}:{}}}},Dt=t=>({name:"arrow",options:t,async fn(e){const{x:n,y:o,placement:i,rects:r,platform:l,elements:c,middlewareData:s}=e,{element:a,padding:u=0}=$(t,e)||{};if(null==a)return{};const f=N(u),p={x:n,y:o},d=M(i),m=H(d),h=await l.getDimensions(a),g="y"===d,y=g?"top":"left",v=g?"bottom":"right",w=g?"clientHeight":"clientWidth",x=r.reference[m]+r.reference[d]-p[d]-r.floating[m],b=p[d]-r.reference[d],E=await(null==l.getOffsetParent?void 0:l.getOffsetParent(a));let C=E?E[w]:0;C&&await(null==l.isElement?void 0:l.isElement(E))||(C=c.floating[w]||r.floating[m]);const L=x/2-b/2,R=C/2-h[m]/2-1,T=P(f[y],R),O=P(f[v],R),A=T,D=C-h[m]-O,q=C/2-h[m]/2+L,F=S(A,q,D),W=!s.arrow&&null!=k(i)&&q!==F&&r.reference[m]/2-(q<A?T:O)-h[m]/2<0,B=W?q<A?q-A:q-D:0;return{[d]:p[d]+B,data:{[d]:F,centerOffset:q-F-B,...W&&{alignmentOffset:B}},reset:W}}}),St=(t,e,n)=>{const o=new Map,i={platform:Rt,...n},r={...i.platform,_c:o};return(async(t,e,n)=>{const{placement:o="bottom",strategy:i="absolute",middleware:r=[],platform:l}=n,c=r.filter(Boolean),s=await(null==l.isRTL?void 0:l.isRTL(e));let a=await l.getElementRects({reference:t,floating:e,strategy:i}),{x:u,y:f}=z(a,o,s),p=o,d={},m=0;for(let n=0;n<c.length;n++){const{name:r,fn:h}=c[n],{x:g,y:y,data:v,reset:w}=await h({x:u,y:f,initialPlacement:o,placement:p,strategy:i,middlewareData:d,rects:a,platform:l,elements:{reference:t,floating:e}});u=null!=g?g:u,f=null!=y?y:f,d={...d,[r]:{...d[r],...v}},w&&m<=50&&(m++,"object"==typeof w&&(w.placement&&(p=w.placement),w.rects&&(a=!0===w.rects?await l.getElementRects({reference:t,floating:e,strategy:i}):w.rects),({x:u,y:f}=z(a,p,s))),n=-1)}return{x:u,y:f,placement:p,strategy:i,middlewareData:d}})(t,e,{...i,platform:r})};async function $t(t,e,n){let{placement:o,offset:i}=n;const r=o[0],l=e.querySelector("[data-popover-arrow]"),c=[qt(o)];if(l){i+=l.clientWidth,c.push(Dt({element:l}))}c.push(Ot(i));const s=await St(t,e,{placement:r,middleware:c}),{x:a,y:u,placement:f}=s;l&&function(t,e){const n=t.clientWidth,{placement:o,middlewareData:{arrow:i}}=e,r=o.split("-")[0],l=kt[r],{x:c,y:s}=i,{borderWidth:a}=getComputedStyle(t.parentElement);Object.assign(t.style,{left:null!=c?`${c}px`:"",top:null!=s?`${s}px`:"",[l]:`calc(${-n}px + ${a})`})}(l,s),e.dataset.placement=f,Object.assign(e.style,{left:`${a}px`,top:`${u}px`})}const qt=t=>{let e=0;return{name:"autoPlacement",async fn(n){if("auto"===n.placement)return At().fn(n);const{top:o,bottom:i,left:r,right:l}=await Tt(n),c=o>0||i>0||r>0||l>0;return"auto"!==t[e]&&c?(e++,{reset:{placement:t[e]||"auto"}}):c?At().fn(n):{}}}},kt={right:"left",left:"right",top:"bottom",bottom:"top"};async function Ft(t,e,n){const o=e.dataset,i=n?`${n}-${t}`:t;let r=`transition${t.charAt(0).toUpperCase()+t.slice(1)}`;const l=o[r]?o[r].split(" "):[i],c=o[`${r}Start`]?o[`${r}Start`].split(" "):[`${i}-start`],s=o[`${r}End`]?o[`${r}End`].split(" "):[`${i}-end`];Ht(e,l),Ht(e,c),await new Promise((t=>{requestAnimationFrame((()=>{requestAnimationFrame(t)}))})),Wt(e,c),Ht(e,s),await function(t){return new Promise((e=>{const n=getComputedStyle(t).transitionDuration.split(",")[0],o=1e3*Number(n.replace("s",""));setTimeout((()=>{e()}),o)}))}(e),Wt(e,s),Wt(e,l)}function Ht(t,e){t.classList.add(...e)}function Wt(t,e){t.classList.remove(...e)}const Mt=new Map;function Bt(t){Mt.set(t.uniqueId,t)}function It(t){Mt.delete(t.uniqueId)}function Vt(t){!function(t){delete t.coupdoeilElement.openingPopover}(t),Nt(t)}function Nt(t){clearTimeout(t.closingRequest),t.closingRequest=null,Bt(t.coupdoeilElement)}function jt(t,e=!0){t.closing||t.isClosed&&!t.coupdoeilElement.openingPopover||(t.closing=!0,Vt(t),t.children.forEach((t=>{jt(t)})),function(t){t.parent&&(t.parent.children.delete(t),t.parent=null)}(t),e&&t.card&&t.card.dataset.animation?async function(t){await async function(t,e=null){await Ft("leave",t,e),t.classList.add("hidden")}(t.card,"popover"),zt(t)}(t):zt(t))}function zt(t){t.card&&(t.card.remove(),t.card=null),delete t.closing,delete t.coupdoeilElement.dataset.popoverOpen}function _t(t){jt(t,!1)}function Ut(t){Vt(t),t.closingRequest=setTimeout((()=>{jt(t)}),75)}function Xt(t){t.children.forEach((t=>{jt(t)}))}function Yt(){for(const t of Mt.values())jt(t.popoverController),It(t)}function Jt(){for(const t of Mt.values())_t(t.popoverController),It(t)}function Gt(t){let e=t;for(;e.parent;)e=e.parent;const n=e.coupdoeilElement.uniqueId;for(const t of Mt.values())t.uniqueId!==n&&h(t.popoverController)&&(jt(t.popoverController),It(t))}async function Kt(t,e,n){return new Promise((o=>{setTimeout((async()=>{if(t.coupdoeilElement.openingPopover){if(!1===e.cache||e.cache&&!x(t)){let n;n="preload"===e.loading?y(t).innerHTML:await function(t){const e=f(t),n=p(t),o=document.querySelector("meta[name=csrf-token]")?.content,i={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({params:n,action_name:e,authenticity_token:o})};return fetch("/coupdoeil/popover",i).then((t=>{if(t.status>=400)throw"error while fetching popover content";return t.text()}))}(t),function(t,e){v.set(w(t),e)}(t,n)}o()}}),n.fetch)}))}async function Qt(t,{parent:n,beforeDisplay:r}){if(t.isOpen)return Nt(t);n&&(t.parent=n,n.children.add(t));const l=function(t){const e=t.popoverController.optionsInt||=u(t),n=Object.create(a);for(const t of i)n[t]=o[t].getter(e);return n}(t.coupdoeilElement),c=function(t,e){if(!1===e.openingDelay||function(t){return"click"===d(t)}(t))return{fetch:0,opening:0};return{fetch:100,opening:200}}(t,l),s=new Promise((t=>setTimeout(t,c.opening))),f=Kt(t,l,c);await Promise.all([f,s]);const p=t.parent&&(t.parent.isClosed||t.parent.closingRequest);t.coupdoeilElement.openingPopover&&!p&&await async function(t,n,o){if(t.isOpen)return;Nt(t),t.card&&t.card.remove();t.card=function(t,n){const o=document.createElement("div");return o.setAttribute("role","dialog"),o.classList.add(e),o.style.cssText="position: absolute; left: 0; top: 0;",o.innerHTML=x(t),o.popoverController=t,o.coupdoeilElement=t.coupdoeilElement,o.close=function(){this.coupdoeilElement.closePopover()},o.dataset.placement=n.placement,o.style.visibility="hidden",o}(t,n),document.body.appendChild(t.card),n.animation&&(t.card.dataset.animation=n.animation);Zt(t,(async()=>{if(await $t(t.coupdoeilElement,t.card,n),null===t.card)return _t(t);t.card.classList.add("hidden"),t.card.style.removeProperty("visibility"),Zt(t,(async()=>{o&&o(t),Bt(t.coupdoeilElement),delete t.coupdoeilElement.openingPopover,t.coupdoeilElement.dataset.popoverOpen=!0,await async function(t,e=null){t.classList.remove("hidden"),await Ft("enter",t,e)}(t.card,"popover")}))}))}(t,l,r)}function Zt(t,e){requestAnimationFrame((()=>{t.card&&t.coupdoeilElement.openingPopover&&!t.closingRequest?e.call():_t(t)}))}class te extends HTMLElement{constructor(){super(),this.uniqueId=function(){const t=new Uint32Array(1);return window.crypto.getRandomValues(t),t[0]}(),this.popoverController=new t(this)}openPopover(t=null,e){if(this.openingPopover||this.popoverController.isOpen||this.disabled)return;this.openingPopover=!0;const o=this.closest(n)?.popoverController;return Bt(this),Qt(this.popoverController,{parent:o,...e})}closePopover(){jt(this.popoverController)}get disabled(){return!!this.getAttribute("disabled")}set disabled(t){t?this.setAttribute("disabled",!0):this.removeAttribute("disabled")}}function ee(){return Mt.size>0}const ne=({target:t})=>{const e=t.closest("coup-doeil"),o=t.closest(n);e&&o?function(t,e,n){const o=t.popoverController;if(m(o))return;o.isOpen?jt(o):t.openPopover(n)}(e,0,t):e?function(t,e){const n=t.popoverController;if(m(n))return;n.isOpen?jt(n):(Yt(),t.openPopover(e))}(e,t):o?function(t,e){const n=t.popoverController;o=e,o.closest("[data-popover-close]")||o.dataset.hasOwnProperty("popoverClose")?requestAnimationFrame((()=>jt(n))):n.children.size>0&&Xt(n);var o}(o,t):Yt()};const oe=({target:t})=>{const e=t.closest("coup-doeil"),o=t.closest(n);e&&o?function(t,e,n){const o=t.popoverController,i=e.popoverController;if(g(o))return;o.isOpen?Xt(o):(Xt(i),t.openPopover(n))}(e,o,t):e?function(t,e){const n=t.popoverController;if(g(n))return;n.isClosed?t.openPopover(e,{beforeDisplay:Gt}):n.closingRequest&&(Nt(n),Bt(t))}(e,t):o?function(t){const e=t.popoverController;e.closingRequest?(Nt(e),Bt(e.coupdoeilElement)):e.children.size>0&&e.children.forEach((t=>{h(t)&&Ut(t)}))}(o):ee()&&function(){for(const t of Mt.values())h(t.popoverController)&&(Ut(t.popoverController),It(t))}()};document.addEventListener("DOMContentLoaded",(()=>{b(),document.addEventListener("click",ne),document.documentElement.addEventListener("mouseover",oe,{passive:!0}),window.Turbo&&(document.addEventListener("turbo:before-cache",(t=>{Jt()})),document.addEventListener("turbo:load",(t=>{Jt(),b()})))})),void 0===customElements.get("coup-doeil")&&customElements.define("coup-doeil",te);
1
+ class t{constructor(t){this.coupdoeilElement=t,this.card=null,this.children=new Set,this.parent=null,this.closingRequest=null}get isOpen(){return!!this.coupdoeilElement.dataset.popoverOpen}get isClosed(){return!this.isOpen}}const e="coupdoeil--popover",n=`.${e}`,o={animation:{getter:function(t){return l[t>>5&7]}},cache:{getter:function(t){return!(8&~t)}},loading:{getter:function(t){return s[t>>1&3]}},offset:{getter:function(t){const e=Number(BigInt(t)>>BigInt(24));if(0===e)return 0;return function(t){if("number"==typeof t)return t;if(/^(-?\d+\.?\d+)px$/.test(t))return parseFloat(t);if(/^(-?\d*\.?\d+)rem$/.test(t))return parseFloat(t)*parseFloat(getComputedStyle(document.documentElement).fontSize);return 0}(`${1&~e?"":"-"}${e>>12}.${e>>2&1023}${2&~e?"px":"rem"}`)}},openingDelay:{getter:function(t){return 1==(t>>4&1)}},placement:{getter:function(t){const e=t>>8&65535;let n=0,o=null;const r=[];for(;"auto"!==o&&n<16;)o=c[e>>n&15],r.push(o),n+=4;return r}},trigger:{getter:function(t){return i[1&t]}}},r=["trigger","loading","cache","openingDelay","animation","placement","offset"],i=["hover","click"],l=[!1,"slide-in","fade-in","slide-out","custom"],c=["auto","top","top-start","top-end","right","right-start","right-end","bottom","bottom-start","bottom-end","left","left-start","left-end"],s=["async","preload","lazy"];const a={animation:void 0,cache:void 0,loading:void 0,offset:void 0,openingDelay:void 0,placement:void 0,trigger:void 0};function u(t){const e=function(t){return t.coupdoeilElement.dataset.popoverOptions}(t);return parseInt(e,36)}function p(t){return t.coupdoeilElement.dataset.popoverType}function d(t){return t.coupdoeilElement.dataset.popoverParams}function f(t){return function(t,e){const n=t.popoverController,r=n.optionsInt||=u(n);return o[e].getter(r)}(t.coupdoeilElement,"trigger")}function m(t){return"click"===f(t)}function g(t){return"click"!==f(t)}function h(t){return"hover"===f(t)}function v(t){return"hover"!==f(t)}function y(t){return t.coupdoeilElement.querySelector(".popover-content")}const w=new Map;function x(t){return y(t)?t.coupdoeilElement.uniqueId:p(t)+d(t)}function b(t){return w.get(x(t))}function E(t,e){w.set(x(t),e)}function C(){w.clear()}const P=["top","right","bottom","left"],L=["start","end"],T=P.reduce(((t,e)=>t.concat(e,e+"-"+L[0],e+"-"+L[1])),[]),R=Math.min,O=Math.max,D=Math.round,A=t=>({x:t,y:t}),q={left:"right",right:"left",bottom:"top",top:"bottom"},S={start:"end",end:"start"};function $(t,e,n){return O(t,R(e,n))}function I(t,e){return"function"==typeof t?t(e):t}function k(t){return t.split("-")[0]}function F(t){return t.split("-")[1]}function H(t){return"x"===t?"y":"x"}function M(t){return"y"===t?"height":"width"}function W(t){return["top","bottom"].includes(k(t))?"y":"x"}function N(t){return H(W(t))}function B(t,e,n){void 0===n&&(n=!1);const o=F(t),r=N(t),i=M(r);let l="x"===r?o===(n?"end":"start")?"right":"left":"start"===o?"bottom":"top";return e.reference[i]>e.floating[i]&&(l=V(l)),[l,V(l)]}function z(t){return t.replace(/start|end/g,(t=>S[t]))}function V(t){return t.replace(/left|right|bottom|top/g,(t=>q[t]))}function j(t){return"number"!=typeof t?function(t){return{top:0,right:0,bottom:0,left:0,...t}}(t):{top:t,right:t,bottom:t,left:t}}function _(t){const{x:e,y:n,width:o,height:r}=t;return{width:o,height:r,top:n,left:e,right:e+o,bottom:n+r,x:e,y:n}}function U(t,e,n){let{reference:o,floating:r}=t;const i=W(e),l=N(e),c=M(l),s=k(e),a="y"===i,u=o.x+o.width/2-r.width/2,p=o.y+o.height/2-r.height/2,d=o[c]/2-r[c]/2;let f;switch(s){case"top":f={x:u,y:o.y-r.height};break;case"bottom":f={x:u,y:o.y+o.height};break;case"right":f={x:o.x+o.width,y:p};break;case"left":f={x:o.x-r.width,y:p};break;default:f={x:o.x,y:o.y}}switch(F(e)){case"start":f[l]-=d*(n&&a?-1:1);break;case"end":f[l]+=d*(n&&a?-1:1)}return f}async function X(t,e){var n;void 0===e&&(e={});const{x:o,y:r,platform:i,rects:l,elements:c,strategy:s}=t,{boundary:a="clippingAncestors",rootBoundary:u="viewport",elementContext:p="floating",altBoundary:d=!1,padding:f=0}=I(e,t),m=j(f),g=c[d?"floating"===p?"reference":"floating":p],h=_(await i.getClippingRect({element:null==(n=await(null==i.isElement?void 0:i.isElement(g)))||n?g:g.contextElement||await(null==i.getDocumentElement?void 0:i.getDocumentElement(c.floating)),boundary:a,rootBoundary:u,strategy:s})),v="floating"===p?{x:o,y:r,width:l.floating.width,height:l.floating.height}:l.reference,y=await(null==i.getOffsetParent?void 0:i.getOffsetParent(c.floating)),w=await(null==i.isElement?void 0:i.isElement(y))&&await(null==i.getScale?void 0:i.getScale(y))||{x:1,y:1},x=_(i.convertOffsetParentRelativeRectToViewportRelativeRect?await i.convertOffsetParentRelativeRectToViewportRelativeRect({elements:c,rect:v,offsetParent:y,strategy:s}):v);return{top:(h.top-x.top+m.top)/w.y,bottom:(x.bottom-h.bottom+m.bottom)/w.y,left:(h.left-x.left+m.left)/w.x,right:(x.right-h.right+m.right)/w.x}}function Y(){return"undefined"!=typeof window}function J(t){return Q(t)?(t.nodeName||"").toLowerCase():"#document"}function G(t){var e;return(null==t||null==(e=t.ownerDocument)?void 0:e.defaultView)||window}function K(t){var e;return null==(e=(Q(t)?t.ownerDocument:t.document)||window.document)?void 0:e.documentElement}function Q(t){return!!Y()&&(t instanceof Node||t instanceof G(t).Node)}function Z(t){return!!Y()&&(t instanceof Element||t instanceof G(t).Element)}function tt(t){return!!Y()&&(t instanceof HTMLElement||t instanceof G(t).HTMLElement)}function et(t){return!(!Y()||"undefined"==typeof ShadowRoot)&&(t instanceof ShadowRoot||t instanceof G(t).ShadowRoot)}function nt(t){const{overflow:e,overflowX:n,overflowY:o,display:r}=st(t);return/auto|scroll|overlay|hidden|clip/.test(e+o+n)&&!["inline","contents"].includes(r)}function ot(t){return["table","td","th"].includes(J(t))}function rt(t){return[":popover-open",":modal"].some((e=>{try{return t.matches(e)}catch(t){return!1}}))}function it(t){const e=lt(),n=Z(t)?st(t):t;return"none"!==n.transform||"none"!==n.perspective||!!n.containerType&&"normal"!==n.containerType||!e&&!!n.backdropFilter&&"none"!==n.backdropFilter||!e&&!!n.filter&&"none"!==n.filter||["transform","perspective","filter"].some((t=>(n.willChange||"").includes(t)))||["paint","layout","strict","content"].some((t=>(n.contain||"").includes(t)))}function lt(){return!("undefined"==typeof CSS||!CSS.supports)&&CSS.supports("-webkit-backdrop-filter","none")}function ct(t){return["html","body","#document"].includes(J(t))}function st(t){return G(t).getComputedStyle(t)}function at(t){return Z(t)?{scrollLeft:t.scrollLeft,scrollTop:t.scrollTop}:{scrollLeft:t.scrollX,scrollTop:t.scrollY}}function ut(t){if("html"===J(t))return t;const e=t.assignedSlot||t.parentNode||et(t)&&t.host||K(t);return et(e)?e.host:e}function pt(t){const e=ut(t);return ct(e)?t.ownerDocument?t.ownerDocument.body:t.body:tt(e)&&nt(e)?e:pt(e)}function dt(t,e,n){var o;void 0===e&&(e=[]),void 0===n&&(n=!0);const r=pt(t),i=r===(null==(o=t.ownerDocument)?void 0:o.body),l=G(r);if(i){const t=ft(l);return e.concat(l,l.visualViewport||[],nt(r)?r:[],t&&n?dt(t):[])}return e.concat(r,dt(r,[],n))}function ft(t){return t.parent&&Object.getPrototypeOf(t.parent)?t.frameElement:null}function mt(t){const e=st(t);let n=parseFloat(e.width)||0,o=parseFloat(e.height)||0;const r=tt(t),i=r?t.offsetWidth:n,l=r?t.offsetHeight:o,c=D(n)!==i||D(o)!==l;return c&&(n=i,o=l),{width:n,height:o,$:c}}function gt(t){return Z(t)?t:t.contextElement}function ht(t){const e=gt(t);if(!tt(e))return A(1);const n=e.getBoundingClientRect(),{width:o,height:r,$:i}=mt(e);let l=(i?D(n.width):n.width)/o,c=(i?D(n.height):n.height)/r;return l&&Number.isFinite(l)||(l=1),c&&Number.isFinite(c)||(c=1),{x:l,y:c}}const vt=A(0);function yt(t){const e=G(t);return lt()&&e.visualViewport?{x:e.visualViewport.offsetLeft,y:e.visualViewport.offsetTop}:vt}function wt(t,e,n,o){void 0===e&&(e=!1),void 0===n&&(n=!1);const r=t.getBoundingClientRect(),i=gt(t);let l=A(1);e&&(o?Z(o)&&(l=ht(o)):l=ht(t));const c=function(t,e,n){return void 0===e&&(e=!1),!(!n||e&&n!==G(t))&&e}(i,n,o)?yt(i):A(0);let s=(r.left+c.x)/l.x,a=(r.top+c.y)/l.y,u=r.width/l.x,p=r.height/l.y;if(i){const t=G(i),e=o&&Z(o)?G(o):o;let n=t,r=ft(n);for(;r&&o&&e!==n;){const t=ht(r),e=r.getBoundingClientRect(),o=st(r),i=e.left+(r.clientLeft+parseFloat(o.paddingLeft))*t.x,l=e.top+(r.clientTop+parseFloat(o.paddingTop))*t.y;s*=t.x,a*=t.y,u*=t.x,p*=t.y,s+=i,a+=l,n=G(r),r=ft(n)}}return _({width:u,height:p,x:s,y:a})}function xt(t,e){const n=at(t).scrollLeft;return e?e.left+n:wt(K(t)).left+n}function bt(t,e,n){void 0===n&&(n=!1);const o=t.getBoundingClientRect();return{x:o.left+e.scrollLeft-(n?0:xt(t,o)),y:o.top+e.scrollTop}}function Et(t,e,n){let o;if("viewport"===e)o=function(t,e){const n=G(t),o=K(t),r=n.visualViewport;let i=o.clientWidth,l=o.clientHeight,c=0,s=0;if(r){i=r.width,l=r.height;const t=lt();(!t||t&&"fixed"===e)&&(c=r.offsetLeft,s=r.offsetTop)}return{width:i,height:l,x:c,y:s}}(t,n);else if("document"===e)o=function(t){const e=K(t),n=at(t),o=t.ownerDocument.body,r=O(e.scrollWidth,e.clientWidth,o.scrollWidth,o.clientWidth),i=O(e.scrollHeight,e.clientHeight,o.scrollHeight,o.clientHeight);let l=-n.scrollLeft+xt(t);const c=-n.scrollTop;return"rtl"===st(o).direction&&(l+=O(e.clientWidth,o.clientWidth)-r),{width:r,height:i,x:l,y:c}}(K(t));else if(Z(e))o=function(t,e){const n=wt(t,!0,"fixed"===e),o=n.top+t.clientTop,r=n.left+t.clientLeft,i=tt(t)?ht(t):A(1);return{width:t.clientWidth*i.x,height:t.clientHeight*i.y,x:r*i.x,y:o*i.y}}(e,n);else{const n=yt(t);o={x:e.x-n.x,y:e.y-n.y,width:e.width,height:e.height}}return _(o)}function Ct(t,e){const n=ut(t);return!(n===e||!Z(n)||ct(n))&&("fixed"===st(n).position||Ct(n,e))}function Pt(t,e,n){const o=tt(e),r=K(e),i="fixed"===n,l=wt(t,!0,i,e);let c={scrollLeft:0,scrollTop:0};const s=A(0);if(o||!o&&!i)if(("body"!==J(e)||nt(r))&&(c=at(e)),o){const t=wt(e,!0,i,e);s.x=t.x+e.clientLeft,s.y=t.y+e.clientTop}else r&&(s.x=xt(r));const a=!r||o||i?A(0):bt(r,c);return{x:l.left+c.scrollLeft-s.x-a.x,y:l.top+c.scrollTop-s.y-a.y,width:l.width,height:l.height}}function Lt(t){return"static"===st(t).position}function Tt(t,e){if(!tt(t)||"fixed"===st(t).position)return null;if(e)return e(t);let n=t.offsetParent;return K(t)===n&&(n=n.ownerDocument.body),n}function Rt(t,e){const n=G(t);if(rt(t))return n;if(!tt(t)){let e=ut(t);for(;e&&!ct(e);){if(Z(e)&&!Lt(e))return e;e=ut(e)}return n}let o=Tt(t,e);for(;o&&ot(o)&&Lt(o);)o=Tt(o,e);return o&&ct(o)&&Lt(o)&&!it(o)?n:o||function(t){let e=ut(t);for(;tt(e)&&!ct(e);){if(it(e))return e;if(rt(e))return null;e=ut(e)}return null}(t)||n}const Ot={convertOffsetParentRelativeRectToViewportRelativeRect:function(t){let{elements:e,rect:n,offsetParent:o,strategy:r}=t;const i="fixed"===r,l=K(o),c=!!e&&rt(e.floating);if(o===l||c&&i)return n;let s={scrollLeft:0,scrollTop:0},a=A(1);const u=A(0),p=tt(o);if((p||!p&&!i)&&(("body"!==J(o)||nt(l))&&(s=at(o)),tt(o))){const t=wt(o);a=ht(o),u.x=t.x+o.clientLeft,u.y=t.y+o.clientTop}const d=!l||p||i?A(0):bt(l,s,!0);return{width:n.width*a.x,height:n.height*a.y,x:n.x*a.x-s.scrollLeft*a.x+u.x+d.x,y:n.y*a.y-s.scrollTop*a.y+u.y+d.y}},getDocumentElement:K,getClippingRect:function(t){let{element:e,boundary:n,rootBoundary:o,strategy:r}=t;const i=[..."clippingAncestors"===n?rt(e)?[]:function(t,e){const n=e.get(t);if(n)return n;let o=dt(t,[],!1).filter((t=>Z(t)&&"body"!==J(t))),r=null;const i="fixed"===st(t).position;let l=i?ut(t):t;for(;Z(l)&&!ct(l);){const e=st(l),n=it(l);n||"fixed"!==e.position||(r=null),(i?!n&&!r:!n&&"static"===e.position&&r&&["absolute","fixed"].includes(r.position)||nt(l)&&!n&&Ct(t,l))?o=o.filter((t=>t!==l)):r=e,l=ut(l)}return e.set(t,o),o}(e,this._c):[].concat(n),o],l=i[0],c=i.reduce(((t,n)=>{const o=Et(e,n,r);return t.top=O(o.top,t.top),t.right=R(o.right,t.right),t.bottom=R(o.bottom,t.bottom),t.left=O(o.left,t.left),t}),Et(e,l,r));return{width:c.right-c.left,height:c.bottom-c.top,x:c.left,y:c.top}},getOffsetParent:Rt,getElementRects:async function(t){const e=this.getOffsetParent||Rt,n=this.getDimensions,o=await n(t.floating);return{reference:Pt(t.reference,await e(t.floating),t.strategy),floating:{x:0,y:0,width:o.width,height:o.height}}},getClientRects:function(t){return Array.from(t.getClientRects())},getDimensions:function(t){const{width:e,height:n}=mt(t);return{width:e,height:n}},getScale:ht,isElement:Z,isRTL:function(t){return"rtl"===st(t).direction}},Dt=X,At=function(t){return void 0===t&&(t=0),{name:"offset",options:t,async fn(e){var n,o;const{x:r,y:i,placement:l,middlewareData:c}=e,s=await async function(t,e){const{placement:n,platform:o,elements:r}=t,i=await(null==o.isRTL?void 0:o.isRTL(r.floating)),l=k(n),c=F(n),s="y"===W(n),a=["left","top"].includes(l)?-1:1,u=i&&s?-1:1,p=I(e,t);let{mainAxis:d,crossAxis:f,alignmentAxis:m}="number"==typeof p?{mainAxis:p,crossAxis:0,alignmentAxis:null}:{mainAxis:p.mainAxis||0,crossAxis:p.crossAxis||0,alignmentAxis:p.alignmentAxis};return c&&"number"==typeof m&&(f="end"===c?-1*m:m),s?{x:f*u,y:d*a}:{x:d*a,y:f*u}}(e,t);return l===(null==(n=c.offset)?void 0:n.placement)&&null!=(o=c.arrow)&&o.alignmentOffset?{}:{x:r+s.x,y:i+s.y,data:{...s,placement:l}}}}},qt=function(t){return void 0===t&&(t={}),{name:"autoPlacement",options:t,async fn(e){var n,o,r;const{rects:i,middlewareData:l,placement:c,platform:s,elements:a}=e,{crossAxis:u=!1,alignment:p,allowedPlacements:d=T,autoAlignment:f=!0,...m}=I(t,e),g=void 0!==p||d===T?function(t,e,n){return(t?[...n.filter((e=>F(e)===t)),...n.filter((e=>F(e)!==t))]:n.filter((t=>k(t)===t))).filter((n=>!t||F(n)===t||!!e&&z(n)!==n))}(p||null,f,d):d,h=await X(e,m),v=(null==(n=l.autoPlacement)?void 0:n.index)||0,y=g[v];if(null==y)return{};const w=B(y,i,await(null==s.isRTL?void 0:s.isRTL(a.floating)));if(c!==y)return{reset:{placement:g[0]}};const x=[h[k(y)],h[w[0]],h[w[1]]],b=[...(null==(o=l.autoPlacement)?void 0:o.overflows)||[],{placement:y,overflows:x}],E=g[v+1];if(E)return{data:{index:v+1,overflows:b},reset:{placement:E}};const C=b.map((t=>{const e=F(t.placement);return[t.placement,e&&u?t.overflows.slice(0,2).reduce(((t,e)=>t+e),0):t.overflows[0],t.overflows]})).sort(((t,e)=>t[1]-e[1])),P=(null==(r=C.filter((t=>t[2].slice(0,F(t[0])?2:3).every((t=>t<=0))))[0])?void 0:r[0])||C[0][0];return P!==c?{data:{index:v+1,overflows:b},reset:{placement:P}}:{}}}},St=t=>({name:"arrow",options:t,async fn(e){const{x:n,y:o,placement:r,rects:i,platform:l,elements:c,middlewareData:s}=e,{element:a,padding:u=0}=I(t,e)||{};if(null==a)return{};const p=j(u),d={x:n,y:o},f=N(r),m=M(f),g=await l.getDimensions(a),h="y"===f,v=h?"top":"left",y=h?"bottom":"right",w=h?"clientHeight":"clientWidth",x=i.reference[m]+i.reference[f]-d[f]-i.floating[m],b=d[f]-i.reference[f],E=await(null==l.getOffsetParent?void 0:l.getOffsetParent(a));let C=E?E[w]:0;C&&await(null==l.isElement?void 0:l.isElement(E))||(C=c.floating[w]||i.floating[m]);const P=x/2-b/2,L=C/2-g[m]/2-1,T=R(p[v],L),O=R(p[y],L),D=T,A=C-g[m]-O,q=C/2-g[m]/2+P,S=$(D,q,A),k=!s.arrow&&null!=F(r)&&q!==S&&i.reference[m]/2-(q<D?T:O)-g[m]/2<0,H=k?q<D?q-D:q-A:0;return{[f]:d[f]+H,data:{[f]:S,centerOffset:q-S-H,...k&&{alignmentOffset:H}},reset:k}}}),$t=(t,e,n)=>{const o=new Map,r={platform:Ot,...n},i={...r.platform,_c:o};return(async(t,e,n)=>{const{placement:o="bottom",strategy:r="absolute",middleware:i=[],platform:l}=n,c=i.filter(Boolean),s=await(null==l.isRTL?void 0:l.isRTL(e));let a=await l.getElementRects({reference:t,floating:e,strategy:r}),{x:u,y:p}=U(a,o,s),d=o,f={},m=0;for(let n=0;n<c.length;n++){const{name:i,fn:g}=c[n],{x:h,y:v,data:y,reset:w}=await g({x:u,y:p,initialPlacement:o,placement:d,strategy:r,middlewareData:f,rects:a,platform:l,elements:{reference:t,floating:e}});u=null!=h?h:u,p=null!=v?v:p,f={...f,[i]:{...f[i],...y}},w&&m<=50&&(m++,"object"==typeof w&&(w.placement&&(d=w.placement),w.rects&&(a=!0===w.rects?await l.getElementRects({reference:t,floating:e,strategy:r}):w.rects),({x:u,y:p}=U(a,d,s))),n=-1)}return{x:u,y:p,placement:d,strategy:r,middlewareData:f}})(t,e,{...r,platform:i})};async function It(t,e,n){let{placement:o,offset:r}=n;const i=o[0],l=e.querySelector("[data-popover-arrow]"),c=[kt(o)];if(l){r+=l.clientWidth,c.push(St({element:l}))}c.push(At(r));const s=await $t(t,e,{placement:i,middleware:c}),{x:a,y:u,placement:p}=s;l&&function(t,e){const n=t.clientWidth,{placement:o,middlewareData:{arrow:r}}=e,i=o.split("-")[0],l=Ft[i],{x:c,y:s}=r,{borderWidth:a}=getComputedStyle(t.parentElement);Object.assign(t.style,{left:null!=c?`${c}px`:"",top:null!=s?`${s}px`:"",[l]:`calc(${-n}px + ${a})`})}(l,s),e.dataset.placement=p,Object.assign(e.style,{left:`${a}px`,top:`${u}px`})}const kt=t=>{let e=0;return{name:"autoPlacement",async fn(n){if("auto"===n.placement)return qt().fn(n);const{top:o,bottom:r,left:i,right:l}=await Dt(n),c=o>0||r>0||i>0||l>0;return"auto"!==t[e]&&c?(e++,{reset:{placement:t[e]||"auto"}}):c?qt().fn(n):{}}}},Ft={right:"left",left:"right",top:"bottom",bottom:"top"};async function Ht(t,e,n){const o=e.dataset,r=n?`${n}-${t}`:t;let i=`transition${t.charAt(0).toUpperCase()+t.slice(1)}`;const l=o[i]?o[i].split(" "):[r],c=o[`${i}Start`]?o[`${i}Start`].split(" "):[`${r}-start`],s=o[`${i}End`]?o[`${i}End`].split(" "):[`${r}-end`];Mt(e,l),Mt(e,c),await new Promise((t=>{requestAnimationFrame((()=>{requestAnimationFrame(t)}))})),Wt(e,c),Mt(e,s),await function(t){return new Promise((e=>{const n=getComputedStyle(t).transitionDuration.split(",")[0],o=1e3*Number(n.replace("s",""));setTimeout((()=>{e()}),o)}))}(e),Wt(e,s),Wt(e,l)}function Mt(t,e){t.classList.add(...e)}function Wt(t,e){t.classList.remove(...e)}const Nt=new Map;function Bt(t){Nt.set(t.uniqueId,t)}function zt(t){Nt.delete(t.uniqueId)}function Vt(t){!function(t){delete t.coupdoeilElement.openingPopover}(t),jt(t)}function jt(t){t.closingRequest&&(clearTimeout(t.closingRequest),t.closingRequest=null)}function _t(t,e=!0){t.closing||t.isClosed&&!t.coupdoeilElement.openingPopover||(jt(t),t.closing=!0,Vt(t),t.children.forEach((t=>{_t(t)})),function(t){t.parent&&(t.parent.children.delete(t),t.parent=null)}(t),e&&t.card&&t.card.dataset.animation?async function(t){await async function(t,e=null){await Ht("leave",t,e),t.classList.add("hidden")}(t.card,"popover"),Ut(t)}(t).then((()=>{zt(t.coupdoeilElement)})):(Ut(t),zt(t.coupdoeilElement)))}function Ut(t){t.card&&(t.card.remove(),t.card=null),delete t.closing,delete t.coupdoeilElement.dataset.popoverOpen}function Xt(t){_t(t,!1)}function Yt(t){Vt(t),t.closingRequest=setTimeout((()=>{_t(t)}),100)}function Jt(t){t.children.forEach((t=>{_t(t)}))}function Gt(){for(const t of Nt.values())_t(t.popoverController)}function Kt(){for(const t of Nt.values())Xt(t.popoverController)}function Qt(t){let e=t;for(;e.parent;)e=e.parent;const n=e.coupdoeilElement.uniqueId;for(const t of Nt.values())t.uniqueId!==n&&h(t.popoverController)&&_t(t.popoverController)}function Zt(t,e=!1){const n=p(t),o=d(t),r=document.querySelector("meta[name=csrf-token]")?.content;const i={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({params:o,action_name:n,authenticity_token:r,lazy:e})};return fetch("/coupdoeil/popover",i).then((t=>{if(t.status>=400)throw"error while fetching popover content";return t.text()}))}function te(t,e){requestAnimationFrame((()=>{const n=t.isOpen||t.coupdoeilElement.openingPopover;t.card&&n&&!t.closingRequest?e.call():Xt(t)}))}function ee(){return Nt.size>0}async function ne(t,e,n){return new Promise((o=>{setTimeout((async()=>{if(!t.coupdoeilElement.openingPopover)return o();if(b(t)&&e.cache)return o();let n;"preload"===e.loading?n=y(t).innerHTML:"lazy"===e.loading?(n=await Zt(t,"lazy"===e.loading),function(t,e){t.coupdoeilElement.dataset.lazyLoading="true";const n=new Promise((t=>setTimeout(t,600)));Zt(t).then((async o=>{await n,E(t,o),delete t.coupdoeilElement.dataset.lazyLoading,t.card&&!t.closingRequest&&(t.card.innerHTML=b(t),te(t,(()=>{It(t.coupdoeilElement,t.card,e)})))}))}(t,e)):"async"===e.loading&&(n=await Zt(t)),E(t,n),o()}),n.fetch)}))}async function oe(t,{parent:n,beforeDisplay:i}){if(t.isOpen)return jt(t);n&&(t.parent=n,n.children.add(t));const l=function(t){const e=t.popoverController,n=e.optionsInt||=u(e),i=Object.create(a);for(const t of r)i[t]=o[t].getter(n);return i}(t.coupdoeilElement),c=function(t,e){if(!1===e.openingDelay||m(t))return{fetch:0,opening:0};return{fetch:100,opening:200}}(t,l),s=new Promise((t=>setTimeout(t,c.opening))),p=ne(t,l,c);await Promise.all([p,s]);const d=t.parent&&(t.parent.isClosed||t.parent.closingRequest);t.coupdoeilElement.openingPopover&&!d&&await async function(t,n,o){if(t.isOpen)return;jt(t),t.card&&t.card.remove();t.card=function(t,n){const o=document.createElement("div");return o.setAttribute("role","dialog"),o.classList.add(e),o.style.cssText="position: absolute; left: 0; top: 0;",o.innerHTML=b(t),o.popoverController=t,o.coupdoeilElement=t.coupdoeilElement,o.close=function(){this.coupdoeilElement.closePopover()},o.dataset.placement=n.placement,o.style.visibility="hidden",o}(t,n),document.body.appendChild(t.card),n.animation&&(t.card.dataset.animation=n.animation);te(t,(async()=>{if(await It(t.coupdoeilElement,t.card,n),null===t.card)return Xt(t);t.card.classList.add("hidden"),t.card.style.removeProperty("visibility"),te(t,(async()=>{o&&o(t),Bt(t.coupdoeilElement),delete t.coupdoeilElement.openingPopover,t.coupdoeilElement.dataset.popoverOpen=!0,await async function(t,e=null){t.classList.remove("hidden"),await Ht("enter",t,e)}(t.card,"popover")}))}))}(t,l,i)}function re(){const t=new Uint32Array(1);return window.crypto.getRandomValues(t),t[0]}class ie extends HTMLElement{constructor(){super(),this.uniqueId=re(),this.popoverController=new t(this)}openPopover(t=null,e){if(this.openingPopover||this.popoverController.isOpen||this.disabled)return;this.openingPopover=!0;const o=this.closest(n)?.popoverController;return oe(this.popoverController,{parent:o,...e})}closePopover(){_t(this.popoverController)}get disabled(){return!!this.getAttribute("disabled")}set disabled(t){t?this.setAttribute("disabled",!0):this.removeAttribute("disabled")}}function le(e){e&&"COUP-DOEIL"!==e.tagName&&!e.customCoupdoeilElement&&(e.customCoupdoeilElement=!0,e.uniqueId=re(),e.popoverController=new t(e),e.openPopover=function(t=null,e){if(this.openingPopover||this.popoverController.isOpen||this.disabled)return;this.openingPopover=!0;const o=this.closest(n)?.popoverController;return Bt(this),oe(this.popoverController,{parent:o,...e})},e.closePopover=function(){_t(this.popoverController)})}const ce=({target:t})=>{const e=t.closest("coup-doeil, [data-popover-options]");le(e);const o=t.closest(n);e&&o?function(t,e,n){const o=t.popoverController;if(g(o))return;o.isOpen?_t(o):t.openPopover(n)}(e,0,t):e?function(t,e){const n=t.popoverController;if(g(n))return;n.isOpen?_t(n):(Gt(),t.openPopover(e))}(e,t):o?function(t,e){const n=t.popoverController;o=e,o.closest("[data-popover-close]")||o.dataset.hasOwnProperty("popoverClose")?requestAnimationFrame((()=>_t(n))):n.children.size>0&&Jt(n);var o}(o,t):Gt()};const se=({target:t})=>{const e=t.closest("coup-doeil, [data-popover-options]");le(e);const o=t.closest(n);e&&o?function(t,e,n){const o=t.popoverController,r=e.popoverController;if(v(o))return;o.isOpen?(Jt(o),jt(o),Bt(o.coupdoeilElement)):(Jt(r),t.openPopover(n))}(e,o,t):e?function(t,e){const n=t.popoverController;if(v(n))return;n.isClosed?t.openPopover(e,{beforeDisplay:Qt}):n.closingRequest&&(jt(n),Bt(n.coupdoeilElement))}(e,t):o?function(t){const e=t.popoverController;if(e.closingRequest){let t=e;for(;t;)jt(t),Bt(t.coupdoeilElement),t=t.parent}else e.children.size>0&&e.children.forEach((t=>{h(t)&&Yt(t)}));!function(t){let e=t;for(;e.parent;)e=e.parent;for(const t of Nt.values())null!==t.popoverController.parent||t.uniqueId===e.coupdoeilElement.uniqueId||m(t.popoverController)||Yt(t.popoverController)}(e)}(o):ee()&&function(){for(const t of Nt.values())h(t.popoverController)&&Yt(t.popoverController)}()};document.addEventListener("DOMContentLoaded",(()=>{C(),document.addEventListener("click",ce),document.documentElement.addEventListener("mouseover",se,{passive:!0}),window.Turbo&&(document.addEventListener("turbo:before-cache",(t=>{Kt()})),document.addEventListener("turbo:load",(t=>{Kt(),C()})))})),void 0===customElements.get("coup-doeil")&&customElements.define("coup-doeil",ie),window.Coupdoeil={upgradeNativeElement(t){if(!t.dataset.popoverOptions)throw"element is missing Coupdoeil popover dataset";le(t)},downgradeNativeElement:function(t,{force:e=!1}={}){(t.customCoupdoeilElement||e)&&(delete t.closePopover,delete t.openPopover,delete t.popoverController,delete t.uniqueId,delete t.customCoupdoeilElement,delete t.dataset.popoverOptions,delete t.dataset.popoverParams,delete t.dataset.popoverType,delete t.dataset.popoverAnimation,delete t.dataset.popoverCache,delete t.dataset.popoverLoading,delete t.dataset.popoverOffset,delete t.dataset.popoverOpeningDelay,delete t.dataset.popoverPlacement,delete t.dataset.popoverTrigger)}};
2
2
  //# sourceMappingURL=coupdoeil.min.js.map