hotwire-native-dev-tools 0.1.0-rc.6 → 0.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.
@@ -1,10 +1,10 @@
1
- var $ = Object.defineProperty;
2
- var L = (i) => {
1
+ var F = Object.defineProperty;
2
+ var T = (i) => {
3
3
  throw TypeError(i);
4
4
  };
5
- var I = (i, t, e) => t in i ? $(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
6
- var l = (i, t, e) => I(i, typeof t != "symbol" ? t + "" : t, e), F = (i, t, e) => t.has(i) || L("Cannot " + e);
7
- var b = (i, t, e) => (F(i, t, "read from private field"), e ? e.call(i) : t.get(i)), g = (i, t, e) => t.has(i) ? L("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(i) : t.set(i, e);
5
+ var q = (i, t, e) => t in i ? F(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
6
+ var d = (i, t, e) => q(i, typeof t != "symbol" ? t + "" : t, e), A = (i, t, e) => t.has(i) || T("Cannot " + e);
7
+ var g = (i, t, e) => (A(i, t, "read from private field"), e ? e.call(i) : t.get(i)), p = (i, t, e) => t.has(i) ? T("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(i) : t.set(i, e);
8
8
  const M = () => `
9
9
  :host {
10
10
  all: initial;
@@ -223,6 +223,8 @@ const M = () => `
223
223
  }
224
224
 
225
225
  .bottom-sheet .content {
226
+ display: flex;
227
+ flex-direction: column;
226
228
  width: 100%;
227
229
  height: 40vh;
228
230
  position: relative;
@@ -336,8 +338,8 @@ const M = () => `
336
338
  height: 100%;
337
339
  overflow: scroll;
338
340
  background-color: hsl(0deg 0% 0% / 80%);
339
- backdrop-filter: blur(3px) saturate(100%);
340
- -webkit-backdrop-filter: blur(3px) saturate(100%);
341
+ backdrop-filter: blur(30px) saturate(250%);
342
+ -webkit-backdrop-filter: blur(30px) saturate(250%);
341
343
  padding-bottom: 7em;
342
344
  }
343
345
  .outer-tab-content.active {
@@ -352,6 +354,25 @@ const M = () => `
352
354
  white-space: normal;
353
355
  }
354
356
 
357
+ .info-card {
358
+ border-radius: 5px;
359
+ background: hsl(0deg 0% 0% / 20%);
360
+ padding: 1em;
361
+ margin-bottom: 1em;
362
+ }
363
+
364
+ .info-card-title {
365
+ font-size: 1em;
366
+ font-weight: 700;
367
+ margin-bottom: 1em;
368
+ display: flex;
369
+ justify-content: space-between;
370
+ }
371
+
372
+ .info-card-hint {
373
+ font-size: 0.8em;
374
+ }
375
+
355
376
  .tab-empty-content {
356
377
  display: flex;
357
378
  justify-content: center;
@@ -634,6 +655,10 @@ const M = () => `
634
655
  overflow: auto;
635
656
  }
636
657
 
658
+ .m-0 {
659
+ margin: 0;
660
+ }
661
+
637
662
  .mt-1 {
638
663
  margin-top: 0.25rem;
639
664
  }
@@ -686,16 +711,16 @@ const M = () => `
686
711
  width: 80%;
687
712
  }
688
713
  `;
689
- var m, u, v;
714
+ var v, f, w;
690
715
  class H {
691
716
  constructor() {
692
- l(this, "printWarning", (t, e = !0, ...o) => {
717
+ d(this, "printWarning", (t, e = !0, ...o) => {
693
718
  e && this.printedWarnings.includes(t) || (console.warn(`DevTools: ${t}`, ...o), this.printedWarnings.push(t));
694
719
  });
695
- l(this, "checkForWarnings", () => {
696
- b(this, m).call(this), b(this, u).call(this), b(this, v).call(this);
720
+ d(this, "checkForWarnings", () => {
721
+ g(this, v).call(this), g(this, f).call(this), g(this, w).call(this);
697
722
  });
698
- g(this, m, () => {
723
+ p(this, v, () => {
699
724
  var t;
700
725
  window.Turbo ? ((t = window.Turbo) == null ? void 0 : t.session.drive) === !1 && setTimeout(() => {
701
726
  var e;
@@ -704,13 +729,13 @@ class H {
704
729
  window.Turbo || this.printWarning("Turbo is not detected. Hotwire Native will not work correctly without Turbo");
705
730
  }, 1e3);
706
731
  });
707
- g(this, u, () => {
732
+ p(this, f, () => {
708
733
  const t = this.turboFrameIds;
709
734
  t.filter((o, s) => t.indexOf(o) !== s).forEach((o) => {
710
735
  this.printWarning(`Multiple Turbo Frames with the same ID '${o}' detected. This can cause unexpected behavior. Ensure that each Turbo Frame has a unique ID.`);
711
736
  });
712
737
  });
713
- g(this, v, () => {
738
+ p(this, w, () => {
714
739
  const t = document.querySelectorAll("[data-turbo-permanent]");
715
740
  t.length !== 0 && t.forEach((e) => {
716
741
  const o = e.id;
@@ -726,29 +751,29 @@ class H {
726
751
  return Array.from(document.querySelectorAll("turbo-frame")).map((t) => t.id);
727
752
  }
728
753
  }
729
- m = new WeakMap(), u = new WeakMap(), v = new WeakMap();
730
- const c = (i) => JSON.parse(localStorage.getItem("hotwire-native-dev-tools") || "{}")[i], d = (i, t) => {
754
+ v = new WeakMap(), f = new WeakMap(), w = new WeakMap();
755
+ const a = (i) => JSON.parse(localStorage.getItem("hotwire-native-dev-tools") || "{}")[i], h = (i, t) => {
731
756
  let e = JSON.parse(localStorage.getItem("hotwire-native-dev-tools") || "{}");
732
757
  e[i] = t, localStorage.setItem("hotwire-native-dev-tools", JSON.stringify(e));
733
- }, q = () => {
758
+ }, z = () => {
734
759
  localStorage.removeItem("hotwire-native-dev-tools");
735
- }, y = () => c("consoleFilterLevels") || {
760
+ }, u = () => a("consoleFilterLevels") || {
736
761
  warn: !0,
737
762
  error: !0,
738
763
  debug: !0,
739
764
  info: !0,
740
765
  log: !0
741
- }, z = (i, t) => {
742
- const e = y();
743
- return e[i] = t, d("consoleFilterLevels", e), e;
744
- }, p = (i, t) => {
766
+ }, N = (i, t) => {
767
+ const e = u();
768
+ return e[i] = t, h("consoleFilterLevels", e), e;
769
+ }, m = (i, t) => {
745
770
  let e = null;
746
771
  return (...o) => {
747
772
  const s = () => i.apply(void 0, o);
748
773
  clearTimeout(e), e = setTimeout(s, t);
749
774
  };
750
- }, { userAgent: E } = window.navigator, A = /iOS/.test(E), N = /Android/.test(E), S = () => A ? "ios" : N ? "android" : "unknown", D = () => {
751
- switch (S()) {
775
+ }, { userAgent: E } = window.navigator, D = /iOS/.test(E), P = /Android/.test(E), L = () => D ? "ios" : P ? "android" : "unknown", O = () => {
776
+ switch (L()) {
752
777
  case "android":
753
778
  return "Android";
754
779
  case "ios":
@@ -756,7 +781,10 @@ const c = (i) => JSON.parse(localStorage.getItem("hotwire-native-dev-tools") ||
756
781
  default:
757
782
  return "<unknown>";
758
783
  }
759
- }, P = `
784
+ }, R = (i) => document.querySelector(`meta[name="${i}"]`), y = (i) => {
785
+ const t = R(i);
786
+ return t && t.content;
787
+ }, j = `
760
788
  <svg width="100%" height="100%" viewBox="0 0 294 320">
761
789
  <g transform="matrix(1,0,0,1,-28.38,-15.268)">
762
790
  <g transform="matrix(1,0,0,1,-462.157,-144.417)">
@@ -764,59 +792,59 @@ const c = (i) => JSON.parse(localStorage.getItem("hotwire-native-dev-tools") ||
764
792
  </g>
765
793
  </g>
766
794
  </svg>
767
- `, R = `
795
+ `, V = `
768
796
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
769
797
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
770
798
  <path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM385 215c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-71-71L280 392c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-214.1-71 71c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9L239 103c9.4-9.4 24.6-9.4 33.9 0L385 215z"/>
771
799
  </svg>
772
- `, j = `
800
+ `, Y = `
773
801
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
774
802
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
775
803
  <path d="M256 0a256 256 0 1 0 0 512A256 256 0 1 0 256 0zM127 297c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l71 71L232 120c0-13.3 10.7-24 24-24s24 10.7 24 24l0 214.1 71-71c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9L273 409c-9.4 9.4-24.6 9.4-33.9 0L127 297z"/>
776
804
  </svg>
777
- `, C = `
805
+ `, S = `
778
806
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
779
807
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
780
808
  <path d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.2 288 416 288c17.7 0 32-14.3 32-32s-14.3-32-32-32l-306.7 0L214.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"/>
781
809
  </svg>
782
- `, f = `
810
+ `, k = `
783
811
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
784
812
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
785
813
  <path d="M135.2 17.7L128 32 32 32C14.3 32 0 46.3 0 64S14.3 96 32 96l384 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-96 0-7.2-14.3C307.4 6.8 296.3 0 284.2 0L163.8 0c-12.1 0-23.2 6.8-28.6 17.7zM416 128L32 128 53.2 467c1.6 25.3 22.6 45 47.9 45l245.8 0c25.3 0 46.3-19.7 47.9-45L416 128z"/>
786
814
  </svg>
787
- `, O = `
815
+ `, W = `
788
816
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
789
817
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
790
818
  <path d="M142.9 142.9c-17.5 17.5-30.1 38-37.8 59.8c-5.9 16.7-24.2 25.4-40.8 19.5s-25.4-24.2-19.5-40.8C55.6 150.7 73.2 122 97.6 97.6c87.2-87.2 228.3-87.5 315.8-1L455 55c6.9-6.9 17.2-8.9 26.2-5.2s14.8 12.5 14.8 22.2l0 128c0 13.3-10.7 24-24 24l-8.4 0c0 0 0 0 0 0L344 224c-9.7 0-18.5-5.8-22.2-14.8s-1.7-19.3 5.2-26.2l41.1-41.1c-62.6-61.5-163.1-61.2-225.3 1zM16 312c0-13.3 10.7-24 24-24l7.6 0 .7 0L168 288c9.7 0 18.5 5.8 22.2 14.8s1.7 19.3-5.2 26.2l-41.1 41.1c62.6 61.5 163.1 61.2 225.3-1c17.5-17.5 30.1-38 37.8-59.8c5.9-16.7 24.2-25.4 40.8-19.5s25.4 24.2 19.5 40.8c-10.8 30.6-28.4 59.3-52.9 83.8c-87.2 87.2-228.3 87.5-315.8 1L57 457c-6.9 6.9-17.2 8.9-26.2 5.2S16 449.7 16 440l0-119.6 0-.7 0-7.6z"/>
791
819
  </svg>
792
- `, V = `
820
+ `, U = `
793
821
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
794
822
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
795
823
  <path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM169.8 165.3c7.9-22.3 29.1-37.3 52.8-37.3l58.3 0c34.9 0 63.1 28.3 63.1 63.1c0 22.6-12.1 43.5-31.7 54.8L280 264.4c-.2 13-10.9 23.6-24 23.6c-13.3 0-24-10.7-24-24l0-13.5c0-8.6 4.6-16.5 12.1-20.8l44.3-25.4c4.7-2.7 7.6-7.7 7.6-13.1c0-8.4-6.8-15.1-15.1-15.1l-58.3 0c-3.4 0-6.4 2.1-7.5 5.3l-.4 1.2c-4.4 12.5-18.2 19-30.6 14.6s-19-18.2-14.6-30.6l.4-1.2zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"/>
796
824
  </svg>
797
- `, Y = `
825
+ `, X = `
798
826
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
799
827
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
800
828
  <path d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z"/>
801
829
  </svg>
802
- `, W = `
830
+ `, J = `
803
831
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
804
832
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
805
833
  <path d="M3.9 54.9C10.5 40.9 24.5 32 40 32l432 0c15.5 0 29.5 8.9 36.1 22.9s4.6 30.5-5.2 42.5L320 320.9 320 448c0 12.1-6.8 23.2-17.7 28.6s-23.8 4.3-33.5-3l-64-48c-8.1-6-12.8-15.5-12.8-25.6l0-79.1L9 97.3C-.7 85.4-2.8 68.8 3.9 54.9z"/>
806
834
  </svg>
807
- `, X = `
835
+ `, G = `
808
836
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 512">
809
837
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
810
838
  <path d="M64 360a56 56 0 1 0 0 112 56 56 0 1 0 0-112zm0-160a56 56 0 1 0 0 112 56 56 0 1 0 0-112zM120 96A56 56 0 1 0 8 96a56 56 0 1 0 112 0z"/>
811
839
  </svg>
812
840
  `;
813
- class U {
841
+ class K {
814
842
  constructor(t) {
815
- l(this, "render", p(() => {
843
+ d(this, "render", m(() => {
816
844
  this.setPosition(), this.createDragItem(), this.setTranslate(this.initialX, this.initialY, this.dragItem), this.addEventListeners();
817
845
  }, 50));
818
- l(this, "animateErrorBorder", p(() => {
819
- if (!this.dragItem || c("errorAnimationEnabled") === !1) return;
846
+ d(this, "animateErrorBorder", m(() => {
847
+ if (!this.dragItem || a("errorAnimationEnabled") === !1) return;
820
848
  let t = this.dragItem.querySelector(".error-border"), e = this.dragItem.querySelector(".error-border circle");
821
849
  t && t.remove();
822
850
  const o = document.createElement("div");
@@ -842,7 +870,7 @@ class U {
842
870
  }
843
871
  setPosition() {
844
872
  this.settingKey = window.innerWidth < window.innerHeight ? "bubblePosPortrait" : "bubblePosLandscape";
845
- const t = { x: window.innerWidth - 100, y: window.innerHeight - 100 }, { x: e, y: o } = c(this.settingKey) || t;
873
+ const t = { x: window.innerWidth - 100, y: window.innerHeight - 100 }, { x: e, y: o } = a(this.settingKey) || t;
846
874
  this.currentX = this.initialX = this.xOffset = e, this.currentY = this.initialY = this.yOffset = o;
847
875
  }
848
876
  createDragItem() {
@@ -852,7 +880,7 @@ class U {
852
880
  this.dragItem = t;
853
881
  return;
854
882
  }
855
- this.dragItem = document.createElement("div"), this.dragItem.id = "floating-bubble", this.dragItem.innerHTML = P, this.devTools.shadowRoot.appendChild(this.dragItem);
883
+ this.dragItem = document.createElement("div"), this.dragItem.id = "floating-bubble", this.dragItem.innerHTML = j, this.devTools.shadowRoot.appendChild(this.dragItem);
856
884
  }
857
885
  addEventListeners() {
858
886
  this.dragItem.hasEventListeners || (this.dragItem.addEventListener("click", this.click.bind(this), { passive: !0 }), this.dragItem.addEventListener("touchstart", this.dragStart.bind(this), { passive: !0 }), this.dragItem.addEventListener("touchend", this.dragEnd.bind(this), { passive: !0 }), this.dragItem.addEventListener("touchmove", this.drag.bind(this), { passive: !0 }), this.dragItem.hasEventListeners = !0);
@@ -867,7 +895,7 @@ class U {
867
895
  t.target.closest("#floating-bubble") && (this.currentlyDragging = !0, this.initialX = t.touches[0].clientX - this.xOffset, this.initialY = t.touches[0].clientY - this.yOffset);
868
896
  }
869
897
  dragEnd() {
870
- this.initialX = this.currentX, this.initialY = this.currentY, this.currentlyDragging = !1, d(this.settingKey, { x: this.currentX, y: this.currentY });
898
+ this.initialX = this.currentX, this.initialY = this.currentY, this.currentlyDragging = !1, h(this.settingKey, { x: this.currentX, y: this.currentY });
871
899
  }
872
900
  drag(t) {
873
901
  if (!this.currentlyDragging) return;
@@ -880,21 +908,39 @@ class U {
880
908
  o.style.transform = `translate3d(${t}px, ${e}px, 0)`;
881
909
  }
882
910
  }
883
- class J {
911
+ class Z {
884
912
  constructor(t) {
885
- l(this, "handleTabClick", (t) => {
913
+ d(this, "handleTabClick", (t) => {
886
914
  const e = t.target.closest(".tablink");
887
915
  if (!e) return;
888
916
  const o = e.dataset.tabId;
889
917
  this.devTools.state.setActiveTab(o), this.updateTabView(o);
890
918
  });
891
- this.devTools = t, this.state = t.state.state, this.sheetHeight = parseInt(c("bottomSheetHeight")) || 55;
919
+ this.devTools = t, this.state = t.state.state, this.sheetHeight = parseInt(a("bottomSheetHeight")) || 55;
892
920
  }
893
921
  render() {
894
922
  this.createBottomSheet(), this.sheetContent = this.bottomSheet.querySelector(".content"), this.sheetOverlay = this.bottomSheet.querySelector(".sheet-overlay"), this.addEventListeners();
895
923
  }
924
+ // Called when the in-memory state changes,
925
+ // such as when a new console or bridge log is captured.
896
926
  update(t) {
897
- this.state = t, this.checkNativeFeatures(), this.renderConsoleLogs(), this.renderBridgeComponents(), this.renderBridgeLogs(), this.renderEvents(), this.renderNativeStack();
927
+ this.state = t, this.checkNativeFeatures(), this.renderConsoleLogs(), this.renderBridgeComponents(), this.renderBridgeLogs(), this.renderEvents(), this.renderNativeStack(), this.scrollToLatestLog(this.state.activeTab), this.state.shouldScrollToLatestLog = !0;
928
+ }
929
+ // Called when another native tab of the mobile app
930
+ // updates devtools-related local storage.
931
+ applySettingsFromStorage() {
932
+ [
933
+ { key: "bottomSheetHeight", setter: (o) => this.updateSheetHeight(o) },
934
+ { key: "activeTab", setter: (o) => this.updateTabView(o) },
935
+ { key: "fontSize", setter: (o) => this.updateFontSize(o) },
936
+ { key: "errorAnimationEnabled", setter: (o) => this.updateErrorAnimation(o) },
937
+ { key: "autoOpen", setter: (o) => this.updateAutoOpen(o) }
938
+ ].forEach(({ key: o, setter: s }) => {
939
+ const n = a(o);
940
+ n !== void 0 && s(n);
941
+ });
942
+ const e = u();
943
+ e && this.updateConsoleFilter(e);
898
944
  }
899
945
  createBottomSheet() {
900
946
  var n;
@@ -903,9 +949,9 @@ class J {
903
949
  this.bottomSheet = t;
904
950
  return;
905
951
  }
906
- const e = this.state.activeTab, o = y(), s = this.state.consoleSearch;
952
+ const e = this.state.activeTab, o = u(), s = this.state.consoleSearch;
907
953
  this.bottomSheet = document.createElement("div"), this.bottomSheet.classList.add("bottom-sheet"), this.bottomSheet.innerHTML = `
908
- <div class="sheet-overlay ${c("bottomSheetPinned") === !0 ? "" : "active"}"></div>
954
+ <div class="sheet-overlay ${a("bottomSheetPinned") === !0 ? "" : "active"}"></div>
909
955
  <div class="content">
910
956
  <div class="top-part">
911
957
  <div class="tablist">
@@ -914,9 +960,10 @@ class J {
914
960
  <button class="tablink ${e === "tab-event-logs" ? "active" : ""}" data-tab-id="tab-event-logs">Events</button>
915
961
  <button class="tablink ${e === "tab-native-stack" ? "active" : ""} d-none" data-tab-id="tab-native-stack">Stack</button>
916
962
  <div class="tablink-settings dropdown d-flex">
917
- <button class="dropdown-trigger tablink-dropdown">${X}</button>
963
+ <button class="dropdown-trigger tablink-dropdown">${G}</button>
918
964
  <div class="dropdown-content settings-dropdown">
919
965
  <button class="btn-switch-to-single-tab-sheet" data-tab-id="single-tab-settings">Settings</button>
966
+ <button class="btn-switch-to-single-tab-sheet" data-tab-id="single-tab-info">Info</button>
920
967
  <button class="pin-bottom-sheet">Pin Bottom Sheet</button>
921
968
  </div>
922
969
  </div>
@@ -924,13 +971,13 @@ class J {
924
971
 
925
972
  <div class="tab-action-bars">
926
973
  <div class="tab-action-bar tab-bridge-components ${e === "tab-bridge-components" ? "active" : ""}">
927
- <button class="btn-icon btn-clear-tab btn-clear-bridge-logs">${f}</button>
974
+ <button class="btn-icon btn-clear-tab btn-clear-bridge-logs">${k}</button>
928
975
  </div>
929
976
  <div class="tab-action-bar d-flex flex-column tab-console-logs ${e === "tab-console-logs" ? "active" : ""}">
930
977
  <div class="d-flex">
931
- <button class="btn-icon btn-search-console">${Y}</button>
978
+ <button class="btn-icon btn-search-console">${X}</button>
932
979
  <div class="dropdown">
933
- <button class="dropdown-trigger btn-icon">${W}</button>
980
+ <button class="dropdown-trigger btn-icon">${J}</button>
934
981
  <div class="dropdown-content console-filter-levels">
935
982
  <label><input type="checkbox" ${o.warn ? "checked" : ""} data-console-filter="warn" /> Warnings</label>
936
983
  <label><input type="checkbox" ${o.error ? "checked" : ""} data-console-filter="error" /> Errors</label>
@@ -939,7 +986,7 @@ class J {
939
986
  <label><input type="checkbox" ${o.log ? "checked" : ""} data-console-filter="log" /> Logs</label>
940
987
  </div>
941
988
  </div>
942
- <button class="btn-icon btn-clear-tab btn-clear-console-logs">${f}</button>
989
+ <button class="btn-icon btn-clear-tab btn-clear-console-logs">${k}</button>
943
990
  </div>
944
991
 
945
992
  <div class="console-search mt-2 ${s ? "" : "d-none"}">
@@ -947,10 +994,10 @@ class J {
947
994
  </div>
948
995
  </div>
949
996
  <div class="tab-action-bar tab-event-logs ${e === "tab-event-logs" ? "active" : ""}">
950
- <button class="btn-icon btn-clear-tab btn-clear-events">${f}</button>
997
+ <button class="btn-icon btn-clear-tab btn-clear-events">${k}</button>
951
998
  </div>
952
999
  <div class="tab-action-bar tab-native-stack ${e === "tab-native-stack" ? "active" : ""}">
953
- <button class="btn-icon btn-reload-tab btn-reload-stack">${O}</button>
1000
+ <button class="btn-icon btn-reload-tab btn-reload-stack">${W}</button>
954
1001
  </div>
955
1002
  </div>
956
1003
  </div>
@@ -964,7 +1011,7 @@ class J {
964
1011
  <div id="bridge-components-collapse" class="collapse-target">
965
1012
  <div class="d-flex justify-content-between border-bottom">
966
1013
  <div class="tab-content-bridge-components flex-grow-1"></div>
967
- <button class="btn-icon btn-help btn-switch-to-single-tab-sheet mt-1" data-tab-id="single-tab-bridge-component-help">${V}</button>
1014
+ <button class="btn-icon btn-help btn-switch-to-single-tab-sheet mt-1" data-tab-id="single-tab-bridge-component-help">${U}</button>
968
1015
  </div>
969
1016
  </div>
970
1017
 
@@ -991,10 +1038,10 @@ class J {
991
1038
  <div id="single-tab-bridge-component-help" class="single-tab-content outer-tab-content">
992
1039
  <div class="inner-tab-content">
993
1040
  <div class="d-flex align-items-center mb-3">
994
- <button class="btn-icon btn-close-single-mode">${C}</button>
1041
+ <button class="btn-icon btn-close-single-mode">${S}</button>
995
1042
  <h3 class="ms-1">Bridge Components</h3>
996
1043
  </div>
997
- <p>This list shows all the bridge components that the ${D()} app supports. Components that are active on this page are marked with a green dot.</p>
1044
+ <p>This list shows all the bridge components that the ${O()} app supports. Components that are active on this page are marked with a green dot.</p>
998
1045
  <h3 class="mt-4">Why is my bridge component not on the list?</h3>
999
1046
  <p class="mt-2">Bridge components are automatically detected when they are registered in the native code. If your component is not on the list, make sure it is registered correctly.</p>
1000
1047
  ${this.registerBridgeComponentExample()}
@@ -1006,7 +1053,7 @@ class J {
1006
1053
  <div id="single-tab-settings" class="single-tab-content outer-tab-content">
1007
1054
  <div class="inner-tab-content">
1008
1055
  <div class="d-flex align-items-center mb-3">
1009
- <button class="btn-icon btn-close-single-mode">${C}</button>
1056
+ <button class="btn-icon btn-close-single-mode">${S}</button>
1010
1057
  <h3 class="ms-1">Settings</h3>
1011
1058
  </div>
1012
1059
  <div class="mb-3">
@@ -1018,25 +1065,65 @@ class J {
1018
1065
  </div>
1019
1066
  <div class="mb-4">
1020
1067
  <label for="font-size-setting"> Font Size</label>
1021
- <input type="range" id="font-size-setting" class="w-100" min="8" max="24" value="${c("fontSize") || 16}" step="1" list="font-size-setting-markers" />
1068
+ <input type="range" id="font-size-setting" class="w-100" min="8" max="24" value="${a("fontSize") || 16}" step="1" list="font-size-setting-markers" />
1022
1069
  <datalist id="font-size-setting-markers">
1023
1070
  <option value="16"></option>
1024
1071
  </datalist>
1025
1072
  </div>
1026
1073
  <div class="mb-3">
1027
1074
  <label class="toggle">
1028
- <input class="toggle-checkbox" type="checkbox" id="console-error-animation-setting" ${c("errorAnimationEnabled") !== !1 ? "checked" : ""} />
1075
+ <input class="toggle-checkbox" type="checkbox" id="console-error-animation-setting" ${a("errorAnimationEnabled") !== !1 ? "checked" : ""} />
1029
1076
  <div class="toggle-switch"></div>
1030
1077
  <span class="toggle-label">Console Error Animation</span>
1031
1078
  </label>
1032
1079
  </div>
1033
1080
  <div class="mb-3">
1034
1081
  <label class="toggle">
1035
- <input class="toggle-checkbox" type="checkbox" id="auto-open-setting" ${c("autoOpen") === !0 ? "checked" : ""} />
1082
+ <input class="toggle-checkbox" type="checkbox" id="auto-open-setting" ${a("autoOpen") === !0 ? "checked" : ""} />
1036
1083
  <div class="toggle-switch"></div>
1037
1084
  <span class="toggle-label">Auto Open</span>
1038
1085
  </label>
1039
1086
  </div>
1087
+ <div class="mb-3">
1088
+ <label class="toggle">
1089
+ <input class="toggle-checkbox" type="checkbox" id="scroll-to-latest-log-setting" ${a("scrollToLatestLog") === !0 ? "checked" : ""} />
1090
+ <div class="toggle-switch"></div>
1091
+ <span class="toggle-label">Automatically Scroll to New Logs</span>
1092
+ </label>
1093
+ </div>
1094
+ </div>
1095
+ </div>
1096
+
1097
+ <div id="single-tab-info" class="single-tab-content outer-tab-content">
1098
+ <div class="inner-tab-content">
1099
+ <div class="d-flex align-items-center mb-3">
1100
+ <button class="btn-icon btn-close-single-mode">${S}</button>
1101
+ <h3 class="ms-1">Info</h3>
1102
+ </div>
1103
+ <div class="info-card">
1104
+ <div class="info-card-title">Current URL</div>
1105
+ <div class="current-url">${this.currentUrl}</div>
1106
+ </div>
1107
+ <div class="info-card">
1108
+ <div class="info-card-title">User Agent</div>
1109
+ <div class="user-agent">${navigator.userAgent}</div>
1110
+ </div>
1111
+ <div class="info-card">
1112
+ <div class="info-card-title"><pre class="m-0">turbo-cache-control:</pre> <span>${y("turbo-cache-control") || "-"}</span></div>
1113
+ <div class="info-card-hint"><strong>no-cache:</strong> always fetched from the network, even on restore</div>
1114
+ <div class="info-card-hint"><strong>no-preview:</strong> skipped in preview, used only on restore</div>
1115
+ <div class="info-card-hint"><strong>unset:</strong> shows cached preview if the cache is valid</div>
1116
+ </div>
1117
+ <div class="info-card">
1118
+ <div class="info-card-title"><pre class="m-0">turbo-refresh-method:</pre> <span>${y("turbo-refresh-method") || "-"}</span></div>
1119
+ <div class="info-card-hint"><strong>replace (default):</strong> replaces the entire &lt;body&gt; on revisit</div>
1120
+ <div class="info-card-hint"><strong>morph:</strong> updates only changed DOM elements, preserving state</div>
1121
+ </div>
1122
+ <div class="info-card">
1123
+ <div class="info-card-title"><pre class="m-0">turbo-visit-control:</pre> <span>${y("turbo-visit-control") || "-"}</span></div>
1124
+ <div class="info-card-hint"><strong>reload:</strong> forces a full page reload</div>
1125
+ <div class="info-card-hint"><strong>unset:</strong> allows Turbo to handle the visit normally</div>
1126
+ </div>
1040
1127
  </div>
1041
1128
  </div>
1042
1129
  </div>
@@ -1044,7 +1131,7 @@ class J {
1044
1131
  `, this.devTools.shadowRoot.appendChild(this.bottomSheet);
1045
1132
  }
1046
1133
  renderConsoleLogs() {
1047
- const t = this.bottomSheet.querySelector(".tab-content-console-logs"), e = y(), o = this.state.consoleSearch;
1134
+ const t = this.bottomSheet.querySelector(".tab-content-console-logs"), e = u(), o = this.state.consoleSearch;
1048
1135
  t.innerHTML = this.state.consoleLogs.length ? this.state.consoleLogs.filter((s) => e[s.type]).filter((s) => o ? s.message.toLowerCase().includes(o.toLowerCase()) : !0).map((s) => this.consoleLogHTML(s.type, s.message, s.time)).join("") : '<div class="tab-empty-content"><span>No console logs yet</span></div>';
1049
1136
  }
1050
1137
  renderBridgeComponents() {
@@ -1069,7 +1156,7 @@ class J {
1069
1156
  return `
1070
1157
  <div class="log-entry d-flex gap-3 pt-2 pb-2">
1071
1158
  <div class="log-entry-icon d-flex justify-content-center align-items-center">
1072
- ${t === "send" ? j : R}
1159
+ ${t === "send" ? Y : V}
1073
1160
  </div>
1074
1161
  <div class="w-100 overflow-auto">
1075
1162
  <div class="d-flex justify-content-between">
@@ -1077,9 +1164,9 @@ class J {
1077
1164
  <small>${n}</small>
1078
1165
  </div>
1079
1166
  <div class="overflow-auto">
1080
- ${Object.entries(s).map(([r, a]) => {
1081
- const w = typeof a == "object" && a !== null ? JSON.stringify(a) : a;
1082
- return `<div class="white-space-collapse">${r}: ${w}</div>`;
1167
+ ${Object.entries(s).map(([r, c]) => {
1168
+ const b = typeof c == "object" && c !== null ? JSON.stringify(c) : c;
1169
+ return `<div class="white-space-collapse">${r}: ${b}</div>`;
1083
1170
  }).join("")}
1084
1171
  </div>
1085
1172
  </div>
@@ -1115,8 +1202,8 @@ class J {
1115
1202
  `;
1116
1203
  }
1117
1204
  nativeViewStackHTML(t) {
1118
- var x;
1119
- const e = ["UINavigationController", "NavigatorHost"].includes(t.type), o = t.type === "UITabBarController", s = ["VisitableViewController", "HotwireWebFragment", "BackStackEntry"].includes(t.type), r = `viewstack-card ${t.url === this.currentUrl ? "current-view" : ""} ${e ? "main-view" : s ? "hotwire-view" : o ? "tab-container" : "non-identified-view"}`, a = "viewstack-" + Math.random().toString(16).slice(2), w = t.url ? `<div class="view-url">
1205
+ var C;
1206
+ const e = (l) => l == null ? void 0 : l.replace(/\/+$/, ""), o = ["UINavigationController", "NavigatorHost"].includes(t.type), s = t.type === "UITabBarController", n = ["VisitableViewController", "HotwireWebFragment", "BackStackEntry"].includes(t.type), c = `viewstack-card ${e(t.url) === e(this.currentUrl) ? "current-view" : ""} ${o ? "main-view" : n ? "hotwire-view" : s ? "tab-container" : "non-identified-view"}`, b = "viewstack-" + Math.random().toString(16).slice(2), B = t.url ? `<div class="view-url">
1120
1207
  ${(() => {
1121
1208
  try {
1122
1209
  return new URL(t.url).pathname;
@@ -1124,31 +1211,31 @@ class J {
1124
1211
  return t.url;
1125
1212
  }
1126
1213
  })()}
1127
- </div>` : "", k = (() => {
1214
+ </div>` : "", x = (() => {
1128
1215
  try {
1129
- const h = t.pathConfigurationProperties;
1130
- return JSON.stringify(typeof h == "string" ? JSON.parse(h) : h, null, 2);
1216
+ const l = t.pathConfigurationProperties;
1217
+ return JSON.stringify(typeof l == "string" ? JSON.parse(l) : l, null, 2);
1131
1218
  } catch {
1132
1219
  return t.pathConfigurationProperties;
1133
1220
  }
1134
- })(), T = k ? `<pre class="view-path-configuration">${k}</pre>` : "", B = (x = t.children) != null && x.length ? `<div class="child-container">
1135
- ${t.children.map((h) => this.nativeViewStackHTML(h)).join("")}
1221
+ })(), $ = x ? `<pre class="view-path-configuration">${x}</pre>` : "", I = (C = t.children) != null && C.length ? `<div class="child-container">
1222
+ ${t.children.map((l) => this.nativeViewStackHTML(l)).join("")}
1136
1223
  </div>` : "";
1137
1224
  return `
1138
1225
  <div>
1139
- <div class="${r} collapse no-chevron" data-collapse-target="path-configuration-properties-${a}">
1226
+ <div class="${c} collapse no-chevron" data-collapse-target="path-configuration-properties-${b}">
1140
1227
  <div>
1141
1228
  <div class="view-title">
1142
1229
  ${t.title == "null" ? "" : t.title}
1143
1230
  <div class="view-title-details">${t.type}</div>
1144
1231
  </div>
1145
- ${w}
1232
+ ${B}
1146
1233
  </div>
1147
- <div id="path-configuration-properties-${a}" class="collapse-target">
1148
- ${T}
1234
+ <div id="path-configuration-properties-${b}" class="collapse-target">
1235
+ ${$}
1149
1236
  </div>
1150
1237
  </div>
1151
- ${B}
1238
+ ${I}
1152
1239
  </div>
1153
1240
  `;
1154
1241
  }
@@ -1161,7 +1248,7 @@ class J {
1161
1248
  });
1162
1249
  }
1163
1250
  registerBridgeComponentExample() {
1164
- switch (S()) {
1251
+ switch (L()) {
1165
1252
  case "android":
1166
1253
  return `
1167
1254
  <pre class="overflow-auto">
@@ -1182,7 +1269,7 @@ class J {
1182
1269
  }
1183
1270
  }
1184
1271
  registerBridgeComponentHelpURL() {
1185
- switch (S()) {
1272
+ switch (L()) {
1186
1273
  case "android":
1187
1274
  return "https://native.hotwired.dev/android/bridge-components";
1188
1275
  case "ios":
@@ -1218,7 +1305,7 @@ class J {
1218
1305
  const e = t.closest("input[type='checkbox']");
1219
1306
  if (!e) return;
1220
1307
  const o = e.dataset.consoleFilter, s = e.checked;
1221
- z(o, s), this.renderConsoleLogs();
1308
+ N(o, s), this.renderConsoleLogs();
1222
1309
  }), this.bottomSheet.querySelector(".btn-search-console").addEventListener("click", () => {
1223
1310
  const t = this.bottomSheet.querySelector(".console-search");
1224
1311
  t.classList.toggle("d-none"), t.querySelector("input").focus();
@@ -1226,24 +1313,26 @@ class J {
1226
1313
  this.devTools.state.setConsoleSearchValue(t.target.value.toLowerCase()), this.renderConsoleLogs();
1227
1314
  }), this.bottomSheet.querySelector("#bottom-sheet-height-setting").addEventListener("change", (t) => {
1228
1315
  const e = t.target.value;
1229
- this.sheetHeight = parseInt(e), d("bottomSheetHeight", e), this.updateSheetHeight(e);
1316
+ this.sheetHeight = parseInt(e), h("bottomSheetHeight", e), this.updateSheetHeight(e);
1230
1317
  }), this.bottomSheet.querySelector("#console-error-animation-setting").addEventListener("change", (t) => {
1231
- d("errorAnimationEnabled", t.target.checked);
1318
+ h("errorAnimationEnabled", t.target.checked);
1232
1319
  }), this.bottomSheet.querySelector("#font-size-setting").addEventListener("change", (t) => {
1233
1320
  let e = t.target.value;
1234
- e = Math.max(8, Math.min(24, e)), d("fontSize", e), this.devTools.setCSSProperty("--font-size", `${e}px`);
1321
+ e = Math.max(8, Math.min(24, e)), h("fontSize", e), this.devTools.setCSSProperty("--font-size", `${e}px`);
1235
1322
  }), this.bottomSheet.querySelector("#auto-open-setting").addEventListener("change", (t) => {
1236
- d("autoOpen", t.target.checked);
1323
+ h("autoOpen", t.target.checked);
1324
+ }), this.bottomSheet.querySelector("#scroll-to-latest-log-setting").addEventListener("change", (t) => {
1325
+ h("scrollToLatestLog", t.target.checked);
1237
1326
  }), this.bottomSheet.querySelector(".pin-bottom-sheet").addEventListener("click", () => {
1238
- const t = c("bottomSheetPinned") === !0;
1239
- d("bottomSheetPinned", !t), this.sheetOverlay.classList.toggle("active"), this.bottomSheet.querySelector(".settings-dropdown").classList.remove("dropdown-open");
1327
+ const t = a("bottomSheetPinned") === !0;
1328
+ h("bottomSheetPinned", !t), this.sheetOverlay.classList.toggle("active"), this.bottomSheet.querySelector(".settings-dropdown").classList.remove("dropdown-open");
1240
1329
  }), this.bottomSheet.addEventListener("click", (t) => {
1241
1330
  const e = t.target.closest(".collapse");
1242
1331
  if (e && this.bottomSheet.contains(e)) {
1243
1332
  const n = e.getAttribute("data-collapse-target"), r = this.bottomSheet.querySelector(`#${n}`);
1244
1333
  if (r) {
1245
- const a = e.classList.toggle("active");
1246
- r.classList.toggle("active", a);
1334
+ const c = e.classList.toggle("active");
1335
+ r.classList.toggle("active", c);
1247
1336
  }
1248
1337
  return;
1249
1338
  }
@@ -1257,6 +1346,12 @@ class J {
1257
1346
  });
1258
1347
  }), this.bottomSheet.hasEventListeners = !0);
1259
1348
  }
1349
+ updateConsoleFilter(t) {
1350
+ this.bottomSheet.querySelectorAll(".console-filter-levels input[type='checkbox']").forEach((e) => {
1351
+ const o = e.dataset.consoleFilter, s = t[o];
1352
+ e.checked = s;
1353
+ });
1354
+ }
1260
1355
  toggleDropdown(t) {
1261
1356
  const e = t.nextElementSibling || t.closest(".dropdown").querySelector(".dropdown-content");
1262
1357
  this.bottomSheet.querySelectorAll(".dropdown-content.dropdown-open").forEach((o) => {
@@ -1264,14 +1359,17 @@ class J {
1264
1359
  }), e.classList.toggle("dropdown-open");
1265
1360
  }
1266
1361
  updateTabView(t) {
1267
- this.devTools.shadowRoot.querySelectorAll(".tablink, .outer-tab-content").forEach((e) => e.classList.remove("active")), this.devTools.shadowRoot.querySelectorAll(".tab-action-bar").forEach((e) => e.classList.remove("active")), this.devTools.shadowRoot.querySelector(`[data-tab-id="${t}"]`).classList.add("active"), this.devTools.shadowRoot.getElementById(t).classList.add("active"), this.devTools.shadowRoot.querySelector(`.tab-action-bar.${t}`).classList.add("active");
1362
+ this.devTools.shadowRoot.querySelectorAll(".tablink, .outer-tab-content").forEach((e) => e.classList.remove("active")), this.devTools.shadowRoot.querySelectorAll(".tab-action-bar").forEach((e) => e.classList.remove("active")), this.devTools.shadowRoot.querySelector(`[data-tab-id="${t}"]`).classList.add("active"), this.devTools.shadowRoot.getElementById(t).classList.add("active"), this.devTools.shadowRoot.querySelector(`.tab-action-bar.${t}`).classList.add("active"), this.state.shouldScrollToLatestLog && (this.scrollToLatestLog(t), this.state.shouldScrollToLatestLog = !1);
1363
+ }
1364
+ scrollToLatestLog(t) {
1365
+ a("scrollToLatestLog") == !0 && requestAnimationFrame(() => {
1366
+ const e = this.devTools.shadowRoot.getElementById(t), o = e == null ? void 0 : e.querySelector(".log-entry:last-child");
1367
+ o == null || o.scrollIntoView({ behavior: "instant", block: "center" });
1368
+ });
1268
1369
  }
1269
1370
  showBottomSheet() {
1270
1371
  this.bottomSheet.classList.contains("show") || (this.bottomSheet.classList.add("show"), this.originalOverflow = document.body.style.overflow, document.body.style.overflow = "hidden", this.updateSheetHeight(this.sheetHeight));
1271
1372
  }
1272
- updateSheetHeight(t) {
1273
- this.sheetContent.style.height = `${t}vh`;
1274
- }
1275
1373
  hideBottomSheet() {
1276
1374
  this.bottomSheet.classList.remove("show"), document.body.style.overflow = this.originalOverflow;
1277
1375
  }
@@ -1293,6 +1391,15 @@ class J {
1293
1391
  const t = 10, e = parseInt(this.sheetContent.style.height), o = Math.max(0, this.sheetHeight - t), s = Math.min(100, this.sheetHeight + t);
1294
1392
  e < o ? this.hideBottomSheet() : e > s ? this.updateSheetHeight(100) : this.updateSheetHeight(this.sheetHeight);
1295
1393
  }
1394
+ updateFontSize(t) {
1395
+ this.devTools.setCSSProperty("--font-size", `${t}px`), this.bottomSheet.querySelector("#font-size-setting").value = t;
1396
+ }
1397
+ updateErrorAnimation(t) {
1398
+ this.bottomSheet.querySelector("#console-error-animation-setting").checked = t;
1399
+ }
1400
+ updateAutoOpen(t) {
1401
+ this.bottomSheet.querySelector("#auto-open-setting").checked = t;
1402
+ }
1296
1403
  // Helper function to log messages, without causing a rerender of the bottom sheet
1297
1404
  // (Messages with a `HotwireDevTools` prefix will not be logged in the bottom sheet)
1298
1405
  log(t) {
@@ -1307,7 +1414,7 @@ class J {
1307
1414
  return window.location.href;
1308
1415
  }
1309
1416
  }
1310
- class G {
1417
+ class Q {
1311
1418
  constructor() {
1312
1419
  this.state = {
1313
1420
  consoleLogs: [],
@@ -1318,7 +1425,7 @@ class G {
1318
1425
  bridgeIsConnected: !1,
1319
1426
  supportsNativeStackView: !1,
1320
1427
  consoleSearch: "",
1321
- activeTab: c("activeTab") || "tab-bridge-components"
1428
+ activeTab: this.storedActiveTab
1322
1429
  }, this.listeners = [];
1323
1430
  }
1324
1431
  subscribe(t) {
@@ -1361,16 +1468,22 @@ class G {
1361
1468
  this.state.eventLogs = [], this.notify();
1362
1469
  }
1363
1470
  setActiveTab(t) {
1364
- this.state.activeTab = t, d("activeTab", t);
1471
+ this.state.activeTab = t, h("activeTab", t);
1365
1472
  }
1366
1473
  setConsoleSearchValue(t) {
1367
1474
  this.state.consoleSearch = t;
1368
1475
  }
1476
+ updateLocalStorageSettings() {
1477
+ this.state.activeTab = this.storedActiveTab;
1478
+ }
1369
1479
  get currentTime() {
1370
1480
  return (/* @__PURE__ */ new Date()).toLocaleTimeString();
1371
1481
  }
1482
+ get storedActiveTab() {
1483
+ return a("activeTab") || "tab-bridge-components";
1484
+ }
1372
1485
  }
1373
- class K {
1486
+ class _ {
1374
1487
  bridgeIsConnected() {
1375
1488
  var t, e;
1376
1489
  return !!((t = window.HotwireNative) != null && t.web || (e = window.Strada) != null && e.web);
@@ -1404,21 +1517,21 @@ class K {
1404
1517
  return ((t = window.HotwireNative) == null ? void 0 : t.web) || ((e = window.Strada) == null ? void 0 : e.web);
1405
1518
  }
1406
1519
  }
1407
- class Z {
1520
+ class tt {
1408
1521
  constructor(t = {}) {
1409
- l(this, "update", p((t) => {
1522
+ d(this, "update", m((t) => {
1410
1523
  this.bottomSheet.update(t);
1411
1524
  }, 200));
1412
1525
  // Fetch the current stack from the native side
1413
1526
  // The debounce on this function is intentionally high,
1414
1527
  // to ensure the native side has enough time to set the ViewController / Fragment titles.
1415
1528
  // With a lower debounce, the view controller / fragment title would often be empty.
1416
- l(this, "fetchNativeStack", p(() => {
1529
+ d(this, "fetchNativeStack", m(() => {
1417
1530
  this.nativeBridge.send("currentStackInfo", {}, (t) => {
1418
1531
  this.state.setSupportsNativeStack(!0), this.state.setNativeStack(t.data.stack);
1419
1532
  });
1420
1533
  }, 1e3));
1421
- l(this, "injectCSSToShadowRoot", async () => {
1534
+ d(this, "injectCSSToShadowRoot", async () => {
1422
1535
  if (this.shadowRoot.querySelector("style")) return;
1423
1536
  const t = document.createElement("style");
1424
1537
  t.textContent = M(), this.shadowRoot.appendChild(t);
@@ -1427,7 +1540,7 @@ class Z {
1427
1540
  enabled: !0,
1428
1541
  reset: !1,
1429
1542
  ...t
1430
- }, this.options.enabled && (this.options.reset && q(), this.state = new G(), this.bubble = new U(this), this.bottomSheet = new J(this), this.nativeBridge = new K(this), this.diagnosticsChecker = new H(), this.state.subscribe(this.update.bind(this)), this.listenForTurboEvents());
1543
+ }, this.options.enabled && (this.options.reset && z(), this.state = new Q(), this.bubble = new K(this), this.bottomSheet = new Z(this), this.nativeBridge = new _(this), this.diagnosticsChecker = new H(), this.state.subscribe(this.update.bind(this)), this.listenForTurboEvents());
1431
1544
  }
1432
1545
  // Setup gets called initially and on every turbo:load event, eg. when navigating to a new page
1433
1546
  setup() {
@@ -1435,7 +1548,7 @@ class Z {
1435
1548
  this.nativeBridgeGotConnected();
1436
1549
  }), this.addEventListeners(), this.diagnosticsChecker.checkForWarnings(), this.bubble.onClick(() => {
1437
1550
  this.bottomSheet.showBottomSheet(), this.nativeBridge.send("vibrate");
1438
- }), c("autoOpen") === !0 && this.bottomSheet.showBottomSheet());
1551
+ }), a("autoOpen") === !0 && this.bottomSheet.showBottomSheet());
1439
1552
  }
1440
1553
  nativeBridgeGotConnected() {
1441
1554
  var t, e;
@@ -1451,7 +1564,7 @@ class Z {
1451
1564
  this.shadowRoot = this.shadowContainer.shadowRoot, this.injectCSSToShadowRoot();
1452
1565
  return;
1453
1566
  }
1454
- this.shadowRoot = this.shadowContainer.attachShadow({ mode: "open" }), this.setCSSProperty("--font-size", `${c("fontSize") || 16}px`), this.injectCSSToShadowRoot();
1567
+ this.shadowRoot = this.shadowContainer.attachShadow({ mode: "open" }), this.setCSSProperty("--font-size", `${a("fontSize") || 16}px`), this.injectCSSToShadowRoot();
1455
1568
  }
1456
1569
  addBridgeProxy() {
1457
1570
  const t = () => ({
@@ -1472,14 +1585,14 @@ class Z {
1472
1585
  }
1473
1586
  interceptedBridgeMessage(t, e) {
1474
1587
  e.forEach((o) => {
1475
- const s = o.component, n = o.event, { metadata: r, ...a } = o.data;
1476
- s !== "dev-tools" && this.state.addBridgeLog(t, s, n, a);
1588
+ const s = o.component, n = o.event, { metadata: r, ...c } = o.data;
1589
+ s !== "dev-tools" && this.state.addBridgeLog(t, s, n, c);
1477
1590
  });
1478
1591
  }
1479
1592
  interceptedConsoleMessage(t, e) {
1480
1593
  const o = e.map((s) => {
1481
1594
  if (s instanceof Element) {
1482
- const r = Array.from(s.attributes).map((a) => `${a.name}="${a.value}"`).join(" ");
1595
+ const r = Array.from(s.attributes).map((c) => `${c.name}="${c.value}"`).join(" ");
1483
1596
  return `&lt;${s.tagName.toLowerCase()}${r ? " " + r : ""}&gt;&lt;/${s.tagName.toLowerCase()}&gt;`;
1484
1597
  }
1485
1598
  if (typeof s == "object")
@@ -1510,7 +1623,9 @@ class Z {
1510
1623
  this.bubble.render();
1511
1624
  },
1512
1625
  { passive: !0 }
1513
- ), this.hasEventListeners = !0);
1626
+ ), window.addEventListener("storage", (t) => {
1627
+ t.key === "hotwire-native-dev-tools" && (this.state.updateLocalStorageSettings(), this.bubble.render(), this.bottomSheet.update(this.state.state), this.bottomSheet.applySettingsFromStorage());
1628
+ }), this.hasEventListeners = !0);
1514
1629
  }
1515
1630
  listenForTurboEvents() {
1516
1631
  if (this.eventsRegistered) return;
@@ -1576,8 +1691,8 @@ class Z {
1576
1691
  return (/* @__PURE__ */ new Date()).toLocaleTimeString();
1577
1692
  }
1578
1693
  }
1579
- const _ = (i = {}) => {
1580
- const t = new Z(i);
1694
+ const ot = (i = {}) => {
1695
+ const t = new tt(i);
1581
1696
  t.options.enabled && (t.setup(), document.addEventListener(
1582
1697
  "turbo:load",
1583
1698
  () => {
@@ -1587,6 +1702,6 @@ const _ = (i = {}) => {
1587
1702
  ));
1588
1703
  };
1589
1704
  export {
1590
- _ as setupDevTools
1705
+ ot as setupDevTools
1591
1706
  };
1592
1707
  //# sourceMappingURL=hotwire-native-dev-tools.es.js.map