@ionic/core 7.6.8-dev.11706715287.1950fa40 → 7.7.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 (346) hide show
  1. package/components/hardware-back-button.js +47 -3
  2. package/components/helpers.js +1 -1
  3. package/components/ion-app.js +12 -2
  4. package/components/ion-menu.js +9 -3
  5. package/components/ion-modal.js +6 -4
  6. package/components/ion-split-pane.js +11 -12
  7. package/components/overlays.js +30 -15
  8. package/dist/cjs/{animation-9b401d39.js → animation-fdab9de5.js} +1 -1
  9. package/dist/cjs/{form-controller-7d42a722.js → form-controller-7b90d7b7.js} +1 -1
  10. package/dist/cjs/{framework-delegate-1c29b14a.js → framework-delegate-a3e6d060.js} +1 -1
  11. package/dist/cjs/{hardware-back-button-76833cac.js → hardware-back-button-d23873bb.js} +48 -2
  12. package/dist/cjs/{helpers-76bb7efb.js → helpers-2e1028fa.js} +1 -1
  13. package/dist/cjs/{index-b4f986cd.js → index-10da82ce.js} +1 -1
  14. package/dist/cjs/{index-da15e99c.js → index-53d162b2.js} +1 -1
  15. package/dist/cjs/{index-fc6d268f.js → index-84351d21.js} +3 -3
  16. package/dist/cjs/{index-8aef188d.js → index-8c679cbf.js} +3 -3
  17. package/dist/cjs/index.cjs.js +9 -9
  18. package/dist/cjs/{input-shims-a23bb0f4.js → input-shims-6f804705.js} +2 -2
  19. package/dist/cjs/{input.utils-3d0166a2.js → input.utils-d693d18a.js} +1 -1
  20. package/dist/cjs/ion-accordion_2.cjs.entry.js +1 -1
  21. package/dist/cjs/ion-action-sheet.cjs.entry.js +5 -5
  22. package/dist/cjs/ion-alert.cjs.entry.js +5 -5
  23. package/dist/cjs/ion-app_8.cjs.entry.js +31 -22
  24. package/dist/cjs/ion-back-button.cjs.entry.js +1 -1
  25. package/dist/cjs/ion-breadcrumb_2.cjs.entry.js +1 -1
  26. package/dist/cjs/ion-button_2.cjs.entry.js +1 -1
  27. package/dist/cjs/ion-card_5.cjs.entry.js +1 -1
  28. package/dist/cjs/ion-checkbox.cjs.entry.js +2 -2
  29. package/dist/cjs/ion-datetime-button.cjs.entry.js +1 -1
  30. package/dist/cjs/ion-datetime_3.cjs.entry.js +5 -5
  31. package/dist/cjs/ion-fab_3.cjs.entry.js +1 -1
  32. package/dist/cjs/ion-img.cjs.entry.js +1 -1
  33. package/dist/cjs/ion-infinite-scroll_2.cjs.entry.js +2 -2
  34. package/dist/cjs/ion-input.cjs.entry.js +4 -4
  35. package/dist/cjs/ion-item-option_3.cjs.entry.js +2 -2
  36. package/dist/cjs/ion-item_8.cjs.entry.js +1 -1
  37. package/dist/cjs/ion-loading.cjs.entry.js +5 -5
  38. package/dist/cjs/ion-menu_3.cjs.entry.js +13 -8
  39. package/dist/cjs/ion-modal.cjs.entry.js +12 -10
  40. package/dist/cjs/ion-nav_2.cjs.entry.js +4 -4
  41. package/dist/cjs/ion-picker-column-internal.cjs.entry.js +1 -1
  42. package/dist/cjs/ion-picker-internal.cjs.entry.js +1 -1
  43. package/dist/cjs/ion-popover.cjs.entry.js +6 -6
  44. package/dist/cjs/ion-progress-bar.cjs.entry.js +1 -1
  45. package/dist/cjs/ion-radio_2.cjs.entry.js +2 -2
  46. package/dist/cjs/ion-range.cjs.entry.js +3 -3
  47. package/dist/cjs/ion-refresher_2.cjs.entry.js +3 -3
  48. package/dist/cjs/ion-reorder_2.cjs.entry.js +2 -2
  49. package/dist/cjs/ion-route_4.cjs.entry.js +1 -1
  50. package/dist/cjs/ion-searchbar.cjs.entry.js +1 -1
  51. package/dist/cjs/ion-segment_2.cjs.entry.js +1 -1
  52. package/dist/cjs/ion-select_3.cjs.entry.js +6 -6
  53. package/dist/cjs/ion-split-pane.cjs.entry.js +11 -12
  54. package/dist/cjs/ion-tab-bar_2.cjs.entry.js +1 -1
  55. package/dist/cjs/ion-tab_2.cjs.entry.js +2 -2
  56. package/dist/cjs/ion-textarea.cjs.entry.js +4 -4
  57. package/dist/cjs/ion-toast.cjs.entry.js +5 -5
  58. package/dist/cjs/ion-toggle.cjs.entry.js +2 -2
  59. package/dist/cjs/ionic.cjs.js +1 -1
  60. package/dist/cjs/{ios.transition-2d1cf0c0.js → ios.transition-8e40c54e.js} +3 -3
  61. package/dist/cjs/loader.cjs.js +1 -1
  62. package/dist/cjs/{md.transition-bb342d2a.js → md.transition-597a2479.js} +3 -3
  63. package/dist/cjs/{notch-controller-9735e7ac.js → notch-controller-db0127c4.js} +1 -1
  64. package/dist/cjs/{overlays-62679ec5.js → overlays-c50bf3c1.js} +32 -16
  65. package/dist/cjs/{status-tap-5fa2bab5.js → status-tap-b0bfea34.js} +2 -2
  66. package/dist/cjs/{swipe-back-2a858bbd.js → swipe-back-8411f044.js} +1 -1
  67. package/dist/collection/components/app/app.js +12 -2
  68. package/dist/collection/components/menu/menu.js +8 -8
  69. package/dist/collection/components/modal/modal.js +6 -4
  70. package/dist/collection/components/split-pane/split-pane.js +11 -12
  71. package/dist/collection/utils/hardware-back-button.js +45 -2
  72. package/dist/collection/utils/helpers.js +1 -1
  73. package/dist/collection/utils/overlays.js +29 -13
  74. package/dist/collection/utils/test/hardware-back-button.spec.js +38 -0
  75. package/dist/docs.json +1 -6
  76. package/dist/esm/{animation-dde8cc0d.js → animation-60dbdd13.js} +1 -1
  77. package/dist/esm/{form-controller-548aa79c.js → form-controller-014aa89f.js} +1 -1
  78. package/dist/esm/{framework-delegate-bc1fd82a.js → framework-delegate-fed7fe7c.js} +1 -1
  79. package/dist/esm/{hardware-back-button-b2bc76db.js → hardware-back-button-f42b9c80.js} +48 -3
  80. package/dist/esm/{helpers-ae653409.js → helpers-c0b9ca37.js} +1 -1
  81. package/dist/esm/{index-6546f0dd.js → index-48209844.js} +3 -3
  82. package/dist/esm/{index-8fac11d0.js → index-4b98143d.js} +3 -3
  83. package/dist/esm/{index-82eeb47f.js → index-d64f34ea.js} +1 -1
  84. package/dist/esm/{index-b9e742e5.js → index-eb12ef92.js} +1 -1
  85. package/dist/esm/index.js +9 -9
  86. package/dist/esm/{input-shims-6539ce13.js → input-shims-b90ca55f.js} +2 -2
  87. package/dist/esm/{input.utils-a5a2d164.js → input.utils-6e9b0046.js} +1 -1
  88. package/dist/esm/ion-accordion_2.entry.js +1 -1
  89. package/dist/esm/ion-action-sheet.entry.js +5 -5
  90. package/dist/esm/ion-alert.entry.js +5 -5
  91. package/dist/esm/ion-app_8.entry.js +21 -12
  92. package/dist/esm/ion-back-button.entry.js +1 -1
  93. package/dist/esm/ion-breadcrumb_2.entry.js +1 -1
  94. package/dist/esm/ion-button_2.entry.js +1 -1
  95. package/dist/esm/ion-card_5.entry.js +1 -1
  96. package/dist/esm/ion-checkbox.entry.js +2 -2
  97. package/dist/esm/ion-datetime-button.entry.js +1 -1
  98. package/dist/esm/ion-datetime_3.entry.js +5 -5
  99. package/dist/esm/ion-fab_3.entry.js +1 -1
  100. package/dist/esm/ion-img.entry.js +1 -1
  101. package/dist/esm/ion-infinite-scroll_2.entry.js +2 -2
  102. package/dist/esm/ion-input.entry.js +4 -4
  103. package/dist/esm/ion-item-option_3.entry.js +2 -2
  104. package/dist/esm/ion-item_8.entry.js +1 -1
  105. package/dist/esm/ion-loading.entry.js +5 -5
  106. package/dist/esm/ion-menu_3.entry.js +13 -8
  107. package/dist/esm/ion-modal.entry.js +12 -10
  108. package/dist/esm/ion-nav_2.entry.js +4 -4
  109. package/dist/esm/ion-picker-column-internal.entry.js +1 -1
  110. package/dist/esm/ion-picker-internal.entry.js +1 -1
  111. package/dist/esm/ion-popover.entry.js +6 -6
  112. package/dist/esm/ion-progress-bar.entry.js +1 -1
  113. package/dist/esm/ion-radio_2.entry.js +2 -2
  114. package/dist/esm/ion-range.entry.js +3 -3
  115. package/dist/esm/ion-refresher_2.entry.js +3 -3
  116. package/dist/esm/ion-reorder_2.entry.js +2 -2
  117. package/dist/esm/ion-route_4.entry.js +1 -1
  118. package/dist/esm/ion-searchbar.entry.js +1 -1
  119. package/dist/esm/ion-segment_2.entry.js +1 -1
  120. package/dist/esm/ion-select_3.entry.js +6 -6
  121. package/dist/esm/ion-split-pane.entry.js +11 -12
  122. package/dist/esm/ion-tab-bar_2.entry.js +1 -1
  123. package/dist/esm/ion-tab_2.entry.js +2 -2
  124. package/dist/esm/ion-textarea.entry.js +4 -4
  125. package/dist/esm/ion-toast.entry.js +5 -5
  126. package/dist/esm/ion-toggle.entry.js +2 -2
  127. package/dist/esm/ionic.js +1 -1
  128. package/dist/esm/{ios.transition-968faaad.js → ios.transition-7ff7381d.js} +3 -3
  129. package/dist/esm/loader.js +1 -1
  130. package/dist/esm/{md.transition-498898ac.js → md.transition-28a9a26b.js} +3 -3
  131. package/dist/esm/{notch-controller-fea7f9c5.js → notch-controller-15d281a4.js} +1 -1
  132. package/dist/esm/{overlays-4bb86b9c.js → overlays-3311e70e.js} +32 -17
  133. package/dist/esm/{status-tap-06b37f21.js → status-tap-2b335fb7.js} +2 -2
  134. package/dist/esm/{swipe-back-a6f386fc.js → swipe-back-c06602f2.js} +1 -1
  135. package/dist/esm-es5/{animation-dde8cc0d.js → animation-60dbdd13.js} +1 -1
  136. package/dist/esm-es5/{form-controller-548aa79c.js → form-controller-014aa89f.js} +1 -1
  137. package/dist/esm-es5/{framework-delegate-bc1fd82a.js → framework-delegate-fed7fe7c.js} +1 -1
  138. package/dist/esm-es5/hardware-back-button-f42b9c80.js +4 -0
  139. package/dist/esm-es5/helpers-c0b9ca37.js +4 -0
  140. package/dist/esm-es5/{index-6546f0dd.js → index-48209844.js} +1 -1
  141. package/dist/esm-es5/{index-8fac11d0.js → index-4b98143d.js} +1 -1
  142. package/dist/esm-es5/index-d64f34ea.js +4 -0
  143. package/dist/esm-es5/{index-b9e742e5.js → index-eb12ef92.js} +1 -1
  144. package/dist/esm-es5/index.js +1 -1
  145. package/dist/esm-es5/{input-shims-6539ce13.js → input-shims-b90ca55f.js} +1 -1
  146. package/dist/esm-es5/{input.utils-a5a2d164.js → input.utils-6e9b0046.js} +1 -1
  147. package/dist/esm-es5/ion-accordion_2.entry.js +1 -1
  148. package/dist/esm-es5/ion-action-sheet.entry.js +1 -1
  149. package/dist/esm-es5/ion-alert.entry.js +1 -1
  150. package/dist/esm-es5/ion-app_8.entry.js +1 -1
  151. package/dist/esm-es5/ion-back-button.entry.js +1 -1
  152. package/dist/esm-es5/ion-breadcrumb_2.entry.js +1 -1
  153. package/dist/esm-es5/ion-button_2.entry.js +1 -1
  154. package/dist/esm-es5/ion-card_5.entry.js +1 -1
  155. package/dist/esm-es5/ion-checkbox.entry.js +1 -1
  156. package/dist/esm-es5/ion-datetime-button.entry.js +1 -1
  157. package/dist/esm-es5/ion-datetime_3.entry.js +1 -1
  158. package/dist/esm-es5/ion-fab_3.entry.js +1 -1
  159. package/dist/esm-es5/ion-img.entry.js +1 -1
  160. package/dist/esm-es5/ion-infinite-scroll_2.entry.js +1 -1
  161. package/dist/esm-es5/ion-input.entry.js +1 -1
  162. package/dist/esm-es5/ion-item-option_3.entry.js +1 -1
  163. package/dist/esm-es5/ion-item_8.entry.js +1 -1
  164. package/dist/esm-es5/ion-loading.entry.js +1 -1
  165. package/dist/esm-es5/ion-menu_3.entry.js +1 -1
  166. package/dist/esm-es5/ion-modal.entry.js +1 -1
  167. package/dist/esm-es5/ion-nav_2.entry.js +1 -1
  168. package/dist/esm-es5/ion-picker-column-internal.entry.js +1 -1
  169. package/dist/esm-es5/ion-picker-internal.entry.js +1 -1
  170. package/dist/esm-es5/ion-popover.entry.js +1 -1
  171. package/dist/esm-es5/ion-progress-bar.entry.js +1 -1
  172. package/dist/esm-es5/ion-radio_2.entry.js +1 -1
  173. package/dist/esm-es5/ion-range.entry.js +1 -1
  174. package/dist/esm-es5/ion-refresher_2.entry.js +1 -1
  175. package/dist/esm-es5/ion-reorder_2.entry.js +1 -1
  176. package/dist/esm-es5/ion-route_4.entry.js +1 -1
  177. package/dist/esm-es5/ion-searchbar.entry.js +1 -1
  178. package/dist/esm-es5/ion-segment_2.entry.js +1 -1
  179. package/dist/esm-es5/ion-select_3.entry.js +1 -1
  180. package/dist/esm-es5/ion-split-pane.entry.js +1 -1
  181. package/dist/esm-es5/ion-tab-bar_2.entry.js +1 -1
  182. package/dist/esm-es5/ion-tab_2.entry.js +1 -1
  183. package/dist/esm-es5/ion-textarea.entry.js +1 -1
  184. package/dist/esm-es5/ion-toast.entry.js +1 -1
  185. package/dist/esm-es5/ion-toggle.entry.js +1 -1
  186. package/dist/esm-es5/ionic.js +1 -1
  187. package/dist/esm-es5/{ios.transition-968faaad.js → ios.transition-7ff7381d.js} +1 -1
  188. package/dist/esm-es5/loader.js +1 -1
  189. package/dist/esm-es5/md.transition-28a9a26b.js +4 -0
  190. package/dist/esm-es5/{notch-controller-fea7f9c5.js → notch-controller-15d281a4.js} +1 -1
  191. package/dist/esm-es5/overlays-3311e70e.js +4 -0
  192. package/dist/esm-es5/{status-tap-06b37f21.js → status-tap-2b335fb7.js} +1 -1
  193. package/dist/esm-es5/{swipe-back-a6f386fc.js → swipe-back-c06602f2.js} +1 -1
  194. package/dist/ionic/index.esm.js +1 -1
  195. package/dist/ionic/ionic.esm.js +1 -1
  196. package/dist/ionic/p-001010b6.system.js +4 -0
  197. package/dist/ionic/{p-f318e213.system.entry.js → p-078fd095.system.entry.js} +1 -1
  198. package/dist/ionic/{p-42f11f58.system.entry.js → p-0ae25399.system.entry.js} +1 -1
  199. package/dist/ionic/p-0b955124.system.js +1 -1
  200. package/dist/ionic/{p-42b4b9a2.system.entry.js → p-0e29919c.system.entry.js} +1 -1
  201. package/dist/ionic/{p-0274f779.system.entry.js → p-0eef8b34.system.entry.js} +1 -1
  202. package/dist/ionic/p-0f1f0519.system.entry.js +4 -0
  203. package/dist/ionic/{p-70684fef.system.entry.js → p-0fd295ef.system.entry.js} +1 -1
  204. package/dist/ionic/{p-9e09d6d3.entry.js → p-108f730a.entry.js} +1 -1
  205. package/dist/ionic/p-1172fd73.system.entry.js +4 -0
  206. package/dist/ionic/{p-b4db67d7.entry.js → p-1c531ca2.entry.js} +1 -1
  207. package/dist/ionic/{p-8642d042.system.entry.js → p-1d72ecba.system.entry.js} +1 -1
  208. package/dist/ionic/{p-3e273305.system.entry.js → p-1f6cdf2c.system.entry.js} +1 -1
  209. package/dist/ionic/{p-99fe3df1.system.entry.js → p-20f7a91e.system.entry.js} +1 -1
  210. package/dist/ionic/{p-487be9e8.system.js → p-25b08bc4.system.js} +1 -1
  211. package/dist/ionic/{p-2f7c7dc9.entry.js → p-2da0a76c.entry.js} +1 -1
  212. package/dist/ionic/{p-ac19cc2f.system.entry.js → p-2e344096.system.entry.js} +1 -1
  213. package/dist/ionic/{p-42dd5fb5.system.entry.js → p-2f66e177.system.entry.js} +1 -1
  214. package/dist/ionic/p-30d77a91.system.js +4 -0
  215. package/dist/ionic/{p-376a6063.js → p-31c495c2.js} +1 -1
  216. package/dist/ionic/p-324dafd3.entry.js +4 -0
  217. package/dist/ionic/{p-cabad15b.system.js → p-37c33319.system.js} +1 -1
  218. package/dist/ionic/{p-c191ba05.system.entry.js → p-389ff4d2.system.entry.js} +1 -1
  219. package/dist/ionic/{p-5d843dac.system.entry.js → p-3a54c070.system.entry.js} +1 -1
  220. package/dist/ionic/{p-5d26143c.entry.js → p-3a98f8db.entry.js} +1 -1
  221. package/dist/ionic/{p-725b4e67.system.js → p-3c6f02cf.system.js} +1 -1
  222. package/dist/ionic/{p-b60b708c.entry.js → p-3cdbaa49.entry.js} +1 -1
  223. package/dist/ionic/p-3eb2da31.js +4 -0
  224. package/dist/ionic/{p-af9ab3f4.entry.js → p-400574bf.entry.js} +1 -1
  225. package/dist/ionic/{p-a3928153.system.entry.js → p-44638413.system.entry.js} +1 -1
  226. package/dist/ionic/{p-ca975c93.entry.js → p-4ae1b532.entry.js} +1 -1
  227. package/dist/ionic/p-4b2d5b9c.js +4 -0
  228. package/dist/ionic/p-4efac4fd.system.js +4 -0
  229. package/dist/ionic/{p-88d5fbd3.js → p-4f777b5e.js} +1 -1
  230. package/dist/ionic/{p-d5824344.system.entry.js → p-50a24d93.system.entry.js} +1 -1
  231. package/dist/ionic/{p-81b652ad.entry.js → p-51f08a9f.entry.js} +1 -1
  232. package/dist/ionic/{p-2b0a2dac.system.entry.js → p-5946d7b8.system.entry.js} +1 -1
  233. package/dist/ionic/{p-0d3e389b.entry.js → p-5a0c301f.entry.js} +1 -1
  234. package/dist/ionic/{p-dbb9820e.entry.js → p-5a7d5f0d.entry.js} +1 -1
  235. package/dist/ionic/p-5b6aa59a.entry.js +4 -0
  236. package/dist/ionic/{p-b853da37.entry.js → p-5e60dbc8.entry.js} +1 -1
  237. package/dist/ionic/{p-bf7f57a7.system.entry.js → p-5f456b3c.system.entry.js} +1 -1
  238. package/dist/ionic/p-61ba2137.system.js +4 -0
  239. package/dist/ionic/{p-408fc801.system.js → p-62a3c609.system.js} +1 -1
  240. package/dist/ionic/{p-ee463529.system.entry.js → p-680f96e8.system.entry.js} +1 -1
  241. package/dist/ionic/p-6871553b.system.js +4 -0
  242. package/dist/ionic/{p-46b0ffa3.system.entry.js → p-6f38d0c5.system.entry.js} +1 -1
  243. package/dist/ionic/{p-03f18e57.system.entry.js → p-70026e8f.system.entry.js} +1 -1
  244. package/dist/ionic/p-776b144b.system.js +4 -0
  245. package/dist/ionic/{p-64520a48.system.entry.js → p-78edc0cd.system.entry.js} +1 -1
  246. package/dist/ionic/{p-41dc24d3.system.entry.js → p-7c32fb95.system.entry.js} +1 -1
  247. package/dist/ionic/{p-4d82a816.system.entry.js → p-84879f61.system.entry.js} +1 -1
  248. package/dist/ionic/{p-57cce147.system.entry.js → p-8569d759.system.entry.js} +1 -1
  249. package/dist/ionic/{p-7e732640.entry.js → p-8a671f16.entry.js} +1 -1
  250. package/dist/ionic/p-8dc4a983.entry.js +4 -0
  251. package/dist/ionic/{p-76d39342.js → p-8ddc00f7.js} +1 -1
  252. package/dist/ionic/{p-b3bf4958.js → p-8f1ce253.js} +1 -1
  253. package/dist/ionic/{p-c44eadec.entry.js → p-90860bc4.entry.js} +1 -1
  254. package/dist/ionic/{p-2f9fe497.system.entry.js → p-92c2178e.system.entry.js} +1 -1
  255. package/dist/ionic/{p-6aacda17.system.entry.js → p-92c7f47f.system.entry.js} +1 -1
  256. package/dist/ionic/{p-29d03b3a.js → p-9393a49f.js} +1 -1
  257. package/dist/ionic/{p-3a75d7fd.js → p-94be3ad7.js} +1 -1
  258. package/dist/ionic/p-95c44e02.system.js +4 -0
  259. package/dist/ionic/{p-0f96cac5.entry.js → p-97eca294.entry.js} +1 -1
  260. package/dist/ionic/{p-195c7203.system.js → p-9c8fb374.system.js} +1 -1
  261. package/dist/ionic/{p-ba0dc6b0.system.entry.js → p-9f5b40c0.system.entry.js} +1 -1
  262. package/dist/ionic/{p-0d197ad6.entry.js → p-9f6397ce.entry.js} +1 -1
  263. package/dist/ionic/{p-4a1eb087.entry.js → p-a02b2d75.entry.js} +1 -1
  264. package/dist/ionic/{p-432353dc.entry.js → p-a19f5ae1.entry.js} +1 -1
  265. package/dist/ionic/{p-18d1b47e.system.entry.js → p-a1bfaa5c.system.entry.js} +1 -1
  266. package/dist/ionic/{p-aad00593.entry.js → p-a2ad515b.entry.js} +1 -1
  267. package/dist/ionic/{p-4180a747.js → p-a3f572a7.js} +1 -1
  268. package/dist/ionic/{p-7b8a53a4.system.entry.js → p-aaa4ffb3.system.entry.js} +1 -1
  269. package/dist/ionic/p-ae40d13d.js +4 -0
  270. package/dist/ionic/{p-66d633fb.js → p-b253ad7f.js} +1 -1
  271. package/dist/ionic/p-b37e4ee5.system.entry.js +4 -0
  272. package/dist/ionic/{p-47bb4958.js → p-b4d8fe47.js} +1 -1
  273. package/dist/ionic/p-b5839dc2.js +4 -0
  274. package/dist/ionic/p-b8c685a7.system.js +4 -0
  275. package/dist/ionic/{p-f57f1a9c.system.entry.js → p-bc2c03d7.system.entry.js} +1 -1
  276. package/dist/ionic/{p-36d187af.js → p-c2289cd1.js} +1 -1
  277. package/dist/ionic/{p-b5914ab2.entry.js → p-c3790581.entry.js} +1 -1
  278. package/dist/ionic/p-c5c3710c.js +4 -0
  279. package/dist/ionic/{p-6ecc011b.system.js → p-c6fef62b.system.js} +1 -1
  280. package/dist/ionic/{p-7798c78a.system.js → p-c80c7e90.system.js} +1 -1
  281. package/dist/ionic/{p-013013a3.js → p-c858f685.js} +1 -1
  282. package/dist/ionic/{p-68a1c901.system.entry.js → p-cd055d60.system.entry.js} +1 -1
  283. package/dist/ionic/{p-6a6477b2.js → p-cdc277a6.js} +1 -1
  284. package/dist/ionic/{p-a6f57a98.entry.js → p-ce2eabd5.entry.js} +1 -1
  285. package/dist/ionic/{p-805a910b.entry.js → p-ce657bb3.entry.js} +1 -1
  286. package/dist/ionic/{p-ee20243d.system.entry.js → p-cfdaf024.system.entry.js} +1 -1
  287. package/dist/ionic/{p-a5954d3d.entry.js → p-d6ca603b.entry.js} +1 -1
  288. package/dist/ionic/{p-f20da312.entry.js → p-d7260b87.entry.js} +1 -1
  289. package/dist/ionic/p-d74ca358.entry.js +4 -0
  290. package/dist/ionic/{p-7288124a.entry.js → p-d95c8e90.entry.js} +1 -1
  291. package/dist/ionic/{p-4eecabe1.entry.js → p-dbb4c012.entry.js} +1 -1
  292. package/dist/ionic/{p-c1d4b820.entry.js → p-dce9bc53.entry.js} +1 -1
  293. package/dist/ionic/{p-0c813cbf.system.entry.js → p-dd60faa5.system.entry.js} +2 -2
  294. package/dist/ionic/{p-3b2ecb7e.entry.js → p-de5c8a55.entry.js} +1 -1
  295. package/dist/ionic/{p-1401bd2e.system.entry.js → p-df281664.system.entry.js} +1 -1
  296. package/dist/ionic/p-df468a8f.entry.js +4 -0
  297. package/dist/ionic/{p-38f2c6bb.system.js → p-e2bb92ed.system.js} +1 -1
  298. package/dist/ionic/{p-364a12ca.system.entry.js → p-e68980ff.system.entry.js} +1 -1
  299. package/dist/ionic/{p-b6e3c96d.system.entry.js → p-e6aaff14.system.entry.js} +1 -1
  300. package/dist/ionic/{p-82e8d988.entry.js → p-ea8fbf09.entry.js} +1 -1
  301. package/dist/ionic/p-efe9180b.entry.js +4 -0
  302. package/dist/ionic/{p-6c938b0d.entry.js → p-f1cc690e.entry.js} +1 -1
  303. package/dist/ionic/p-f46775e4.entry.js +4 -0
  304. package/dist/ionic/{p-a072a420.system.entry.js → p-f7b43141.system.entry.js} +1 -1
  305. package/dist/ionic/p-f85932b8.entry.js +4 -0
  306. package/dist/ionic/{p-7bb1d7dd.entry.js → p-f88dd429.entry.js} +1 -1
  307. package/dist/ionic/p-fd36799d.system.js +4 -0
  308. package/dist/ionic/{p-2a098168.entry.js → p-fd3f475f.entry.js} +1 -1
  309. package/dist/ionic/p-fd8ced99.system.js +4 -0
  310. package/dist/types/utils/browser/index.d.ts +22 -1
  311. package/dist/types/utils/config.d.ts +7 -0
  312. package/dist/types/utils/hardware-back-button.d.ts +13 -0
  313. package/hydrate/index.js +61 -36
  314. package/package.json +2 -2
  315. package/dist/collection/components/modal/test/animations/modal.e2e.js +0 -36
  316. package/dist/esm-es5/hardware-back-button-b2bc76db.js +0 -4
  317. package/dist/esm-es5/helpers-ae653409.js +0 -4
  318. package/dist/esm-es5/index-82eeb47f.js +0 -4
  319. package/dist/esm-es5/md.transition-498898ac.js +0 -4
  320. package/dist/esm-es5/overlays-4bb86b9c.js +0 -4
  321. package/dist/ionic/p-1902859c.system.js +0 -4
  322. package/dist/ionic/p-1b3fb9c6.system.entry.js +0 -4
  323. package/dist/ionic/p-23a9d086.js +0 -4
  324. package/dist/ionic/p-2afd906c.system.entry.js +0 -4
  325. package/dist/ionic/p-2b9debd4.entry.js +0 -4
  326. package/dist/ionic/p-32ad210f.system.js +0 -4
  327. package/dist/ionic/p-35ce400e.system.js +0 -4
  328. package/dist/ionic/p-38c337e7.system.js +0 -4
  329. package/dist/ionic/p-3d9154f0.entry.js +0 -4
  330. package/dist/ionic/p-40f68333.system.js +0 -4
  331. package/dist/ionic/p-4b3623da.js +0 -4
  332. package/dist/ionic/p-562bc465.js +0 -4
  333. package/dist/ionic/p-5ecb46d2.entry.js +0 -4
  334. package/dist/ionic/p-7045f570.entry.js +0 -4
  335. package/dist/ionic/p-70e988e8.js +0 -4
  336. package/dist/ionic/p-74d32574.entry.js +0 -4
  337. package/dist/ionic/p-765b4f12.system.entry.js +0 -4
  338. package/dist/ionic/p-790220fd.system.js +0 -4
  339. package/dist/ionic/p-888db766.system.js +0 -4
  340. package/dist/ionic/p-8bd50516.js +0 -4
  341. package/dist/ionic/p-a9cff22f.entry.js +0 -4
  342. package/dist/ionic/p-baf4a4a2.entry.js +0 -4
  343. package/dist/ionic/p-d2827762.system.js +0 -4
  344. package/dist/ionic/p-de6f8b28.system.js +0 -4
  345. package/dist/ionic/p-f06a7c31.system.js +0 -4
  346. package/dist/ionic/p-fac5d418.entry.js +0 -4
