@gemx-dev/heatmap-react 3.5.44 → 3.5.46

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 (303) hide show
  1. package/dist/esm/components/Layout/ContentHeader.d.ts +4 -0
  2. package/dist/esm/components/Layout/ContentHeader.d.ts.map +1 -0
  3. package/dist/esm/components/Layout/VizMode.d.ts +2 -0
  4. package/dist/esm/components/Layout/VizMode.d.ts.map +1 -0
  5. package/dist/esm/components/Test.d.ts +121 -0
  6. package/dist/esm/components/Test.d.ts.map +1 -0
  7. package/dist/esm/components/VizDom/VizDomContainer.d.ts +6 -0
  8. package/dist/esm/components/VizDom/VizDomContainer.d.ts.map +1 -0
  9. package/dist/esm/components/VizDom/VizDomRenderer.d.ts.map +1 -1
  10. package/dist/esm/components/VizElement/ClickedElementOverlay.d.ts +17 -0
  11. package/dist/esm/components/VizElement/ClickedElementOverlay.d.ts.map +1 -0
  12. package/dist/esm/components/VizElement/HeatmapElements.d.ts.map +1 -1
  13. package/dist/esm/components/VizElement/HoveredElementOverlay.d.ts +12 -0
  14. package/dist/esm/components/VizElement/HoveredElementOverlay.d.ts.map +1 -0
  15. package/dist/esm/components/VizElement/MissingElementMessage.d.ts +7 -0
  16. package/dist/esm/components/VizElement/MissingElementMessage.d.ts.map +1 -0
  17. package/dist/esm/components/VizElement/VizElements.d.ts.map +1 -1
  18. package/dist/esm/components/VizElement/temp/ClarityVisualizer.d.ts +150 -0
  19. package/dist/esm/components/VizElement/temp/ClarityVisualizer.d.ts.map +1 -0
  20. package/dist/esm/components/VizElement/temp/VizElementRank.d.ts +74 -0
  21. package/dist/esm/components/VizElement/temp/VizElementRank.d.ts.map +1 -0
  22. package/dist/esm/components/VizLive/VizLive.d.ts +2 -0
  23. package/dist/esm/components/VizLive/VizLive.d.ts.map +1 -0
  24. package/dist/esm/components/VizLive/VizLiveHeatmap.d.ts.map +1 -1
  25. package/dist/esm/components/VizLive/VizLiveRenderer.d.ts.map +1 -1
  26. package/dist/esm/configs/style.d.ts +0 -2
  27. package/dist/esm/configs/style.d.ts.map +1 -1
  28. package/dist/esm/helpers/index.d.ts +2 -1
  29. package/dist/esm/helpers/index.d.ts.map +1 -1
  30. package/dist/esm/helpers/viewport-fixer.d.ts +13 -0
  31. package/dist/esm/helpers/viewport-fixer.d.ts.map +1 -0
  32. package/dist/esm/helpers/viewport-replacer.d.ts +26 -0
  33. package/dist/esm/helpers/viewport-replacer.d.ts.map +1 -0
  34. package/dist/esm/hooks/vix-elements/useHoveredElement.d.ts.map +1 -1
  35. package/dist/esm/hooks/viz-canvas/useClickmap.d.ts +1 -3
  36. package/dist/esm/hooks/viz-canvas/useClickmap.d.ts.map +1 -1
  37. package/dist/esm/hooks/viz-canvas/useHeatmapVizCanvas.d.ts +1 -1
  38. package/dist/esm/hooks/viz-canvas/useHeatmapVizCanvas.d.ts.map +1 -1
  39. package/dist/esm/hooks/viz-canvas/useScrollmap.d.ts +1 -3
  40. package/dist/esm/hooks/viz-canvas/useScrollmap.d.ts.map +1 -1
  41. package/dist/esm/hooks/viz-live/index.d.ts +1 -1
  42. package/dist/esm/hooks/viz-live/{useVizLiveIframeMsg.d.ts → useIframeMessage.d.ts} +10 -2
  43. package/dist/esm/hooks/viz-live/useIframeMessage.d.ts.map +1 -0
  44. package/dist/esm/hooks/viz-render/useHeatmapRender.d.ts.map +1 -1
  45. package/dist/esm/hooks/viz-scale/useContainerDimensions.d.ts.map +1 -1
  46. package/dist/esm/hooks/viz-scale/useHeatmapScale.d.ts +1 -1
  47. package/dist/esm/hooks/viz-scale/useHeatmapScale.d.ts.map +1 -1
  48. package/dist/esm/hooks/viz-scale/useIframeHeight.d.ts +10 -0
  49. package/dist/esm/hooks/viz-scale/useIframeHeight.d.ts.map +1 -0
  50. package/dist/esm/index.d.ts +1 -1
  51. package/dist/esm/index.d.ts.map +1 -1
  52. package/dist/esm/index.js +203 -910
  53. package/dist/esm/index.mjs +203 -910
  54. package/dist/esm/stores/index.d.ts +0 -1
  55. package/dist/esm/stores/index.d.ts.map +1 -1
  56. package/dist/esm/stores/interaction.d.ts.map +1 -1
  57. package/dist/esm/stores/mode-live.d.ts +0 -4
  58. package/dist/esm/stores/mode-live.d.ts.map +1 -1
  59. package/dist/esm/stores/viz.d.ts +4 -0
  60. package/dist/esm/stores/viz.d.ts.map +1 -1
  61. package/dist/esm/types/index.d.ts +1 -1
  62. package/dist/esm/types/index.d.ts.map +1 -1
  63. package/dist/esm/types/viewport-fixer.d.ts +31 -0
  64. package/dist/esm/types/viewport-fixer.d.ts.map +1 -0
  65. package/dist/umd/components/Layout/ContentHeader.d.ts +4 -0
  66. package/dist/umd/components/Layout/ContentHeader.d.ts.map +1 -0
  67. package/dist/umd/components/Test.d.ts +121 -0
  68. package/dist/umd/components/Test.d.ts.map +1 -0
  69. package/dist/umd/components/VizDom/VizDomContainer.d.ts +2 -0
  70. package/dist/umd/components/VizDom/VizDomContainer.d.ts.map +1 -0
  71. package/dist/umd/components/VizDom/VizDomRenderer.d.ts.map +1 -1
  72. package/dist/umd/components/VizElement/ClickedElementOverlay.d.ts +17 -0
  73. package/dist/umd/components/VizElement/ClickedElementOverlay.d.ts.map +1 -0
  74. package/dist/umd/components/VizElement/HeatmapElements.d.ts.map +1 -1
  75. package/dist/umd/components/VizElement/HoveredElementOverlay.d.ts +12 -0
  76. package/dist/umd/components/VizElement/HoveredElementOverlay.d.ts.map +1 -0
  77. package/dist/umd/components/VizElement/MissingElementMessage.d.ts +7 -0
  78. package/dist/umd/components/VizElement/MissingElementMessage.d.ts.map +1 -0
  79. package/dist/umd/components/VizElement/VizElements.d.ts.map +1 -1
  80. package/dist/umd/components/VizElement/temp/ClarityVisualizer.d.ts +150 -0
  81. package/dist/umd/components/VizElement/temp/ClarityVisualizer.d.ts.map +1 -0
  82. package/dist/umd/components/VizElement/temp/VizElementRank.d.ts +74 -0
  83. package/dist/umd/components/VizElement/temp/VizElementRank.d.ts.map +1 -0
  84. package/dist/umd/components/VizLive/VizLiveHeatmap.d.ts.map +1 -1
  85. package/dist/umd/components/VizLive/VizLiveRenderer.d.ts.map +1 -1
  86. package/dist/umd/configs/style.d.ts +0 -2
  87. package/dist/umd/configs/style.d.ts.map +1 -1
  88. package/dist/umd/helpers/index.d.ts +2 -1
  89. package/dist/umd/helpers/index.d.ts.map +1 -1
  90. package/dist/umd/helpers/viewport-fixer.d.ts +13 -0
  91. package/dist/umd/helpers/viewport-fixer.d.ts.map +1 -0
  92. package/dist/umd/helpers/viewport-replacer.d.ts +26 -0
  93. package/dist/umd/helpers/viewport-replacer.d.ts.map +1 -0
  94. package/dist/umd/hooks/vix-elements/useHoveredElement.d.ts.map +1 -1
  95. package/dist/umd/hooks/viz-canvas/useClickmap.d.ts +1 -3
  96. package/dist/umd/hooks/viz-canvas/useClickmap.d.ts.map +1 -1
  97. package/dist/umd/hooks/viz-canvas/useHeatmapVizCanvas.d.ts +1 -1
  98. package/dist/umd/hooks/viz-canvas/useHeatmapVizCanvas.d.ts.map +1 -1
  99. package/dist/umd/hooks/viz-canvas/useScrollmap.d.ts +1 -3
  100. package/dist/umd/hooks/viz-canvas/useScrollmap.d.ts.map +1 -1
  101. package/dist/umd/hooks/viz-live/index.d.ts +1 -1
  102. package/dist/umd/hooks/viz-live/{useVizLiveIframeMsg.d.ts → useIframeMessage.d.ts} +10 -2
  103. package/dist/umd/hooks/viz-live/useIframeMessage.d.ts.map +1 -0
  104. package/dist/umd/hooks/viz-render/useHeatmapRender.d.ts.map +1 -1
  105. package/dist/umd/hooks/viz-scale/useContainerDimensions.d.ts.map +1 -1
  106. package/dist/umd/hooks/viz-scale/useHeatmapScale.d.ts +1 -1
  107. package/dist/umd/hooks/viz-scale/useHeatmapScale.d.ts.map +1 -1
  108. package/dist/umd/hooks/viz-scale/useIframeHeight.d.ts +10 -0
  109. package/dist/umd/hooks/viz-scale/useIframeHeight.d.ts.map +1 -0
  110. package/dist/umd/index.d.ts +1 -1
  111. package/dist/umd/index.d.ts.map +1 -1
  112. package/dist/umd/index.js +2 -2
  113. package/dist/umd/stores/index.d.ts +0 -1
  114. package/dist/umd/stores/index.d.ts.map +1 -1
  115. package/dist/umd/stores/interaction.d.ts.map +1 -1
  116. package/dist/umd/stores/mode-live.d.ts +0 -4
  117. package/dist/umd/stores/mode-live.d.ts.map +1 -1
  118. package/dist/umd/stores/viz.d.ts +4 -0
  119. package/dist/umd/stores/viz.d.ts.map +1 -1
  120. package/dist/umd/types/index.d.ts +1 -1
  121. package/dist/umd/types/index.d.ts.map +1 -1
  122. package/dist/umd/types/viewport-fixer.d.ts +31 -0
  123. package/dist/umd/types/viewport-fixer.d.ts.map +1 -0
  124. package/package.json +13 -15
  125. package/src/components/GraphView.tsx +58 -0
  126. package/src/components/Layout/ContentMetricBar.tsx +23 -0
  127. package/src/components/Layout/ContentToolbar.tsx +22 -0
  128. package/src/components/Layout/ContentTopBar.tsx +24 -0
  129. package/src/components/Layout/ContentVizByMode.tsx +14 -0
  130. package/src/components/Layout/HeatmapLayout.tsx +60 -0
  131. package/src/components/Layout/LeftSidebar.tsx +44 -0
  132. package/src/components/Layout/WrapperLayout.tsx +12 -0
  133. package/src/components/Layout/WrapperPreview.tsx +24 -0
  134. package/src/components/Layout/index.ts +1 -0
  135. package/src/components/VizDom/ReplayControls.tsx +48 -0
  136. package/src/components/VizDom/VizContainer.tsx +40 -0
  137. package/src/components/VizDom/VizDomHeatmap.tsx +28 -0
  138. package/src/components/VizDom/VizDomRenderer.tsx +82 -0
  139. package/src/components/VizDom/VizLoading.tsx +8 -0
  140. package/src/components/VizDom/WrapperVisual.tsx +73 -0
  141. package/src/components/VizDom/index.ts +5 -0
  142. package/src/components/VizElement/DefaultRankBadges.tsx +36 -0
  143. package/src/components/VizElement/ElementCallout.tsx +82 -0
  144. package/src/components/VizElement/ElementMissing.tsx +35 -0
  145. package/src/components/VizElement/ElementOverlay.tsx +66 -0
  146. package/src/components/VizElement/HeatmapElements.tsx +127 -0
  147. package/src/components/VizElement/HeatmapExample.tsx +70 -0
  148. package/src/components/VizElement/RankBadge.tsx +25 -0
  149. package/src/components/VizElement/VizElements.tsx +57 -0
  150. package/src/components/VizElement/index.ts +1 -0
  151. package/src/components/VizLive/VizLiveHeatmap.tsx +27 -0
  152. package/src/components/VizLive/VizLiveRenderer.tsx +47 -0
  153. package/src/components/VizLive/index.ts +1 -0
  154. package/src/components/VizScrollmap/AverageFoldLine.tsx +57 -0
  155. package/src/components/VizScrollmap/HoverZones.tsx +58 -0
  156. package/src/components/VizScrollmap/MetricRow.tsx +0 -0
  157. package/src/components/VizScrollmap/ScrollMapMinimap.tsx +64 -0
  158. package/src/components/VizScrollmap/ScrollMapOverlay.tsx +79 -0
  159. package/src/components/VizScrollmap/ScrollZoneHoverArea.tsx +35 -0
  160. package/src/components/VizScrollmap/ScrollZoneTooltip.tsx +146 -0
  161. package/src/components/VizScrollmap/ScrollmapMarker.tsx +106 -0
  162. package/src/components/VizScrollmap/VizScrollMap.tsx +36 -0
  163. package/src/components/VizScrollmap/index.ts +1 -0
  164. package/src/components/VizScrollmapV2/ScrollmapOverlay.css +94 -0
  165. package/src/components/VizScrollmapV2/ScrollmapOverlayV2.tsx +130 -0
  166. package/src/components/VizScrollmapV2/index.ts +1 -0
  167. package/src/components/VizScrollmapV2/scrollmap.types.ts +21 -0
  168. package/src/components/VizScrollmapV2/useScrollmapOverlay.ts +187 -0
  169. package/src/components/index.tsx +2 -0
  170. package/src/configs/iframe.ts +15 -0
  171. package/src/configs/index.ts +2 -0
  172. package/src/configs/style.ts +21 -0
  173. package/src/constants/index.ts +4 -0
  174. package/src/global.d.ts +5 -0
  175. package/src/helpers/elm-callout.ts +347 -0
  176. package/src/helpers/elm-getter.ts +70 -0
  177. package/src/helpers/iframe-helper/fixer.ts +100 -0
  178. package/src/helpers/iframe-helper/index.ts +1 -0
  179. package/src/helpers/iframe-helper/init.ts +56 -0
  180. package/src/helpers/iframe-helper/navigation-blocker-v2.ts +371 -0
  181. package/src/helpers/iframe-helper/navigation-blocker.ts +367 -0
  182. package/src/helpers/iframe-helper/style-replacer.ts +231 -0
  183. package/src/helpers/iframe.ts +42 -0
  184. package/src/helpers/index.ts +8 -0
  185. package/src/helpers/viz-canvas/area-clustering.ts +234 -0
  186. package/src/helpers/viz-canvas/area-overlay-manager-v2.ts +176 -0
  187. package/src/helpers/viz-canvas/area-overlay-manager.ts +273 -0
  188. package/src/helpers/viz-canvas/hierarchical-area-clustering.ts +420 -0
  189. package/src/helpers/viz-canvas/index.ts +2 -0
  190. package/src/helpers/viz-elements.ts +43 -0
  191. package/src/hooks/index.ts +8 -0
  192. package/src/hooks/register/index.ts +4 -0
  193. package/src/hooks/register/useRegisterConfig.ts +17 -0
  194. package/src/hooks/register/useRegisterControl.ts +13 -0
  195. package/src/hooks/register/useRegisterData.ts +36 -0
  196. package/src/hooks/register/useRegisterHeatmap.ts +38 -0
  197. package/src/hooks/viz-area/useAreaHeatmap.ts +336 -0
  198. package/src/hooks/viz-area/useAreaHeatmapManager.ts +692 -0
  199. package/src/hooks/viz-canvas/index.ts +1 -0
  200. package/src/hooks/viz-canvas/useAreamap.ts +162 -0
  201. package/src/hooks/viz-canvas/useClickmap.ts +24 -0
  202. package/src/hooks/viz-canvas/useHeatmapCanvas.ts +27 -0
  203. package/src/hooks/viz-canvas/useScrollmap.ts +22 -0
  204. package/src/hooks/viz-elements/index.ts +5 -0
  205. package/src/hooks/viz-elements/useClickedElement.ts +86 -0
  206. package/src/hooks/viz-elements/useElementCalloutVisible.ts +45 -0
  207. package/src/hooks/viz-elements/useHeatmapEffects.ts +30 -0
  208. package/src/hooks/viz-elements/useHeatmapElementPosition.ts +60 -0
  209. package/src/hooks/viz-elements/useHeatmapMouseHandler.ts +255 -0
  210. package/src/hooks/viz-elements/useHoveredElement.ts +170 -0
  211. package/src/hooks/viz-live/index.ts +1 -0
  212. package/src/hooks/viz-live/useVizLiveIframeMsg.ts +88 -0
  213. package/src/hooks/viz-live/useVizLiveRender.ts +67 -0
  214. package/src/hooks/viz-render/index.ts +1 -0
  215. package/src/hooks/viz-render/useHeatmapRender.ts +71 -0
  216. package/src/hooks/viz-render/useHeatmapVizRender.ts +20 -0
  217. package/src/hooks/viz-render/useReplayRender.ts +160 -0
  218. package/src/hooks/viz-scale/index.ts +2 -0
  219. package/src/hooks/viz-scale/useContainerDimensions.ts +48 -0
  220. package/src/hooks/viz-scale/useContentDimensions.ts +25 -0
  221. package/src/hooks/viz-scale/useHeatmapScale.ts +52 -0
  222. package/src/hooks/viz-scale/useObserveIframeHeight.ts +162 -0
  223. package/src/hooks/viz-scale/useScaleCalculation.ts +31 -0
  224. package/src/hooks/viz-scale/useScrollSync.ts +36 -0
  225. package/src/hooks/viz-scale/useWrapperRefHeight.ts +91 -0
  226. package/src/hooks/viz-scrollmap/index.ts +2 -0
  227. package/src/hooks/viz-scrollmap/useScrollmapZones.ts +165 -0
  228. package/src/hooks/viz-scrollmap/useZonePositions.ts +38 -0
  229. package/src/index.ts +10 -0
  230. package/src/stores/comp.ts +31 -0
  231. package/src/stores/config.ts +37 -0
  232. package/src/stores/data.ts +30 -0
  233. package/src/stores/index.ts +10 -0
  234. package/src/stores/interaction.ts +32 -0
  235. package/src/stores/mode-live.ts +38 -0
  236. package/src/stores/mode-single.ts +18 -0
  237. package/src/stores/viz-scrollmap.ts +22 -0
  238. package/src/stores/viz.ts +17 -0
  239. package/src/styles/base.css +1 -0
  240. package/src/styles/style.css +137 -0
  241. package/src/types/clarity.ts +45 -0
  242. package/src/types/control.ts +10 -0
  243. package/src/types/elm-callout.ts +9 -0
  244. package/src/types/heatmap-info.ts +11 -0
  245. package/src/types/heatmap.ts +25 -0
  246. package/src/types/iframe-helper.ts +18 -0
  247. package/src/types/index.ts +12 -0
  248. package/src/types/viz-canvas.ts +20 -0
  249. package/src/types/viz-element.ts +34 -0
  250. package/src/types/viz-scrollmap.ts +28 -0
  251. package/src/ui/BoxStack/BoxStack.tsx +136 -0
  252. package/src/ui/BoxStack/index.ts +1 -0
  253. package/src/ui/index.ts +1 -0
  254. package/src/utils/debounce.ts +10 -0
  255. package/src/utils/device.ts +7 -0
  256. package/src/utils/retry.ts +20 -0
  257. package/src/utils/sort.ts +5 -0
  258. package/dist/esm/helpers/iframe-helper/fixer.d.ts +0 -18
  259. package/dist/esm/helpers/iframe-helper/fixer.d.ts.map +0 -1
  260. package/dist/esm/helpers/iframe-helper/index.d.ts +0 -2
  261. package/dist/esm/helpers/iframe-helper/index.d.ts.map +0 -1
  262. package/dist/esm/helpers/iframe-helper/init.d.ts +0 -5
  263. package/dist/esm/helpers/iframe-helper/init.d.ts.map +0 -1
  264. package/dist/esm/helpers/iframe-helper/navigation-blocker-v2.d.ts +0 -28
  265. package/dist/esm/helpers/iframe-helper/navigation-blocker-v2.d.ts.map +0 -1
  266. package/dist/esm/helpers/iframe-helper/navigation-blocker.d.ts +0 -20
  267. package/dist/esm/helpers/iframe-helper/navigation-blocker.d.ts.map +0 -1
  268. package/dist/esm/helpers/iframe-helper/style-replacer.d.ts +0 -25
  269. package/dist/esm/helpers/iframe-helper/style-replacer.d.ts.map +0 -1
  270. package/dist/esm/hooks/vix-elements/useHeatmapMouseHandler.d.ts +0 -34
  271. package/dist/esm/hooks/vix-elements/useHeatmapMouseHandler.d.ts.map +0 -1
  272. package/dist/esm/hooks/viz-live/useVizLiveIframeMsg.d.ts.map +0 -1
  273. package/dist/esm/hooks/viz-live/useVizLiveRender.d.ts +0 -4
  274. package/dist/esm/hooks/viz-live/useVizLiveRender.d.ts.map +0 -1
  275. package/dist/esm/hooks/viz-scale/useObserveIframeHeight.d.ts +0 -10
  276. package/dist/esm/hooks/viz-scale/useObserveIframeHeight.d.ts.map +0 -1
  277. package/dist/esm/stores/mode-single.d.ts +0 -9
  278. package/dist/esm/stores/mode-single.d.ts.map +0 -1
  279. package/dist/esm/types/iframe-helper.d.ts +0 -20
  280. package/dist/esm/types/iframe-helper.d.ts.map +0 -1
  281. package/dist/umd/helpers/iframe-helper/fixer.d.ts +0 -18
  282. package/dist/umd/helpers/iframe-helper/fixer.d.ts.map +0 -1
  283. package/dist/umd/helpers/iframe-helper/index.d.ts +0 -2
  284. package/dist/umd/helpers/iframe-helper/index.d.ts.map +0 -1
  285. package/dist/umd/helpers/iframe-helper/init.d.ts +0 -5
  286. package/dist/umd/helpers/iframe-helper/init.d.ts.map +0 -1
  287. package/dist/umd/helpers/iframe-helper/navigation-blocker-v2.d.ts +0 -28
  288. package/dist/umd/helpers/iframe-helper/navigation-blocker-v2.d.ts.map +0 -1
  289. package/dist/umd/helpers/iframe-helper/navigation-blocker.d.ts +0 -20
  290. package/dist/umd/helpers/iframe-helper/navigation-blocker.d.ts.map +0 -1
  291. package/dist/umd/helpers/iframe-helper/style-replacer.d.ts +0 -25
  292. package/dist/umd/helpers/iframe-helper/style-replacer.d.ts.map +0 -1
  293. package/dist/umd/hooks/vix-elements/useHeatmapMouseHandler.d.ts +0 -34
  294. package/dist/umd/hooks/vix-elements/useHeatmapMouseHandler.d.ts.map +0 -1
  295. package/dist/umd/hooks/viz-live/useVizLiveIframeMsg.d.ts.map +0 -1
  296. package/dist/umd/hooks/viz-live/useVizLiveRender.d.ts +0 -4
  297. package/dist/umd/hooks/viz-live/useVizLiveRender.d.ts.map +0 -1
  298. package/dist/umd/hooks/viz-scale/useObserveIframeHeight.d.ts +0 -10
  299. package/dist/umd/hooks/viz-scale/useObserveIframeHeight.d.ts.map +0 -1
  300. package/dist/umd/stores/mode-single.d.ts +0 -9
  301. package/dist/umd/stores/mode-single.d.ts.map +0 -1
  302. package/dist/umd/types/iframe-helper.d.ts +0 -20
  303. package/dist/umd/types/iframe-helper.d.ts.map +0 -1