@@ -4,10 +4,10 @@
4
4
  'use strict';
5
5
 
6
6
  const index = require('./index-c8d52405.js');
7
+ const hardwareBackButton = require('./hardware-back-button-d23873bb.js');
7
8
  const ionicGlobal = require('./ionic-global-7358c23e.js');
8
- const frameworkDelegate = require('./framework-delegate-1c29b14a.js');
9
- const hardwareBackButton = require('./hardware-back-button-76833cac.js');
10
- const helpers = require('./helpers-76bb7efb.js');
9
+ const frameworkDelegate = require('./framework-delegate-a3e6d060.js');
10
+ const helpers = require('./helpers-2e1028fa.js');
11
11
  const index$1 = require('./index-5915f9b3.js');
12
12
 
13
13
  let lastOverlayIndex = 0;
@@ -298,19 +298,38 @@ const connectListeners = (doc) => {
298
298
  const lastOverlay = getPresentedOverlay(doc);
299
299
  if (lastOverlay === null || lastOverlay === void 0 ? void 0 : lastOverlay.backdropDismiss) {
300
300
  ev.detail.register(hardwareBackButton.OVERLAY_BACK_BUTTON_PRIORITY, () => {
301
- return lastOverlay.dismiss(undefined, BACKDROP);
301
+ /**
302
+ * Do not return this promise otherwise
303
+ * the hardware back button utility will
304
+ * be blocked until the overlay dismisses.
305
+ * This is important for a modal with canDismiss.
306
+ * If the application presents a confirmation alert
307
+ * in the "canDismiss" callback, then it will be impossible
308
+ * to use the hardware back button to dismiss the alert
309
+ * dialog because the hardware back button utility
310
+ * is blocked on waiting for the modal to dismiss.
311
+ */
312
+ lastOverlay.dismiss(undefined, BACKDROP);
302
313
  });
303
314
  }
304
315
  });
305
- // handle ESC to close overlay
306
- doc.addEventListener('keydown', (ev) => {
307
- if (ev.key === 'Escape') {
308
- const lastOverlay = getPresentedOverlay(doc);
309
- if (lastOverlay === null || lastOverlay === void 0 ? void 0 : lastOverlay.backdropDismiss) {
310
- lastOverlay.dismiss(undefined, BACKDROP);
316
+ /**
317
+ * Handle ESC to close overlay.
318
+ * CloseWatcher also handles pressing the Esc
319
+ * key, so if a browser supports CloseWatcher then
320
+ * this behavior will be handled via the ionBackButton
321
+ * event.
322
+ */
323
+ if (!hardwareBackButton.shoudUseCloseWatcher()) {
324
+ doc.addEventListener('keydown', (ev) => {
325
+ if (ev.key === 'Escape') {
326
+ const lastOverlay = getPresentedOverlay(doc);
327
+ if (lastOverlay === null || lastOverlay === void 0 ? void 0 : lastOverlay.backdropDismiss) {
328
+ lastOverlay.dismiss(undefined, BACKDROP);
329
+ }
311
330
  }
312
- }
313
- });
331
+ });
332
+ }
314
333
  }
315
334
  };
316
335
  const dismissOverlay = (doc, data, role, overlayTag, id) => {
@@ -476,10 +495,6 @@ const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnim
476
495
  }