@@ -0,0 +1,371 @@
1
+ export class IframeNavigationBlockerV2 {
2
+ private doc: Document;
3
+ private win: Window;
4
+ private isEnabled = false;
5
+ private showMessage = false;
6
+ private originalWindowOpen: typeof window.open;
7
+ private observers: MutationObserver[] = [];
8
+
9
+ constructor(iframe: HTMLIFrameElement) {
10
+ if (!iframe.contentDocument || !iframe.contentWindow) {
11
+ throw new Error('Iframe document or window not accessible');
12
+ }
13
+
14
+ this.doc = iframe.contentDocument;
15
+ this.win = iframe.contentWindow;
16
+ this.originalWindowOpen = this.win.open.bind(this.win);
17
+
18
+ this.init();
19
+ }
20
+
21
+ private init(): void {
22
+ console.log('[NavigationBlocker] Initializing...');
23
+
24
+ try {
25
+ // Chặn navigation qua links
26
+ this.blockLinkNavigation();
27
+
28
+ // Chặn form submissions
29
+ this.blockFormSubmissions();
30
+
31
+ // Chặn window.open (này an toàn)
32
+ this.blockWindowOpen();
33
+
34
+ // Chặn beforeunload để prevent navigation
35
+ this.blockBeforeUnload();
36
+
37
+ // Monitor DOM changes để block dynamic links
38
+ this.monitorDOMChanges();
39
+
40
+ // Inject CSP nếu có thể
41
+ this.injectCSP();
42
+ } catch (error) {
43
+ console.error('[NavigationBlocker] Init error:', error);
44
+ }
45
+ }
46
+
47
+ private blockLinkNavigation(): void {
48
+ // Sử dụng capture phase để chặn sớm nhất
49
+ this.doc.addEventListener(
50
+ 'click',
51
+ (e) => {
52
+ if (!this.isEnabled) return;
53
+
54
+ const target = e.target as HTMLElement;
55
+ const link = target.closest('a');
56
+
57
+ if (link) {
58
+ const href = link.getAttribute('href');
59
+
60
+ // Cho phép hash links và empty links
61
+ if (!href || href === '' || href === '#' || href.startsWith('#')) {
62
+ console.log('[NavigationBlocker] Allowed hash navigation:', href);
63
+ return;
64
+ }
65
+
66
+ // Chặn tất cả các loại navigation
67
+ console.log('[NavigationBlocker] Blocked link navigation to:', href);
68
+ e.preventDefault();
69
+ e.stopPropagation();
70
+ e.stopImmediatePropagation();
71
+
72
+ this.notifyBlockedNavigation(href);
73
+ }
74
+ },
75
+ true,
76
+ );
77
+
78
+ // Chặn cả middle click và right click "open in new tab"
79
+ this.doc.addEventListener(
80
+ 'auxclick',
81
+ (e) => {
82
+ if (!this.isEnabled) return;
83
+
84
+ const target = e.target as HTMLElement;
85
+ const link = target.closest('a');
86
+
87
+ if (link) {
88
+ const href = link.getAttribute('href');
89
+ if (href && !href.startsWith('#')) {
90
+ console.log('[NavigationBlocker] Blocked auxclick navigation');
91
+ e.preventDefault();
92
+ e.stopPropagation();
93
+ e.stopImmediatePropagation();
94
+ }
95
+ }
96
+ },
97
+ true,
98
+ );
99
+
100
+ // Disable tất cả links ngay từ đầu
101
+ this.disableAllLinks();
102
+ }
103
+
104
+ private disableAllLinks(): void {
105
+ this.doc.querySelectorAll('a[href]').forEach((link) => {
106
+ const href = link.getAttribute('href');
107
+ if (href && !href.startsWith('#')) {
108
+ // Thêm pointer-events: none và cursor
109
+ (link as HTMLElement).style.cursor = 'not-allowed';
110
+ link.setAttribute('data-navigation-blocked', 'true');
111
+
112
+ // Remove href để browser không hiện preview
113
+ link.setAttribute('data-original-href', href);
114
+ link.removeAttribute('href');
115
+
116
+ // Hoặc giữ href nhưng disable
117
+ // link.setAttribute('onclick', 'return false');
118
+ }
119
+ });
120
+ }
121
+
122
+ private blockFormSubmissions(): void {
123
+ this.doc.addEventListener(
124
+ 'submit',
125
+ (e) => {
126
+ if (!this.isEnabled) return;
127
+
128
+ const form = e.target as HTMLFormElement;
129
+ const action = form.getAttribute('action');
130
+
131
+ // Cho phép forms không có action
132
+ if (!action || action === '' || action === '#') {
133
+ console.log('[NavigationBlocker] Allowed same-page form');
134
+ e.preventDefault();
135
+ this.handleFormSubmit(form);
136
+ return;
137
+ }
138
+
139
+ // Chặn tất cả external submissions
140
+ console.log('[NavigationBlocker] Blocked form submission to:', action);
141
+ e.preventDefault();
142
+ e.stopPropagation();
143
+ e.stopImmediatePropagation();
144
+ this.notifyBlockedNavigation(action);
145
+ },
146
+ true,
147
+ );
148
+ }
149
+
150
+ private blockWindowOpen(): void {
151
+ // Override window.open - đây là safe
152
+ this.win.open = ((...args: any[]) => {
153
+ if (!this.isEnabled) {
154
+ return this.originalWindowOpen(...args);
155
+ }
156
+
157
+ const url = args[0]?.toString() || 'popup';
158
+ console.log('[NavigationBlocker] Blocked window.open:', url);
159
+ this.notifyBlockedNavigation(url);
160
+ return null;
161
+ }) as any;
162
+ }
163
+
164
+ private blockBeforeUnload(): void {
165
+ // Chặn unload
166
+ this.win.addEventListener(
167
+ 'beforeunload',
168
+ (e) => {
169
+ if (!this.isEnabled) return;
170
+
171
+ console.log('[NavigationBlocker] Blocked beforeunload');
172
+ e.preventDefault();
173
+ e.returnValue = '';
174
+ return '';
175
+ },
176
+ true,
177
+ );
178
+
179
+ // Chặn unload
180
+ this.win.addEventListener(
181
+ 'unload',
182
+ (e) => {
183
+ if (!this.isEnabled) return;
184
+
185
+ console.log('[NavigationBlocker] Blocked unload');
186
+ e.preventDefault();
187
+ e.stopPropagation();
188
+ },
189
+ true,
190
+ );
191
+
192
+ // Monitor popstate
193
+ this.win.addEventListener(
194
+ 'popstate',
195
+ (e) => {
196
+ if (!this.isEnabled) return;
197
+
198
+ console.log('[NavigationBlocker] Blocked popstate');
199
+ e.preventDefault();
200
+ e.stopPropagation();
201
+ },
202
+ true,
203
+ );
204
+ }
205
+
206
+ private monitorDOMChanges(): void {
207
+ // Monitor khi có links mới được thêm vào
208
+ const observer = new MutationObserver((mutations) => {
209
+ if (!this.isEnabled) return;
210
+
211
+ mutations.forEach((mutation) => {
212
+ mutation.addedNodes.forEach((node) => {
213
+ if (node.nodeType === Node.ELEMENT_NODE) {
214
+ const element = node as HTMLElement;
215
+
216
+ // Nếu là link
217
+ if (element.tagName === 'A') {
218
+ const href = element.getAttribute('href');
219
+ if (href && !href.startsWith('#')) {
220
+ element.style.cursor = 'not-allowed';
221
+ element.setAttribute('data-navigation-blocked', 'true');
222
+ element.setAttribute('data-original-href', href);
223
+ element.removeAttribute('href');
224
+ }
225
+ }
226
+
227
+ // Tìm links trong subtree
228
+ element.querySelectorAll('a[href]').forEach((link) => {
229
+ const href = link.getAttribute('href');
230
+ if (href && !href.startsWith('#')) {
231
+ (link as HTMLElement).style.cursor = 'not-allowed';
232
+ link.setAttribute('data-navigation-blocked', 'true');
233
+ link.setAttribute('data-original-href', href);
234
+ link.removeAttribute('href');
235
+ }
236
+ });
237
+ }
238
+ });
239
+ });
240
+ });
241
+
242
+ observer.observe(this.doc.body, {
243
+ childList: true,
244
+ subtree: true,
245
+ });
246
+
247
+ this.observers.push(observer);
248
+ }
249
+
250
+ private injectCSP(): void {
251
+ // Thêm CSP meta tag nếu chưa có (optional)
252
+ try {
253
+ const existingCSP = this.doc.querySelector('meta[http-equiv="Content-Security-Policy"]');
254
+ if (!existingCSP) {
255
+ const meta = this.doc.createElement('meta');
256
+ meta.httpEquiv = 'Content-Security-Policy';
257
+ meta.content = "navigate-to 'none'"; // Chặn tất cả navigation
258
+ this.doc.head.appendChild(meta);
259
+ console.log('[NavigationBlocker] Injected CSP');
260
+ }
261
+ } catch (error) {
262
+ console.warn('[NavigationBlocker] Could not inject CSP:', error);
263
+ }
264
+ }
265
+
266
+ private handleFormSubmit(form: HTMLFormElement): void {
267
+ const formData = new FormData(form);
268
+ const data: Record<string, any> = {};
269
+ formData.forEach((value, key) => {
270
+ data[key] = value;
271
+ });
272
+
273
+ console.log('[NavigationBlocker] Handling form data:', data);
274
+
275
+ window.dispatchEvent(
276
+ new CustomEvent('iframe-form-submit', {
277
+ detail: { form, data },
278
+ }),
279
+ );
280
+ }
281
+
282
+ private notifyBlockedNavigation(url: string): void {
283
+ console.warn('[NavigationBlocker] Navigation blocked to:', url);
284
+
285
+ window.dispatchEvent(
286
+ new CustomEvent('iframe-navigation-blocked', {
287
+ detail: { url, timestamp: Date.now() },
288
+ }),
289
+ );
290
+
291
+ if (this.shouldShowMessage(url)) {
292
+ this.showBlockedMessage(url);
293
+ }
294
+ }
295
+
296
+ private shouldShowMessage(url: string): boolean {
297
+ return !url.startsWith('#') && url !== 'reload' && url !== 'popup';
298
+ }
299
+
300
+ private showBlockedMessage(url: string): void {
301
+ if (!this.showMessage) return;
302
+
303
+ const message = this.doc.createElement('div');
304
+ message.style.cssText = `
305
+ position: fixed;
306
+ top: 20px;
307
+ right: 20px;
308
+ background: #ff6b6b;
309
+ color: white;
310
+ padding: 12px 20px;
311
+ border-radius: 8px;
312
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
313
+ z-index: 999999;
314
+ font-family: system-ui, -apple-system, sans-serif;
315
+ font-size: 14px;
316
+ max-width: 300px;
317
+ word-break: break-word;
318
+ pointer-events: none;
319
+ `;
320
+
321
+ const shortUrl = url.length > 50 ? url.substring(0, 47) + '...' : url;
322
+ message.innerHTML = `
323
+ <div style="font-weight: 600; margin-bottom: 4px;">🚫 Navigation Blocked</div>
324
+ <div style="font-size: 12px; opacity: 0.9;">${this.escapeHtml(shortUrl)}</div>
325
+ `;
326
+
327
+ this.doc.body.appendChild(message);
328
+
329
+ setTimeout(() => {
330
+ message.style.opacity = '0';
331
+ message.style.transition = 'opacity 0.3s';
332
+ setTimeout(() => message.remove(), 300);
333
+ }, 3000);
334
+ }
335
+
336
+ private escapeHtml(text: string): string {
337
+ const div = this.doc.createElement('div');
338
+ div.textContent = text;
339
+ return div.innerHTML;
340
+ }
341
+
342
+ public enable(): void {
343
+ this.isEnabled = true;
344
+ console.log('[NavigationBlocker] Enabled');
345
+ }
346
+
347
+ public enableMessage(): void {
348
+ this.showMessage = true;
349
+ console.log('[NavigationBlocker] Enabled message');
350
+ }
351
+
352
+ public disable(): void {
353
+ this.isEnabled = false;
354
+ console.log('[NavigationBlocker] Disabled');
355
+ }
356
+
357
+ public disableMessage(): void {
358
+ this.showMessage = false;
359
+ console.log('[NavigationBlocker] Disabled message');
360
+ }
361
+
362
+ public destroy(): void {
363
+ this.isEnabled = false;
364
+ this.showMessage = false;
365
+ // Cleanup observers
366
+ this.observers.forEach((observer) => observer.disconnect());
367
+ this.observers = [];
368
+
369
+ console.log('[NavigationBlocker] Destroyed');
370
+ }
371
+ }