477
496
  overlay.didDismiss.emit({ data, role });
478
497
  (_b = overlay.didDismissShorthand) === null || _b === void 0 ? void 0 : _b.emit({ data, role });
479
- // Get a reference to all animations currently assigned to this overlay
480
- // Then tear them down to return the overlay to its initial visual state
481
- const animations = activeAnimations.get(overlay) || [];
482
- animations.forEach((ani) => ani.destroy());
483
498
  activeAnimations.delete(overlay);
484
499
  /**
485
500
  * Make overlay hidden again in case it is being reused.
@@ -700,6 +715,7 @@ exports.BACKDROP = BACKDROP;
700
715
  exports.GESTURE = GESTURE;
701
716
  exports.OVERLAY_GESTURE_PRIORITY = OVERLAY_GESTURE_PRIORITY;
702
717
  exports.actionSheetController = actionSheetController;
718
+ exports.activeAnimations = activeAnimations;
703
719
  exports.alertController = alertController;
704
720
  exports.createDelegateController = createDelegateController;
705
721
  exports.createTriggerController = createTriggerController;
@@ -4,8 +4,8 @@
4
4
  'use strict';
5
5
 
6
6
  const index = require('./index-5a471146.js');
7
- const index$1 = require('./index-da15e99c.js');
8
- const helpers = require('./helpers-76bb7efb.js');
7
+ const index$1 = require('./index-53d162b2.js');
8
+ const helpers = require('./helpers-2e1028fa.js');
9
9
  require('./index-5915f9b3.js');
10
10
 
11
11
  const startStatusTap = () => {
@@ -3,7 +3,7 @@
3
3
  */
4
4
  'use strict';
5
5
 
6
- const helpers = require('./helpers-76bb7efb.js');
6
+ const helpers = require('./helpers-2e1028fa.js');
7
7
  const dir = require('./dir-94c21456.js');
8
8
  const index = require('./index-d1b59ffa.js');
9
9
  require('./gesture-controller-c40c045a.js');
@@ -2,6 +2,8 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { Build, Host, h } from "@stencil/core";
5
+ import { shoudUseCloseWatcher } from "../../utils/hardware-back-button";
6
+ import { printIonWarning } from "../../utils/logging/index";
5
7
  import { isPlatform } from "../../utils/platform";
6
8
  import { config } from "../../global/config";
7
9
  import { getIonMode } from "../../global/ionic-global";
@@ -25,10 +27,18 @@ export class App {
25
27
  import('../../utils/input-shims/input-shims').then((module) => module.startInputShims(config, platform));
26
28
  }
27
29
  const hardwareBackButtonModule = await import('../../utils/hardware-back-button');
28
- if (config.getBoolean('hardwareBackButton', isHybrid)) {
30
+ const supportsHardwareBackButtonEvents = isHybrid || shoudUseCloseWatcher();
31
+ if (config.getBoolean('hardwareBackButton', supportsHardwareBackButtonEvents)) {
29
32
  hardwareBackButtonModule.startHardwareBackButton();
30
33
  }
31
34
  else {
35
+ /**
36
+ * If an app sets hardwareBackButton: false and experimentalCloseWatcher: true
37
+ * then the close watcher will not be used.
38
+ */
39
+ if (shoudUseCloseWatcher()) {
40
+ printIonWarning('experimentalCloseWatcher was set to `true`, but hardwareBackButton was set to `false`. Both config options must be `true` for the Close Watcher API to be used.');
41
+ }
32
42
  hardwareBackButtonModule.blockHardwareBackButton();
33
43
  }
34
44
  if (typeof window !== 'undefined') {
@@ -55,7 +65,7 @@ export class App {
55
65
  }
56
66
  render() {
57
67
  const mode = getIonMode(this);
58
- return (h(Host, { key: '56c81f5d59b568ffd4a6de2f9b1c48c9a9456e8b', class: {
68
+ return (h(Host, { key: '3535eb5c0dab78a78011e552524a98599b2b650f', class: {
59
69
  [mode]: true,
60
70
  'ion-page': true,
61
71
  'force-statusbar-padding': config.getBoolean('_forceStatusbarPadding'),
@@ -4,6 +4,7 @@
4
4
  import { Build, Host, h } from "@stencil/core";
5
5
  import { getTimeGivenProgression } from "../../utils/animation/cubic-bezier";
6
6
  import { GESTURE_CONTROLLER } from "../../utils/gesture/index";
7
+ import { shoudUseCloseWatcher } from "../../utils/hardware-back-button";
7
8
  import { inheritAriaAttributes, assert, clamp, isEndSide as isEnd } from "../../utils/helpers";
8
9
  import { menuController } from "../../utils/menu-controller/index";
9
10
  import { getPresentedOverlay } from "../../utils/overlays";
@@ -595,13 +596,18 @@ export class Menu {
595
596
  render() {
596
597
  const { type, disabled, isPaneVisible, inheritedAttributes, side } = this;
597
598
  const mode = getIonMode(this);
598
- return (h(Host, { key: '8665a4cec887bb6b0178d1df62e47c8575104ad1', role: "navigation", "aria-label": inheritedAttributes['aria-label'] || 'menu', class: {
599
+ /**
600
+ * If the Close Watcher is enabled then
601
+ * the ionBackButton listener in the menu controller
602
+ * will handle closing the menu when Escape is pressed.
603
+ */
604
+ return (h(Host, { key: 'be7145625a30951e5cc26646f6121ee4fa4c910f', onKeyDown: shoudUseCloseWatcher() ? null : this.onKeydown, role: "navigation", "aria-label": inheritedAttributes['aria-label'] || 'menu', class: {
599
605
  [mode]: true,
600
606
  [`menu-type-${type}`]: true,
601
607
  'menu-enabled': !disabled,
602
608
  [`menu-side-${side}`]: true,
603
609
  'menu-pane-visible': isPaneVisible,
604
- } }, h("div", { key: '37f5797a28f2809cb979272525ef64074b2c9730', class: "menu-inner", part: "container", ref: (el) => (this.menuInnerEl = el) }, h("slot", { key: '718a506b80373deecb1ea5205384839ac222c74e' })), h("ion-backdrop", { key: 'a499b8f60a8aef2ec125a1814b491e8e1a863825', ref: (el) => (this.backdropEl = el), class: "menu-backdrop", tappable: false, stopPropagation: false, part: "backdrop" })));
610
+ } }, h("div", { key: 'ecd6e0641ed67691db270190801f7be365a2d121', class: "menu-inner", part: "container", ref: (el) => (this.menuInnerEl = el) }, h("slot", { key: 'aea3780e259f2b3ea84697a509bb7f13fa9531e9' })), h("ion-backdrop", { key: 'be3253506a34c4c00eb1814621c674196b72db46', ref: (el) => (this.backdropEl = el), class: "menu-backdrop", tappable: false, stopPropagation: false, part: "backdrop" })));
605
611
  }
606
612
  static get is() { return "ion-menu"; }
607
613
  static get encapsulation() { return "shadow"; }
@@ -998,12 +1004,6 @@ export class Menu {
998
1004
  "target": undefined,
999
1005
  "capture": true,
1000
1006
  "passive": false
1001
- }, {
1002
- "name": "keydown",
1003
- "method": "onKeydown",
1004
- "target": undefined,
1005
- "capture": false,
1006
- "passive": false
1007
1007
  }];
1008
1008
  }
1009
1009
  }
@@ -8,7 +8,7 @@ import { raf, inheritAttributes, hasLazyBuild } from "../../utils/helpers";
8
8
  import { createLockController } from "../../utils/lock-controller";
9
9
  import { printIonWarning } from "../../utils/logging/index";
10
10
  import { Style as StatusBarStyle, StatusBar } from "../../utils/native/status-bar";
11
- import { GESTURE, BACKDROP, dismiss, eventMethod, prepareOverlay, present, createTriggerController, setOverlayId, } from "../../utils/overlays";
11
+ import { GESTURE, BACKDROP, activeAnimations, dismiss, eventMethod, prepareOverlay, present, createTriggerController, setOverlayId, } from "../../utils/overlays";
12
12
  import { getClassMap } from "../../utils/theme";
13
13
  import { deepReady, waitForMount } from "../../utils/transition/index";
14
14
  import { config } from "../../global/config";
@@ -432,6 +432,7 @@ export class Modal {
432
432
  window.removeEventListener(KEYBOARD_DID_OPEN, this.keyboardOpenCallback);
433
433
  this.keyboardOpenCallback = undefined;
434
434
  }
435
+ const enteringAnimation = activeAnimations.get(this) || [];
435
436
  const dismissed = await dismiss(this, data, role, 'modalLeave', iosLeaveAnimation, mdLeaveAnimation, {
436
437
  presentingEl: presentingElement,
437
438
  currentBreakpoint: (_a = this.currentBreakpoint) !== null && _a !== void 0 ? _a : this.initialBreakpoint,
@@ -447,6 +448,7 @@ export class Modal {
447
448
  if (this.gesture) {
448
449
  this.gesture.destroy();
449
450
  }
451
+ enteringAnimation.forEach((ani) => ani.destroy());
450
452
  }
451
453
  this.currentBreakpoint = undefined;
452
454
  this.animation = undefined;
@@ -526,9 +528,9 @@ export class Modal {
526
528
  const mode = getIonMode(this);
527
529
  const isCardModal = presentingElement !== undefined && mode === 'ios';
528
530
  const isHandleCycle = handleBehavior === 'cycle';
529
- return (h(Host, Object.assign({ key: '9a305d82f123283b6200c42d67393b378bb309a8', "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
531
+ return (h(Host, Object.assign({ key: '8c163f4f59429227cab3a1cafb5612994939a629', "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
530
532
  zIndex: `${20000 + this.overlayIndex}`,
531
- }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle }), h("ion-backdrop", { key: '85e8dc6f19b30fd95db518445929fb0c1d5cdef0', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { class: "modal-shadow" }), h("div", Object.assign({ key: '893a0202d91828e60099311442c2677bee5464e2',
533
+ }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle }), h("ion-backdrop", { key: '6908bdf9462d940eff6607b626a499eedc66dc9c', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { class: "modal-shadow" }), h("div", Object.assign({ key: 'ac224394e19b9e8c7dd902f2836fa25787663455',
532
534
  /*
533
535
  role and aria-modal must be used on the
534
536
  same element. They must also be set inside the
@@ -537,7 +539,7 @@ export class Modal {
537
539
  */
538
540
  role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { class: "modal-handle",
539
541
  // Prevents the handle from receiving keyboard focus when it does not cycle
540
- tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle" })), h("slot", { key: '25187bf4c69d9022930227b8b8748a294176be5f' }))));
542
+ tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle" })), h("slot", { key: '9c3c5ec797b6415110a3275c6ff33277291a6e21' }))));
541
543
  }
542
544
  static get is() { return "ion-modal"; }
543
545
  static get encapsulation() { return "shadow"; }
@@ -66,16 +66,15 @@ export class SplitPane {
66
66
  this.visible = false;
67
67
  return;
68
68
  }
69
- if (window.matchMedia) {
70
- // Listen on media query
71
- const callback = (q) => {
72
- this.visible = q.matches;
73
- };
74
- const mediaList = window.matchMedia(mediaQuery);
75
- mediaList.addListener(callback);
76
- this.rmL = () => mediaList.removeListener(callback);
77
- this.visible = mediaList.matches;
78
- }
69
+ // Listen on media query
70
+ const callback = (q) => {
71
+ this.visible = q.matches;
72
+ };
73
+ const mediaList = window.matchMedia(mediaQuery);
74
+ // TODO FW-5869
75
+ mediaList.addListener(callback);
76
+ this.rmL = () => mediaList.removeListener(callback);
77
+ this.visible = mediaList.matches;
79
78
  }
80
79
  isPane(element) {
81
80
  if (!this.visible) {
@@ -109,12 +108,12 @@ export class SplitPane {
109
108
  }
110
109
  render() {
111
110
  const mode = getIonMode(this);
112
- return (h(Host, { key: '68f375658524c6b2ecc95f51125f496e76291b99', class: {
111
+ return (h(Host, { key: '3efe241375d23ae12c47927aa1fc1f3f4b4e5807', class: {
113
112
  [mode]: true,
114
113
  // Used internally for styling
115
114
  [`split-pane-${mode}`]: true,
116
115
  'split-pane-visible': this.visible,
117
- } }, h("slot", { key: '606277cb63a5772e421c0dad9d0b4568276d8a7a' })));
116
+ } }, h("slot", { key: 'd5c94319658e2291dcc356e6ed7a9abc1a48a8b9' })));
118
117
  }
119
118
  static get is() { return "ion-split-pane"; }
120
119
  static get encapsulation() { return "shadow"; }
@@ -1,6 +1,21 @@
1
1
  /*!
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
+ import { win } from "./browser/index";
5
+ import { config } from "../global/config";
6
+ /**
7
+ * CloseWatcher is a newer API that lets
8
+ * use detect the hardware back button event
9
+ * in a web browser: https://caniuse.com/?search=closewatcher
10
+ * However, not every browser supports it yet.
11
+ *
12
+ * This needs to be a function so that we can
13
+ * check the config once it has been set.
14
+ * Otherwise, this code would be evaluated the
15
+ * moment this file is evaluated which could be
16
+ * before the config is set.
17
+ */
18
+ export const shoudUseCloseWatcher = () => config.get('experimentalCloseWatcher', false) && win !== undefined && 'CloseWatcher' in win;
4
19
  /**
5
20
  * When hardwareBackButton: false in config,
6
21
  * we need to make sure we also block the default
@@ -17,7 +32,7 @@ export const blockHardwareBackButton = () => {
17
32
  export const startHardwareBackButton = () => {
18
33
  const doc = document;
19
34
  let busy = false;
20
- doc.addEventListener('backbutton', () => {
35
+ const backButtonCallback = () => {
21
36
  if (busy) {
22
37
  return;
23
38
  }
@@ -63,7 +78,35 @@ export const startHardwareBackButton = () => {
63
78
  }
64
79
  };
65
80
  processHandlers();
66
- });
81
+ };
82
+ /**
83
+ * If the CloseWatcher is defined then
84
+ * we don't want to also listen for the native
85
+ * backbutton event otherwise we may get duplicate
86
+ * events firing.
87
+ */
88
+ if (shoudUseCloseWatcher()) {
89
+ let watcher;
90
+ const configureWatcher = () => {
91
+ watcher === null || watcher === void 0 ? void 0 : watcher.destroy();
92
+ watcher = new win.CloseWatcher();
93
+ /**
94
+ * Once a close request happens
95
+ * the watcher gets destroyed.
96
+ * As a result, we need to re-configure
97
+ * the watcher so we can respond to other
98
+ * close requests.
99
+ */
100
+ watcher.onclose = () => {
101
+ backButtonCallback();
102
+ configureWatcher();
103
+ };
104
+ };
105
+ configureWatcher();
106
+ }
107
+ else {
108
+ doc.addEventListener('backbutton', backButtonCallback);
109
+ }
67
110
  };
68
111
  export const OVERLAY_BACK_BUTTON_PRIORITY = 100;
69
112
  export const MENU_BACK_BUTTON_PRIORITY = 99; // 1 less than overlay priority since menu is displayed behind overlays
@@ -34,7 +34,7 @@ const transitionEnd = (el, expectedDuration = 0, callback) => {
34
34
  el.addEventListener('transitionend', onTransitionEnd, opts);
35
35
  animationTimeout = setTimeout(onTransitionEnd, expectedDuration + ANIMATION_FALLBACK_TIMEOUT);
36
36
  unRegTrans = () => {
37
- if (animationTimeout) {
37
+ if (animationTimeout !== undefined) {
38
38
  clearTimeout(animationTimeout);
39
39
  animationTimeout = undefined;
40
40
  }
@@ -2,6 +2,7 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { doc } from "./browser/index";
5
+ import { shoudUseCloseWatcher } from "./hardware-back-button";
5
6
  import { config } from "../global/config";
6
7
  import { getIonMode } from "../global/ionic-global";
7
8
  import { CoreDelegate } from "./framework-delegate";
@@ -296,19 +297,38 @@ const connectListeners = (doc) => {
296
297
  const lastOverlay = getPresentedOverlay(doc);
297
298
  if (lastOverlay === null || lastOverlay === void 0 ? void 0 : lastOverlay.backdropDismiss) {
298
299
  ev.detail.register(OVERLAY_BACK_BUTTON_PRIORITY, () => {
299
- return lastOverlay.dismiss(undefined, BACKDROP);
300
+ /**
301
+ * Do not return this promise otherwise
302
+ * the hardware back button utility will
303
+ * be blocked until the overlay dismisses.
304
+ * This is important for a modal with canDismiss.
305
+ * If the application presents a confirmation alert
306
+ * in the "canDismiss" callback, then it will be impossible
307
+ * to use the hardware back button to dismiss the alert
308
+ * dialog because the hardware back button utility
309
+ * is blocked on waiting for the modal to dismiss.
310
+ */
311
+ lastOverlay.dismiss(undefined, BACKDROP);
300
312
  });
301
313
  }
302
314
  });
303
- // handle ESC to close overlay
304
- doc.addEventListener('keydown', (ev) => {
305
- if (ev.key === 'Escape') {
306
- const lastOverlay = getPresentedOverlay(doc);
307
- if (lastOverlay === null || lastOverlay === void 0 ? void 0 : lastOverlay.backdropDismiss) {
308
- lastOverlay.dismiss(undefined, BACKDROP);
315
+ /**
316
+ * Handle ESC to close overlay.
317
+ * CloseWatcher also handles pressing the Esc
318
+ * key, so if a browser supports CloseWatcher then
319
+ * this behavior will be handled via the ionBackButton
320
+ * event.
321
+ */
322
+ if (!shoudUseCloseWatcher()) {
323
+ doc.addEventListener('keydown', (ev) => {
324
+ if (ev.key === 'Escape') {
325
+ const lastOverlay = getPresentedOverlay(doc);
326
+ if (lastOverlay === null || lastOverlay === void 0 ? void 0 : lastOverlay.backdropDismiss) {
327
+ lastOverlay.dismiss(undefined, BACKDROP);
328
+ }
309
329
  }
310
- }
311
- });
330
+ });
331
+ }
312
332
  }
313
333
  };
314
334
  export const dismissOverlay = (doc, data, role, overlayTag, id) => {
@@ -474,10 +494,6 @@ export const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLe
474
494
  }
475
495
  overlay.didDismiss.emit({ data, role });
476
496
  (_b = overlay.didDismissShorthand) === null || _b === void 0 ? void 0 : _b.emit({ data, role });
477
- // Get a reference to all animations currently assigned to this overlay
478
- // Then tear them down to return the overlay to its initial visual state
479
- const animations = activeAnimations.get(overlay) || [];
480
- animations.forEach((ani) => ani.destroy());
481
497
  activeAnimations.delete(overlay);
482
498
  /**
483
499
  * Make overlay hidden again in case it is being reused.
@@ -2,6 +2,8 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { startHardwareBackButton } from "../hardware-back-button";
5
+ import { config } from "../../global/config";
6
+ import { win } from "../browser/index";
5
7
  describe('Hardware Back Button', () => {
6
8
  beforeEach(() => startHardwareBackButton());
7
9
  it('should call handler', () => {
@@ -47,6 +49,42 @@ describe('Hardware Back Button', () => {
47
49
  expect(cbSpyTwo).toHaveBeenCalled();
48
50
  });
49
51
  });
52
+ describe('Experimental Close Watcher', () => {
53
+ test('should not use the Close Watcher API when available', () => {
54
+ const mockAPI = mockCloseWatcher();
55
+ config.reset({ experimentalCloseWatcher: false });
56
+ startHardwareBackButton();
57
+ expect(mockAPI.mock.calls).toHaveLength(0);
58
+ });
59
+ test('should use the Close Watcher API when available', () => {
60
+ const mockAPI = mockCloseWatcher();
61
+ config.reset({ experimentalCloseWatcher: true });
62
+ startHardwareBackButton();
63
+ expect(mockAPI.mock.calls).toHaveLength(1);
64
+ });
65
+ test('Close Watcher should dispatch ionBackButton events', () => {
66
+ const mockAPI = mockCloseWatcher();
67
+ config.reset({ experimentalCloseWatcher: true });
68
+ startHardwareBackButton();
69
+ const cbSpy = jest.fn();
70
+ document.addEventListener('ionBackButton', cbSpy);
71
+ // Call onclose on Ionic's instance of CloseWatcher
72
+ mockAPI.getMockImplementation()().onclose();
73
+ expect(cbSpy).toHaveBeenCalled();
74
+ });
75
+ });
76
+ const mockCloseWatcher = () => {
77
+ const mockCloseWatcher = jest.fn();
78
+ mockCloseWatcher.mockReturnValue({
79
+ requestClose: () => null,
80
+ close: () => null,
81
+ destroy: () => null,
82
+ oncancel: () => null,
83
+ onclose: () => null,
84
+ });
85
+ win.CloseWatcher = mockCloseWatcher;
86
+ return mockCloseWatcher;
87
+ };
50
88
  const dispatchBackButtonEvent = () => {
51
89
  const ev = new Event('backbutton');
52
90
  document.dispatchEvent(ev);
package/dist/docs.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2024-01-31T15:36:35",
2
+ "timestamp": "2024-01-31T15:13:30",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.12.0",
@@ -14568,11 +14568,6 @@
14568
14568
  "event": "click",
14569
14569
  "capture": true,
14570
14570
  "passive": false
14571
- },
14572
- {
14573
- "event": "keydown",
14574
- "capture": false,
14575
- "passive": false
14576
14571
  }
14577
14572
  ],
14578
14573
  "styles": [
@@ -2,7 +2,7 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { w as win } from './index-a5d50daf.js';
5
- import { r as raf } from './helpers-ae653409.js';
5
+ import { r as raf } from './helpers-c0b9ca37.js';
6
6
 
7
7
  let animationPrefix;
8
8
  /**
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
- import { h as findItemLabel } from './helpers-ae653409.js';
4
+ import { h as findItemLabel } from './helpers-c0b9ca37.js';
5
5
 
6
6
  /**
7
7
  * Creates a controller that tracks whether a form control is using the legacy or modern syntax. This should be removed when the legacy form control syntax is removed.
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
- import { c as componentOnReady } from './helpers-ae653409.js';
4
+ import { c as componentOnReady } from './helpers-c0b9ca37.js';
5
5
 
6
6
  // TODO(FW-2832): types
7
7
  const attachComponent = async (delegate, container, component, cssClasses, componentProps, inline) => {
@@ -1,6 +1,23 @@
1
1
  /*!
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
+ import { w as win } from './index-a5d50daf.js';
5
+ import { c as config } from './ionic-global-778b7863.js';
6
+ import './index-73881b51.js';
7
+
8
+ /**
9
+ * CloseWatcher is a newer API that lets
10
+ * use detect the hardware back button event
11
+ * in a web browser: https://caniuse.com/?search=closewatcher
12
+ * However, not every browser supports it yet.
13
+ *
14
+ * This needs to be a function so that we can
15
+ * check the config once it has been set.
16
+ * Otherwise, this code would be evaluated the
17
+ * moment this file is evaluated which could be
18
+ * before the config is set.
19
+ */
20
+ const shoudUseCloseWatcher = () => config.get('experimentalCloseWatcher', false) && win !== undefined && 'CloseWatcher' in win;
4
21
  /**
5
22
  * When hardwareBackButton: false in config,
6
23
  * we need to make sure we also block the default
@@ -17,7 +34,7 @@ const blockHardwareBackButton = () => {
17
34
  const startHardwareBackButton = () => {
18
35
  const doc = document;
19
36
  let busy = false;
20
- doc.addEventListener('backbutton', () => {
37
+ const backButtonCallback = () => {
21
38
  if (busy) {
22
39
  return;
23
40
  }
@@ -63,9 +80,37 @@ const startHardwareBackButton = () => {
63
80
  }
64
81
  };
65
82
  processHandlers();
66
- });
83
+ };
84
+ /**
85
+ * If the CloseWatcher is defined then
86
+ * we don't want to also listen for the native
87
+ * backbutton event otherwise we may get duplicate
88
+ * events firing.
89
+ */
90
+ if (shoudUseCloseWatcher()) {
91
+ let watcher;
92
+ const configureWatcher = () => {
93
+ watcher === null || watcher === void 0 ? void 0 : watcher.destroy();
94
+ watcher = new win.CloseWatcher();
95
+ /**
96
+ * Once a close request happens
97
+ * the watcher gets destroyed.
98
+ * As a result, we need to re-configure
99
+ * the watcher so we can respond to other
100
+ * close requests.
101
+ */
102
+ watcher.onclose = () => {
103
+ backButtonCallback();
104
+ configureWatcher();
105
+ };
106
+ };
107
+ configureWatcher();
108
+ }
109
+ else {
110
+ doc.addEventListener('backbutton', backButtonCallback);
111
+ }
67
112
  };
68
113
  const OVERLAY_BACK_BUTTON_PRIORITY = 100;
69
114
  const MENU_BACK_BUTTON_PRIORITY = 99; // 1 less than overlay priority since menu is displayed behind overlays
70
115
 
71
- export { MENU_BACK_BUTTON_PRIORITY, OVERLAY_BACK_BUTTON_PRIORITY, blockHardwareBackButton, startHardwareBackButton };
116
+ export { MENU_BACK_BUTTON_PRIORITY, OVERLAY_BACK_BUTTON_PRIORITY, blockHardwareBackButton, shoudUseCloseWatcher, startHardwareBackButton };
@@ -34,7 +34,7 @@ const transitionEnd = (el, expectedDuration = 0, callback) => {
34
34
  el.addEventListener('transitionend', onTransitionEnd, opts);
35
35
  animationTimeout = setTimeout(onTransitionEnd, expectedDuration + ANIMATION_FALLBACK_TIMEOUT);
36
36
  unRegTrans = () => {
37
- if (animationTimeout) {
37
+ if (animationTimeout !== undefined) {
38
38
  clearTimeout(animationTimeout);
39
39
  animationTimeout = undefined;
40
40
  }
@@ -2,11 +2,11 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { d as doc } from './index-a5d50daf.js';
5
- import { MENU_BACK_BUTTON_PRIORITY } from './hardware-back-button-b2bc76db.js';
5
+ import { MENU_BACK_BUTTON_PRIORITY } from './hardware-back-button-f42b9c80.js';
6
6
  import { p as printIonWarning } from './index-9b0d46f4.js';
7
- import { c as componentOnReady } from './helpers-ae653409.js';
7
+ import { c as componentOnReady } from './helpers-c0b9ca37.js';
8
8
  import { b as getIonMode } from './ionic-global-778b7863.js';
9
- import { c as createAnimation } from './animation-dde8cc0d.js';
9
+ import { c as createAnimation } from './animation-60dbdd13.js';
10
10
 
11
11
  /**
12
12
  * baseAnimation
@@ -2,7 +2,7 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { w as writeTask, B as Build } from './index-73881b51.js';
5
- import { r as raf } from './helpers-ae653409.js';
5
+ import { r as raf } from './helpers-c0b9ca37.js';
6
6
 
7
7
  const LIFECYCLE_WILL_ENTER = 'ionViewWillEnter';
8
8
  const LIFECYCLE_DID_ENTER = 'ionViewDidEnter';
@@ -10,8 +10,8 @@ const LIFECYCLE_WILL_LEAVE = 'ionViewWillLeave';
10
10
  const LIFECYCLE_DID_LEAVE = 'ionViewDidLeave';
11
11
  const LIFECYCLE_WILL_UNLOAD = 'ionViewWillUnload';
12
12
 
13
- const iosTransitionAnimation = () => import('./ios.transition-968faaad.js');
14
- const mdTransitionAnimation = () => import('./md.transition-498898ac.js');
13
+ const iosTransitionAnimation = () => import('./ios.transition-7ff7381d.js');
14
+ const mdTransitionAnimation = () => import('./md.transition-28a9a26b.js');
15
15
  // TODO(FW-2832): types
16
16
  const transition = (opts) => {
17
17
  return new Promise((resolve, reject) => {