hotwire-native-dev-tools 0.2.0 → 0.3.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,11 +1,4 @@
1
- var F = Object.defineProperty;
2
- var T = (i) => {
3
- throw TypeError(i);
4
- };
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
- const M = () => `
1
+ const E = () => `
9
2
  :host {
10
3
  all: initial;
11
4
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important;
@@ -65,6 +58,13 @@ const M = () => `
65
58
  fill: white;
66
59
  }
67
60
 
61
+ .icon--black svg {
62
+ fill: black;
63
+ }
64
+ .icon--muted svg {
65
+ fill: #6c6c6c;
66
+ }
67
+
68
68
  /* Dropdown */
69
69
  .dropdown-content {
70
70
  display: none;
@@ -103,10 +103,20 @@ const M = () => `
103
103
  align-items: center;
104
104
  }
105
105
 
106
- .dropdown-content button:not(:first-child) {
106
+ .dropdown-content .dropdown-btn-full-width:not(:first-child),
107
+ .dropdown-content .dropdown-entry:not(:first-child) {
107
108
  border-top: 1px solid #cecdcd;
108
109
  }
109
110
 
111
+ .dropdown--right .dropdown-content {
112
+ right: 1em;
113
+ }
114
+
115
+ .dropdown--scrollable .dropdown-content {
116
+ overflow-y: auto;
117
+ max-height: 100%;
118
+ }
119
+
110
120
  .settings-dropdown {
111
121
  right: 0;
112
122
  top: 2rem;
@@ -604,6 +614,10 @@ const M = () => `
604
614
  text-align: center;
605
615
  }
606
616
 
617
+ .text-muted {
618
+ color: #6c6c6c;
619
+ }
620
+
607
621
  .text-ellipsis {
608
622
  text-overflow: ellipsis;
609
623
  white-space: nowrap;
@@ -707,55 +721,48 @@ const M = () => `
707
721
  width: 100%;
708
722
  }
709
723
 
724
+ .w-auto {
725
+ width: auto !important;
726
+ }
727
+
710
728
  .w-80 {
711
729
  width: 80%;
712
730
  }
713
731
  `;
714
- var v, f, w;
715
- class H {
732
+ class T {
716
733
  constructor() {
717
- d(this, "printWarning", (t, e = !0, ...o) => {
718
- e && this.printedWarnings.includes(t) || (console.warn(`DevTools: ${t}`, ...o), this.printedWarnings.push(t));
719
- });
720
- d(this, "checkForWarnings", () => {
721
- g(this, v).call(this), g(this, f).call(this), g(this, w).call(this);
722
- });
723
- p(this, v, () => {
724
- var t;
725
- window.Turbo ? ((t = window.Turbo) == null ? void 0 : t.session.drive) === !1 && setTimeout(() => {
726
- var e;
727
- ((e = window.Turbo) == null ? void 0 : e.session.drive) === !1 && this.printWarning("Turbo Drive is disabled. Hotwire Native will not work correctly without Turbo Drive");
728
- }, 1e3) : setTimeout(() => {
729
- window.Turbo || this.printWarning("Turbo is not detected. Hotwire Native will not work correctly without Turbo");
730
- }, 1e3);
731
- });
732
- p(this, f, () => {
733
- const t = this.turboFrameIds;
734
- t.filter((o, s) => t.indexOf(o) !== s).forEach((o) => {
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.`);
736
- });
737
- });
738
- p(this, w, () => {
739
- const t = document.querySelectorAll("[data-turbo-permanent]");
740
- t.length !== 0 && t.forEach((e) => {
741
- const o = e.id;
742
- if (o === "" && this.printWarning("Turbo Permanent Element detected without an ID. Turbo Permanent Elements must have a unique ID to work correctly.", !0, e), o && document.querySelectorAll(`#${o}`).length > 1) {
743
- const n = `Turbo Permanent Element with ID '${o}' doesn't have a unique ID. Turbo Permanent Elements must have a unique ID to work correctly.`;
744
- this.printWarning(n, !0, e);
745
- }
746
- });
747
- });
748
734
  this.printedWarnings = [];
749
735
  }
736
+ printWarning = (t, e = !0, ...o) => {
737
+ e && this.printedWarnings.includes(t) || (console.warn(`DevTools: ${t}`, ...o), this.printedWarnings.push(t));
738
+ };
739
+ checkForWarnings = () => {
740
+ this.#t(), this.#e();
741
+ };
742
+ #t = () => {
743
+ const t = this.turboFrameIds;
744
+ t.filter((o, s) => t.indexOf(o) !== s).forEach((o) => {
745
+ 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.`);
746
+ });
747
+ };
748
+ #e = () => {
749
+ const t = document.querySelectorAll("[data-turbo-permanent]");
750
+ t.length !== 0 && t.forEach((e) => {
751
+ const o = e.id;
752
+ if (o === "" && this.printWarning("Turbo Permanent Element detected without an ID. Turbo Permanent Elements must have a unique ID to work correctly.", !0, e), o && document.querySelectorAll(`#${o}`).length > 1) {
753
+ const n = `Turbo Permanent Element with ID '${o}' doesn't have a unique ID. Turbo Permanent Elements must have a unique ID to work correctly.`;
754
+ this.printWarning(n, !0, e);
755
+ }
756
+ });
757
+ };
750
758
  get turboFrameIds() {
751
759
  return Array.from(document.querySelectorAll("turbo-frame")).map((t) => t.id);
752
760
  }
753
761
  }
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) => {
762
+ const a = (i) => JSON.parse(localStorage.getItem("hotwire-native-dev-tools") || "{}")[i], l = (i, t) => {
756
763
  let e = JSON.parse(localStorage.getItem("hotwire-native-dev-tools") || "{}");
757
764
  e[i] = t, localStorage.setItem("hotwire-native-dev-tools", JSON.stringify(e));
758
- }, z = () => {
765
+ }, B = () => {
759
766
  localStorage.removeItem("hotwire-native-dev-tools");
760
767
  }, u = () => a("consoleFilterLevels") || {
761
768
  warn: !0,
@@ -763,17 +770,24 @@ const a = (i) => JSON.parse(localStorage.getItem("hotwire-native-dev-tools") ||
763
770
  debug: !0,
764
771
  info: !0,
765
772
  log: !0
766
- }, N = (i, t) => {
773
+ }, $ = (i, t) => {
767
774
  const e = u();
768
- return e[i] = t, h("consoleFilterLevels", e), e;
769
- }, m = (i, t) => {
775
+ return e[i] = t, l("consoleFilterLevels", e), e;
776
+ }, m = () => a("consoleLogBlacklist") || [], I = (i) => {
777
+ i = i.trim();
778
+ const t = a("consoleLogBlacklist") || [];
779
+ return t.includes(i) || (t.push(i), l("consoleLogBlacklist", t)), t;
780
+ }, F = (i) => {
781
+ let t = a("consoleLogBlacklist") || [];
782
+ return t = t.filter((e) => e !== i), l("consoleLogBlacklist", t), t;
783
+ }, h = (i, t) => {
770
784
  let e = null;
771
785
  return (...o) => {
772
786
  const s = () => i.apply(void 0, o);
773
787
  clearTimeout(e), e = setTimeout(s, t);
774
788
  };
775
- }, { userAgent: E } = window.navigator, D = /iOS/.test(E), P = /Android/.test(E), L = () => D ? "ios" : P ? "android" : "unknown", O = () => {
776
- switch (L()) {
789
+ }, { userAgent: S } = window.navigator, k = /iOS/.test(S), q = /Android/.test(S), f = () => k ? "ios" : q ? "android" : "unknown", A = () => {
790
+ switch (f()) {
777
791
  case "android":
778
792
  return "Android";
779
793
  case "ios":
@@ -781,10 +795,10 @@ const a = (i) => JSON.parse(localStorage.getItem("hotwire-native-dev-tools") ||
781
795
  default:
782
796
  return "<unknown>";
783
797
  }
784
- }, R = (i) => document.querySelector(`meta[name="${i}"]`), y = (i) => {
785
- const t = R(i);
798
+ }, M = (i) => document.querySelector(`meta[name="${i}"]`), v = (i) => {
799
+ const t = M(i);
786
800
  return t && t.content;
787
- }, j = `
801
+ }, H = `
788
802
  <svg width="100%" height="100%" viewBox="0 0 294 320">
789
803
  <g transform="matrix(1,0,0,1,-28.38,-15.268)">
790
804
  <g transform="matrix(1,0,0,1,-462.157,-144.417)">
@@ -792,95 +806,76 @@ const a = (i) => JSON.parse(localStorage.getItem("hotwire-native-dev-tools") ||
792
806
  </g>
793
807
  </g>
794
808
  </svg>
795
- `, V = `
809
+ `, z = `
796
810
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
797
811
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
798
812
  <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"/>
799
813
  </svg>
800
- `, Y = `
814
+ `, N = `
801
815
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
802
816
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
803
817
  <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"/>
804
818
  </svg>
805
- `, S = `
819
+ `, b = `
806
820
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
807
821
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
808
822
  <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"/>
809
823
  </svg>
810
- `, k = `
824
+ `, p = `
811
825
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
812
826
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
813
827
  <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"/>
814
828
  </svg>
815
- `, W = `
829
+ `, P = `
816
830
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
817
831
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
818
832
  <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"/>
819
833
  </svg>
820
- `, U = `
834
+ `, D = `
821
835
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
822
836
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
823
837
  <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"/>
824
838
  </svg>
825
- `, X = `
839
+ `, O = `
826
840
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
827
841
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
828
842
  <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"/>
829
843
  </svg>
830
- `, J = `
844
+ `, j = `
831
845
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
832
846
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
833
847
  <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"/>
834
848
  </svg>
835
- `, G = `
849
+ `, y = `
836
850
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 512">
837
851
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
838
852
  <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"/>
839
853
  </svg>
854
+ `, R = `
855
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640">
856
+ <!--!Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
857
+ <path d="M431.2 476.5L163.5 208.8C141.1 240.2 128 278.6 128 320C128 426 214 512 320 512C361.5 512 399.9 498.9 431.2 476.5zM476.5 431.2C498.9 399.8 512 361.4 512 320C512 214 426 128 320 128C278.5 128 240.1 141.1 208.8 163.5L476.5 431.2zM64 320C64 178.6 178.6 64 320 64C461.4 64 576 178.6 576 320C576 461.4 461.4 576 320 576C178.6 576 64 461.4 64 320z"/>
858
+ </svg>
840
859
  `;
841
- class K {
860
+ class V {
842
861
  constructor(t) {
843
- d(this, "render", m(() => {
844
- this.setPosition(), this.createDragItem(), this.setTranslate(this.initialX, this.initialY, this.dragItem), this.addEventListeners();
845
- }, 50));
846
- d(this, "animateErrorBorder", m(() => {
847
- if (!this.dragItem || a("errorAnimationEnabled") === !1) return;
848
- let t = this.dragItem.querySelector(".error-border"), e = this.dragItem.querySelector(".error-border circle");
849
- t && t.remove();
850
- const o = document.createElement("div");
851
- o.className = "animation-container", o.innerHTML = `
852
- <svg viewBox="0 0 180 180" xmlns="http://www.w3.org/2000/svg" class="error-border">
853
- <defs>
854
- <linearGradient id="errorGradient" gradientTransform="rotate(45)">
855
- <stop offset="0%" stop-color="#e4241a" />
856
- <stop offset="50%" stop-color="#dd1f15" />
857
- <stop offset="100%" stop-color="#f6160a" />
858
- </linearGradient>
859
- </defs>
860
- <circle cx="90" cy="90" r="90" fill="none" stroke="url(#errorGradient)" stroke-width="21"
861
- stroke-dasharray="565" stroke-dashoffset="565" stroke-linecap="round" />
862
- </svg>
863
- `, this.dragItem.appendChild(o), e = this.dragItem.querySelector(".error-border circle"), e.classList.add("animate"), setTimeout(() => {
864
- o.classList.add("fade-out");
865
- }, 1300), setTimeout(() => {
866
- o && o.parentNode && o.remove();
867
- }, 1800);
868
- }, 100));
869
862
  this.devTools = t, this.bubbleSize = 4.75 * 16 + 0.3 * 16, this.minVisible = this.bubbleSize * 0.5, this.currentlyDragging = !1;
870
863
  }
864
+ render = h(() => {
865
+ this.setPosition(), this.createDragItem(), this.setTranslate(this.initialX, this.initialY, this.dragItem), this.addEventListeners();
866
+ }, 50);
871
867
  setPosition() {
872
868
  this.settingKey = window.innerWidth < window.innerHeight ? "bubblePosPortrait" : "bubblePosLandscape";
873
869
  const t = { x: window.innerWidth - 100, y: window.innerHeight - 100 }, { x: e, y: o } = a(this.settingKey) || t;
874
870
  this.currentX = this.initialX = this.xOffset = e, this.currentY = this.initialY = this.yOffset = o;
875
871
  }
876
872
  createDragItem() {
877
- var e;
878
- const t = (e = this.devTools.shadowRoot) == null ? void 0 : e.getElementById("floating-bubble");
873
+ const t = this.devTools.shadowRoot?.getElementById("floating-bubble");
879
874
  if (t) {
880
875
  this.dragItem = t;
881
876
  return;
882
877
  }
883
- this.dragItem = document.createElement("div"), this.dragItem.id = "floating-bubble", this.dragItem.innerHTML = j, this.devTools.shadowRoot.appendChild(this.dragItem);
878
+ this.dragItem = document.createElement("div"), this.dragItem.id = "floating-bubble", this.dragItem.innerHTML = H, this.devTools.shadowRoot.appendChild(this.dragItem);
884
879
  }
885
880
  addEventListeners() {
886
881
  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);
@@ -888,6 +883,29 @@ class K {
888
883
  click(t) {
889
884
  this.clickCallback && this.clickCallback(t);
890
885
  }
886
+ animateErrorBorder = h(() => {
887
+ if (!this.dragItem || a("errorAnimationEnabled") === !1) return;
888
+ let t = this.dragItem.querySelector(".error-border"), e = this.dragItem.querySelector(".error-border circle");
889
+ t && t.remove();
890
+ const o = document.createElement("div");
891
+ o.className = "animation-container", o.innerHTML = `
892
+ <svg viewBox="0 0 180 180" xmlns="http://www.w3.org/2000/svg" class="error-border">
893
+ <defs>
894
+ <linearGradient id="errorGradient" gradientTransform="rotate(45)">
895
+ <stop offset="0%" stop-color="#e4241a" />
896
+ <stop offset="50%" stop-color="#dd1f15" />
897
+ <stop offset="100%" stop-color="#f6160a" />
898
+ </linearGradient>
899
+ </defs>
900
+ <circle cx="90" cy="90" r="90" fill="none" stroke="url(#errorGradient)" stroke-width="21"
901
+ stroke-dasharray="565" stroke-dashoffset="565" stroke-linecap="round" />
902
+ </svg>
903
+ `, this.dragItem.appendChild(o), e = this.dragItem.querySelector(".error-border circle"), e.classList.add("animate"), setTimeout(() => {
904
+ o.classList.add("fade-out");
905
+ }, 1300), setTimeout(() => {
906
+ o && o.parentNode && o.remove();
907
+ }, 1800);
908
+ }, 100);
891
909
  onClick(t) {
892
910
  this.clickCallback = t;
893
911
  }
@@ -895,7 +913,7 @@ class K {
895
913
  t.target.closest("#floating-bubble") && (this.currentlyDragging = !0, this.initialX = t.touches[0].clientX - this.xOffset, this.initialY = t.touches[0].clientY - this.yOffset);
896
914
  }
897
915
  dragEnd() {
898
- this.initialX = this.currentX, this.initialY = this.currentY, this.currentlyDragging = !1, h(this.settingKey, { x: this.currentX, y: this.currentY });
916
+ this.initialX = this.currentX, this.initialY = this.currentY, this.currentlyDragging = !1, l(this.settingKey, { x: this.currentX, y: this.currentY });
899
917
  }
900
918
  drag(t) {
901
919
  if (!this.currentlyDragging) return;
@@ -908,14 +926,8 @@ class K {
908
926
  o.style.transform = `translate3d(${t}px, ${e}px, 0)`;
909
927
  }
910
928
  }
911
- class Z {
929
+ class Y {
912
930
  constructor(t) {
913
- d(this, "handleTabClick", (t) => {
914
- const e = t.target.closest(".tablink");
915
- if (!e) return;
916
- const o = e.dataset.tabId;
917
- this.devTools.state.setActiveTab(o), this.updateTabView(o);
918
- });
919
931
  this.devTools = t, this.state = t.state.state, this.sheetHeight = parseInt(a("bottomSheetHeight")) || 55;
920
932
  }
921
933
  render() {
@@ -943,8 +955,7 @@ class Z {
943
955
  e && this.updateConsoleFilter(e);
944
956
  }
945
957
  createBottomSheet() {
946
- var n;
947
- const t = (n = this.devTools.shadowRoot) == null ? void 0 : n.querySelector(".bottom-sheet");
958
+ const t = this.devTools.shadowRoot?.querySelector(".bottom-sheet");
948
959
  if (t) {
949
960
  this.bottomSheet = t;
950
961
  return;
@@ -960,24 +971,25 @@ class Z {
960
971
  <button class="tablink ${e === "tab-event-logs" ? "active" : ""}" data-tab-id="tab-event-logs">Events</button>
961
972
  <button class="tablink ${e === "tab-native-stack" ? "active" : ""} d-none" data-tab-id="tab-native-stack">Stack</button>
962
973
  <div class="tablink-settings dropdown d-flex">
963
- <button class="dropdown-trigger tablink-dropdown">${G}</button>
974
+ <button class="dropdown-trigger tablink-dropdown">${y}</button>
964
975
  <div class="dropdown-content settings-dropdown">
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>
967
- <button class="pin-bottom-sheet">Pin Bottom Sheet</button>
976
+ <button class="dropdown-btn-full-width btn-switch-to-single-tab-sheet" data-tab-id="single-tab-settings">Settings</button>
977
+ <button class="dropdown-btn-full-width btn-switch-to-single-tab-sheet" data-tab-id="single-tab-info">Info</button>
978
+ <button class="dropdown-btn-full-width btn-switch-to-single-tab-sheet d-none" data-tab-id="single-tab-path-configuration-check">PathConfiguration Check</button>
979
+ <button class="dropdown-btn-full-width pin-bottom-sheet">Pin Bottom Sheet</button>
968
980
  </div>
969
981
  </div>
970
982
  </div>
971
983
 
972
984
  <div class="tab-action-bars">
973
985
  <div class="tab-action-bar tab-bridge-components ${e === "tab-bridge-components" ? "active" : ""}">
974
- <button class="btn-icon btn-clear-tab btn-clear-bridge-logs">${k}</button>
986
+ <button class="btn-icon btn-clear-tab btn-clear-bridge-logs">${p}</button>
975
987
  </div>
976
988
  <div class="tab-action-bar d-flex flex-column tab-console-logs ${e === "tab-console-logs" ? "active" : ""}">
977
989
  <div class="d-flex">
978
- <button class="btn-icon btn-search-console">${X}</button>
990
+ <button class="btn-icon btn-search-console">${O}</button>
979
991
  <div class="dropdown">
980
- <button class="dropdown-trigger btn-icon">${J}</button>
992
+ <button class="dropdown-trigger btn-icon">${j}</button>
981
993
  <div class="dropdown-content console-filter-levels">
982
994
  <label><input type="checkbox" ${o.warn ? "checked" : ""} data-console-filter="warn" /> Warnings</label>
983
995
  <label><input type="checkbox" ${o.error ? "checked" : ""} data-console-filter="error" /> Errors</label>
@@ -986,7 +998,12 @@ class Z {
986
998
  <label><input type="checkbox" ${o.log ? "checked" : ""} data-console-filter="log" /> Logs</label>
987
999
  </div>
988
1000
  </div>
989
- <button class="btn-icon btn-clear-tab btn-clear-console-logs">${k}</button>
1001
+ <div class="dropdown dropdown--scrollable">
1002
+ <button class="dropdown-trigger btn-icon">${R}</button>
1003
+ <div class="dropdown-content console-log-blacklist">
1004
+ </div>
1005
+ </div>
1006
+ <button class="btn-icon btn-clear-tab btn-clear-console-logs">${p}</button>
990
1007
  </div>
991
1008
 
992
1009
  <div class="console-search mt-2 ${s ? "" : "d-none"}">
@@ -994,10 +1011,10 @@ class Z {
994
1011
  </div>
995
1012
  </div>
996
1013
  <div class="tab-action-bar tab-event-logs ${e === "tab-event-logs" ? "active" : ""}">
997
- <button class="btn-icon btn-clear-tab btn-clear-events">${k}</button>
1014
+ <button class="btn-icon btn-clear-tab btn-clear-events">${p}</button>
998
1015
  </div>
999
1016
  <div class="tab-action-bar tab-native-stack ${e === "tab-native-stack" ? "active" : ""}">
1000
- <button class="btn-icon btn-reload-tab btn-reload-stack">${W}</button>
1017
+ <button class="btn-icon btn-reload-tab btn-reload-stack">${P}</button>
1001
1018
  </div>
1002
1019
  </div>
1003
1020
  </div>
@@ -1011,7 +1028,7 @@ class Z {
1011
1028
  <div id="bridge-components-collapse" class="collapse-target">
1012
1029
  <div class="d-flex justify-content-between border-bottom">
1013
1030
  <div class="tab-content-bridge-components flex-grow-1"></div>
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>
1031
+ <button class="btn-icon btn-help btn-switch-to-single-tab-sheet mt-1" data-tab-id="single-tab-bridge-component-help">${D}</button>
1015
1032
  </div>
1016
1033
  </div>
1017
1034
 
@@ -1038,10 +1055,10 @@ class Z {
1038
1055
  <div id="single-tab-bridge-component-help" class="single-tab-content outer-tab-content">
1039
1056
  <div class="inner-tab-content">
1040
1057
  <div class="d-flex align-items-center mb-3">
1041
- <button class="btn-icon btn-close-single-mode">${S}</button>
1058
+ <button class="btn-icon btn-close-single-mode">${b}</button>
1042
1059
  <h3 class="ms-1">Bridge Components</h3>
1043
1060
  </div>
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>
1061
+ <p>This list shows all the bridge components that the ${A()} app supports. Components that are active on this page are marked with a green dot.</p>
1045
1062
  <h3 class="mt-4">Why is my bridge component not on the list?</h3>
1046
1063
  <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>
1047
1064
  ${this.registerBridgeComponentExample()}
@@ -1053,7 +1070,7 @@ class Z {
1053
1070
  <div id="single-tab-settings" class="single-tab-content outer-tab-content">
1054
1071
  <div class="inner-tab-content">
1055
1072
  <div class="d-flex align-items-center mb-3">
1056
- <button class="btn-icon btn-close-single-mode">${S}</button>
1073
+ <button class="btn-icon btn-close-single-mode">${b}</button>
1057
1074
  <h3 class="ms-1">Settings</h3>
1058
1075
  </div>
1059
1076
  <div class="mb-3">
@@ -1094,10 +1111,25 @@ class Z {
1094
1111
  </div>
1095
1112
  </div>
1096
1113
 
1114
+ <div id="single-tab-path-configuration-check" class="single-tab-content outer-tab-content">
1115
+ <div class="inner-tab-content">
1116
+ <div class="d-flex align-items-center mb-3">
1117
+ <button class="btn-icon btn-close-single-mode">${b}</button>
1118
+ <h3 class="ms-1">PathConfiguration Check</h3>
1119
+ </div>
1120
+ <div class="mb-3">
1121
+ <label for="path-configuration-check-url">URL</label>
1122
+ <input id="path-configuration-check-url" class="w-100" value="/" />
1123
+ </div>
1124
+ <div id="path-configuration-check-properties-output" class="overflow-auto">
1125
+ </div>
1126
+ </div>
1127
+ </div>
1128
+
1097
1129
  <div id="single-tab-info" class="single-tab-content outer-tab-content">
1098
1130
  <div class="inner-tab-content">
1099
1131
  <div class="d-flex align-items-center mb-3">
1100
- <button class="btn-icon btn-close-single-mode">${S}</button>
1132
+ <button class="btn-icon btn-close-single-mode">${b}</button>
1101
1133
  <h3 class="ms-1">Info</h3>
1102
1134
  </div>
1103
1135
  <div class="info-card">
@@ -1109,18 +1141,18 @@ class Z {
1109
1141
  <div class="user-agent">${navigator.userAgent}</div>
1110
1142
  </div>
1111
1143
  <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>
1144
+ <div class="info-card-title"><pre class="m-0">turbo-cache-control:</pre> <span>${v("turbo-cache-control") || "-"}</span></div>
1113
1145
  <div class="info-card-hint"><strong>no-cache:</strong> always fetched from the network, even on restore</div>
1114
1146
  <div class="info-card-hint"><strong>no-preview:</strong> skipped in preview, used only on restore</div>
1115
1147
  <div class="info-card-hint"><strong>unset:</strong> shows cached preview if the cache is valid</div>
1116
1148
  </div>
1117
1149
  <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>
1150
+ <div class="info-card-title"><pre class="m-0">turbo-refresh-method:</pre> <span>${v("turbo-refresh-method") || "-"}</span></div>
1119
1151
  <div class="info-card-hint"><strong>replace (default):</strong> replaces the entire &lt;body&gt; on revisit</div>
1120
1152
  <div class="info-card-hint"><strong>morph:</strong> updates only changed DOM elements, preserving state</div>
1121
1153
  </div>
1122
1154
  <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>
1155
+ <div class="info-card-title"><pre class="m-0">turbo-visit-control:</pre> <span>${v("turbo-visit-control") || "-"}</span></div>
1124
1156
  <div class="info-card-hint"><strong>reload:</strong> forces a full page reload</div>
1125
1157
  <div class="info-card-hint"><strong>unset:</strong> allows Turbo to handle the visit normally</div>
1126
1158
  </div>
@@ -1131,8 +1163,19 @@ class Z {
1131
1163
  `, this.devTools.shadowRoot.appendChild(this.bottomSheet);
1132
1164
  }
1133
1165
  renderConsoleLogs() {
1134
- const t = this.bottomSheet.querySelector(".tab-content-console-logs"), e = u(), o = this.state.consoleSearch;
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>';
1166
+ const t = this.bottomSheet.querySelector(".tab-content-console-logs"), e = u(), o = m(), s = this.state.consoleSearch;
1167
+ t.innerHTML = this.state.consoleLogs.length ? this.state.consoleLogs.filter((n) => e[n.type]).filter((n) => s ? n.message.toLowerCase().includes(s.toLowerCase()) : !0).filter((n) => !o.includes(n.message.trim())).map((n) => this.consoleLogHTML(n.type, n.message, n.time)).join("") : '<div class="tab-empty-content"><span>No console logs yet</span></div>', this.renderConsoleBlacklist();
1168
+ }
1169
+ renderConsoleBlacklist() {
1170
+ this.bottomSheet.querySelector(".console-log-blacklist").innerHTML = m().length ? `
1171
+ ${m().map(
1172
+ (t) => `
1173
+ <div class="d-flex justify-content-between align-items-center dropdown-entry">
1174
+ <label class="console-log-blacklist-entry-text">${t}</label>
1175
+ <button class="btn-icon btn-remove-console-log-blacklist-entry icon--muted dropdown-content-action w-auto" data-entry="${t}">${p}</button>
1176
+ </div>
1177
+ `
1178
+ ).join("")}` : '<div class="text-center text-muted">No blacklisted logs</div>';
1136
1179
  }
1137
1180
  renderBridgeComponents() {
1138
1181
  const t = this.state.supportedBridgeComponents.length;
@@ -1152,11 +1195,26 @@ class Z {
1152
1195
  const t = this.bottomSheet.querySelector(".tab-content-native-stack");
1153
1196
  t.innerHTML = '<div class="native-stack-wrapper">' + (this.state.nativeStack.length ? this.state.nativeStack.map((e) => this.nativeViewStackHTML(e)).join("") : '<div class="tab-empty-content"><span>No native stack captured yet</span></div>') + "</div>";
1154
1197
  }
1198
+ renderPathConfigurationCheck = h((t) => {
1199
+ const e = k ? t : `${window.location.origin}${t}`;
1200
+ this.devTools.nativeBridge.send("propertiesForUrl", { url: e }, (o) => {
1201
+ this.bottomSheet.querySelector("#path-configuration-check-properties-output").style.opacity = 1;
1202
+ const s = (() => {
1203
+ try {
1204
+ const c = o.data.properties;
1205
+ return JSON.stringify(typeof c == "string" ? JSON.parse(c) : c, null, 2);
1206
+ } catch {
1207
+ return o.data.properties;
1208
+ }
1209
+ })(), n = s ? `<pre class="view-path-configuration">${s}</pre>` : "", r = this.bottomSheet.querySelector("#path-configuration-check-properties-output");
1210
+ r.innerHTML = n;
1211
+ });
1212
+ }, 500);
1155
1213
  bridgeLogHTML(t, e, o, s, n) {
1156
1214
  return `
1157
1215
  <div class="log-entry d-flex gap-3 pt-2 pb-2">
1158
1216
  <div class="log-entry-icon d-flex justify-content-center align-items-center">
1159
- ${t === "send" ? Y : V}
1217
+ ${t === "send" ? N : z}
1160
1218
  </div>
1161
1219
  <div class="w-100 overflow-auto">
1162
1220
  <div class="d-flex justify-content-between">
@@ -1165,8 +1223,8 @@ class Z {
1165
1223
  </div>
1166
1224
  <div class="overflow-auto">
1167
1225
  ${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>`;
1226
+ const g = typeof c == "object" && c !== null ? JSON.stringify(c) : c;
1227
+ return `<div class="white-space-collapse">${r}: ${g}</div>`;
1170
1228
  }).join("")}
1171
1229
  </div>
1172
1230
  </div>
@@ -1180,8 +1238,17 @@ class Z {
1180
1238
  <div class="d-flex justify-content-end">
1181
1239
  <small>${o}</small>
1182
1240
  </div>
1183
- <div class="log-entry-message ${t}">
1184
- ${e}
1241
+ <div class="d-flex justify-content-between">
1242
+ <div class="log-entry-message ${t}">
1243
+ ${e}
1244
+ </div>
1245
+ <div class="dropdown dropdown--right">
1246
+ <button class="dropdown-trigger btn-icon">${y}</button>
1247
+ <div class="dropdown-content">
1248
+ <button class="dropdown-btn-full-width dropdown-content-action console-log-action-hide-console-log">Ignore this log</button>
1249
+ <button class="dropdown-btn-full-width dropdown-content-action console-log-action-copy-console-log">Copy log message</button>
1250
+ </div>
1251
+ </div>
1185
1252
  </div>
1186
1253
  </div>
1187
1254
  </div>
@@ -1202,8 +1269,7 @@ class Z {
1202
1269
  `;
1203
1270
  }
1204
1271
  nativeViewStackHTML(t) {
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">
1272
+ const e = (d) => d?.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"}`, g = "viewstack-" + Math.random().toString(16).slice(2), L = t.url ? `<div class="view-url">
1207
1273
  ${(() => {
1208
1274
  try {
1209
1275
  return new URL(t.url).pathname;
@@ -1211,31 +1277,31 @@ class Z {
1211
1277
  return t.url;
1212
1278
  }
1213
1279
  })()}
1214
- </div>` : "", x = (() => {
1280
+ </div>` : "", w = (() => {
1215
1281
  try {
1216
- const l = t.pathConfigurationProperties;
1217
- return JSON.stringify(typeof l == "string" ? JSON.parse(l) : l, null, 2);
1282
+ const d = t.pathConfigurationProperties;
1283
+ return JSON.stringify(typeof d == "string" ? JSON.parse(d) : d, null, 2);
1218
1284
  } catch {
1219
1285
  return t.pathConfigurationProperties;
1220
1286
  }
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("")}
1287
+ })(), x = w ? `<pre class="view-path-configuration">${w}</pre>` : "", C = t.children?.length ? `<div class="child-container">
1288
+ ${t.children.map((d) => this.nativeViewStackHTML(d)).join("")}
1223
1289
  </div>` : "";
1224
1290
  return `
1225
1291
  <div>
1226
- <div class="${c} collapse no-chevron" data-collapse-target="path-configuration-properties-${b}">
1292
+ <div class="${c} collapse no-chevron" data-collapse-target="path-configuration-properties-${g}">
1227
1293
  <div>
1228
1294
  <div class="view-title">
1229
1295
  ${t.title == "null" ? "" : t.title}
1230
1296
  <div class="view-title-details">${t.type}</div>
1231
1297
  </div>
1232
- ${B}
1298
+ ${L}
1233
1299
  </div>
1234
- <div id="path-configuration-properties-${b}" class="collapse-target">
1235
- ${$}
1300
+ <div id="path-configuration-properties-${g}" class="collapse-target">
1301
+ ${x}
1236
1302
  </div>
1237
1303
  </div>
1238
- ${I}
1304
+ ${C}
1239
1305
  </div>
1240
1306
  `;
1241
1307
  }
@@ -1248,7 +1314,7 @@ class Z {
1248
1314
  });
1249
1315
  }
1250
1316
  registerBridgeComponentExample() {
1251
- switch (L()) {
1317
+ switch (f()) {
1252
1318
  case "android":
1253
1319
  return `
1254
1320
  <pre class="overflow-auto">
@@ -1269,7 +1335,7 @@ class Z {
1269
1335
  }
1270
1336
  }
1271
1337
  registerBridgeComponentHelpURL() {
1272
- switch (L()) {
1338
+ switch (f()) {
1273
1339
  case "android":
1274
1340
  return "https://native.hotwired.dev/android/bridge-components";
1275
1341
  case "ios":
@@ -1279,7 +1345,7 @@ class Z {
1279
1345
  }
1280
1346
  }
1281
1347
  checkNativeFeatures() {
1282
- this.state.supportsNativeStackView && this.bottomSheet.querySelector(".tablink[data-tab-id='tab-native-stack']").classList.remove("d-none");
1348
+ this.state.supportsNativeStackView && (this.bottomSheet.querySelector(".tablink[data-tab-id='tab-native-stack']").classList.remove("d-none"), this.bottomSheet.querySelector(".btn-switch-to-single-tab-sheet[data-tab-id='single-tab-path-configuration-check']").classList.remove("d-none"));
1283
1349
  }
1284
1350
  addEventListeners() {
1285
1351
  this.bottomSheet.hasEventListeners || (this.sheetOverlay.addEventListener("click", () => {
@@ -1295,7 +1361,7 @@ class Z {
1295
1361
  }), this.bottomSheet.querySelectorAll(".btn-switch-to-single-tab-sheet").forEach((t) => {
1296
1362
  t.addEventListener("click", (e) => {
1297
1363
  const o = e.target.closest("[data-tab-id]").dataset.tabId;
1298
- o && this.switchToSingleTabSheet(o);
1364
+ o && (o === "single-tab-path-configuration-check" && this.bottomSheet.querySelector("#path-configuration-check-url").value === "/" && this.renderPathConfigurationCheck("/"), this.switchToSingleTabSheet(o));
1299
1365
  });
1300
1366
  }), this.bottomSheet.querySelectorAll(".btn-close-single-mode").forEach((t) => {
1301
1367
  t.addEventListener("click", () => {
@@ -1305,7 +1371,7 @@ class Z {
1305
1371
  const e = t.closest("input[type='checkbox']");
1306
1372
  if (!e) return;
1307
1373
  const o = e.dataset.consoleFilter, s = e.checked;
1308
- N(o, s), this.renderConsoleLogs();
1374
+ $(o, s), this.renderConsoleLogs();
1309
1375
  }), this.bottomSheet.querySelector(".btn-search-console").addEventListener("click", () => {
1310
1376
  const t = this.bottomSheet.querySelector(".console-search");
1311
1377
  t.classList.toggle("d-none"), t.querySelector("input").focus();
@@ -1313,19 +1379,21 @@ class Z {
1313
1379
  this.devTools.state.setConsoleSearchValue(t.target.value.toLowerCase()), this.renderConsoleLogs();
1314
1380
  }), this.bottomSheet.querySelector("#bottom-sheet-height-setting").addEventListener("change", (t) => {
1315
1381
  const e = t.target.value;
1316
- this.sheetHeight = parseInt(e), h("bottomSheetHeight", e), this.updateSheetHeight(e);
1382
+ this.sheetHeight = parseInt(e), l("bottomSheetHeight", e), this.updateSheetHeight(e);
1317
1383
  }), this.bottomSheet.querySelector("#console-error-animation-setting").addEventListener("change", (t) => {
1318
- h("errorAnimationEnabled", t.target.checked);
1384
+ l("errorAnimationEnabled", t.target.checked);
1319
1385
  }), this.bottomSheet.querySelector("#font-size-setting").addEventListener("change", (t) => {
1320
1386
  let e = t.target.value;
1321
- e = Math.max(8, Math.min(24, e)), h("fontSize", e), this.devTools.setCSSProperty("--font-size", `${e}px`);
1387
+ e = Math.max(8, Math.min(24, e)), l("fontSize", e), this.devTools.setCSSProperty("--font-size", `${e}px`);
1322
1388
  }), this.bottomSheet.querySelector("#auto-open-setting").addEventListener("change", (t) => {
1323
- h("autoOpen", t.target.checked);
1389
+ l("autoOpen", t.target.checked);
1324
1390
  }), this.bottomSheet.querySelector("#scroll-to-latest-log-setting").addEventListener("change", (t) => {
1325
- h("scrollToLatestLog", t.target.checked);
1391
+ l("scrollToLatestLog", t.target.checked);
1326
1392
  }), this.bottomSheet.querySelector(".pin-bottom-sheet").addEventListener("click", () => {
1327
1393
  const t = a("bottomSheetPinned") === !0;
1328
- h("bottomSheetPinned", !t), this.sheetOverlay.classList.toggle("active"), this.bottomSheet.querySelector(".settings-dropdown").classList.remove("dropdown-open");
1394
+ l("bottomSheetPinned", !t), this.sheetOverlay.classList.toggle("active"), this.bottomSheet.querySelector(".settings-dropdown").classList.remove("dropdown-open");
1395
+ }), this.bottomSheet.querySelector("#path-configuration-check-url").addEventListener("input", (t) => {
1396
+ this.bottomSheet.querySelector("#path-configuration-check-properties-output").style.opacity = 0.5, this.renderPathConfigurationCheck(t.target.value);
1329
1397
  }), this.bottomSheet.addEventListener("click", (t) => {
1330
1398
  const e = t.target.closest(".collapse");
1331
1399
  if (e && this.bottomSheet.contains(e)) {
@@ -1341,11 +1409,18 @@ class Z {
1341
1409
  t.preventDefault(), this.toggleDropdown(o);
1342
1410
  return;
1343
1411
  }
1344
- this.bottomSheet.querySelectorAll(".dropdown-content.dropdown-open").forEach((n) => {
1345
- n.closest(".dropdown").contains(t.target) || n.classList.remove("dropdown-open");
1346
- });
1412
+ if (t.target.closest(".dropdown-content-action")) {
1413
+ this.handleDropdownActionClick(t);
1414
+ return;
1415
+ }
1416
+ this.closeAllDropdowns(t);
1347
1417
  }), this.bottomSheet.hasEventListeners = !0);
1348
1418
  }
1419
+ closeAllDropdowns(t) {
1420
+ this.bottomSheet.querySelectorAll(".dropdown-content.dropdown-open").forEach((o) => {
1421
+ o.closest(".dropdown").contains(t.target) || o.classList.remove("dropdown-open");
1422
+ });
1423
+ }
1349
1424
  updateConsoleFilter(t) {
1350
1425
  this.bottomSheet.querySelectorAll(".console-filter-levels input[type='checkbox']").forEach((e) => {
1351
1426
  const o = e.dataset.consoleFilter, s = t[o];
@@ -1358,13 +1433,30 @@ class Z {
1358
1433
  o !== e && o.classList.remove("dropdown-open");
1359
1434
  }), e.classList.toggle("dropdown-open");
1360
1435
  }
1436
+ handleTabClick = (t) => {
1437
+ const e = t.target.closest(".tablink");
1438
+ if (!e) return;
1439
+ const o = e.dataset.tabId;
1440
+ this.devTools.state.setActiveTab(o), this.updateTabView(o);
1441
+ };
1442
+ handleDropdownActionClick = (t) => {
1443
+ const e = t.target.closest(".dropdown-content-action");
1444
+ if (e)
1445
+ if (e.classList.contains("console-log-action-hide-console-log"))
1446
+ I(e.closest(".log-entry").querySelector(".log-entry-message").textContent), this.renderConsoleLogs();
1447
+ else if (e.classList.contains("console-log-action-copy-console-log")) {
1448
+ const s = e.closest(".log-entry").querySelector(".log-entry-message").textContent;
1449
+ navigator.clipboard.writeText(s).then(() => {
1450
+ this.closeAllDropdowns(t);
1451
+ });
1452
+ } else e.classList.contains("btn-remove-console-log-blacklist-entry") && (F(e.dataset.entry.trim()), this.renderConsoleLogs());
1453
+ };
1361
1454
  updateTabView(t) {
1362
1455
  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
1456
  }
1364
1457
  scrollToLatestLog(t) {
1365
1458
  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" });
1459
+ this.devTools.shadowRoot.getElementById(t)?.querySelector(".log-entry:last-child")?.scrollIntoView({ behavior: "instant", block: "center" });
1368
1460
  });
1369
1461
  }
1370
1462
  showBottomSheet() {
@@ -1377,13 +1469,11 @@ class Z {
1377
1469
  this.sheetContent.style.height = `${t}vh`, this.bottomSheet.classList.toggle("fullscreen", t === 100);
1378
1470
  }
1379
1471
  dragStart(t) {
1380
- var e;
1381
- this.isDragging = !0, this.startY = t.pageY || ((e = t.touches) == null ? void 0 : e[0].pageY), this.startHeight = parseInt(this.sheetContent.style.height), this.bottomSheet.classList.add("dragging");
1472
+ this.isDragging = !0, this.startY = t.pageY || t.touches?.[0].pageY, this.startHeight = parseInt(this.sheetContent.style.height), this.bottomSheet.classList.add("dragging");
1382
1473
  }
1383
1474
  dragging(t) {
1384
- var s;
1385
1475
  if (!this.isDragging) return;
1386
- const e = this.startY - (t.pageY || ((s = t.touches) == null ? void 0 : s[0].pageY)), o = this.startHeight + e / window.innerHeight * 100;
1476
+ const e = this.startY - (t.pageY || t.touches?.[0].pageY), o = this.startHeight + e / window.innerHeight * 100;
1387
1477
  this.updateSheetHeight(o);
1388
1478
  }
1389
1479
  dragStop() {
@@ -1407,14 +1497,13 @@ class Z {
1407
1497
  }
1408
1498
  // Get all the `static component = "..."` from the bridge components
1409
1499
  get bridgeComponentIdentifiers() {
1410
- var t;
1411
- return ((t = window.Stimulus) == null ? void 0 : t.controllers.map((e) => e.component).filter((e) => e !== void 0)) || [];
1500
+ return window.Stimulus?.controllers.map((t) => t.component).filter((t) => t !== void 0) || [];
1412
1501
  }
1413
1502
  get currentUrl() {
1414
1503
  return window.location.href;
1415
1504
  }
1416
1505
  }
1417
- class Q {
1506
+ class U {
1418
1507
  constructor() {
1419
1508
  this.state = {
1420
1509
  consoleLogs: [],
@@ -1468,7 +1557,7 @@ class Q {
1468
1557
  this.state.eventLogs = [], this.notify();
1469
1558
  }
1470
1559
  setActiveTab(t) {
1471
- this.state.activeTab = t, h("activeTab", t);
1560
+ this.state.activeTab = t, l("activeTab", t);
1472
1561
  }
1473
1562
  setConsoleSearchValue(t) {
1474
1563
  this.state.consoleSearch = t;
@@ -1483,10 +1572,9 @@ class Q {
1483
1572
  return a("activeTab") || "tab-bridge-components";
1484
1573
  }
1485
1574
  }
1486
- class _ {
1575
+ class W {
1487
1576
  bridgeIsConnected() {
1488
- var t, e;
1489
- return !!((t = window.HotwireNative) != null && t.web || (e = window.Strada) != null && e.web);
1577
+ return !!(window.HotwireNative?.web || window.Strada?.web);
1490
1578
  }
1491
1579
  // Send a message to the native side
1492
1580
  send(t, e = {}, o = null) {
@@ -1509,38 +1597,19 @@ class _ {
1509
1597
  return this.bridgeIsConnected() ? this.bridge.supportsComponent(t) : !1;
1510
1598
  }
1511
1599
  getSupportedComponents() {
1512
- var t;
1513
- return ((t = document.documentElement.dataset.bridgeComponents) == null ? void 0 : t.split(" ")) || [];
1600
+ return document.documentElement.dataset.bridgeComponents?.split(" ") || [];
1514
1601
  }
1515
1602
  get bridge() {
1516
- var t, e;
1517
- return ((t = window.HotwireNative) == null ? void 0 : t.web) || ((e = window.Strada) == null ? void 0 : e.web);
1603
+ return window.HotwireNative?.web || window.Strada?.web;
1518
1604
  }
1519
1605
  }
1520
- class tt {
1606
+ class X {
1521
1607
  constructor(t = {}) {
1522
- d(this, "update", m((t) => {
1523
- this.bottomSheet.update(t);
1524
- }, 200));
1525
- // Fetch the current stack from the native side
1526
- // The debounce on this function is intentionally high,
1527
- // to ensure the native side has enough time to set the ViewController / Fragment titles.
1528
- // With a lower debounce, the view controller / fragment title would often be empty.
1529
- d(this, "fetchNativeStack", m(() => {
1530
- this.nativeBridge.send("currentStackInfo", {}, (t) => {
1531
- this.state.setSupportsNativeStack(!0), this.state.setNativeStack(t.data.stack);
1532
- });
1533
- }, 1e3));
1534
- d(this, "injectCSSToShadowRoot", async () => {
1535
- if (this.shadowRoot.querySelector("style")) return;
1536
- const t = document.createElement("style");
1537
- t.textContent = M(), this.shadowRoot.appendChild(t);
1538
- });
1539
1608
  this.options = {
1540
1609
  enabled: !0,
1541
1610
  reset: !1,
1542
1611
  ...t
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());
1612
+ }, this.options.enabled && (this.options.reset && B(), this.state = new U(), this.bubble = new V(this), this.bottomSheet = new Y(this), this.nativeBridge = new W(this), this.diagnosticsChecker = new T(), this.state.subscribe(this.update.bind(this)), this.listenForTurboEvents());
1544
1613
  }
1545
1614
  // Setup gets called initially and on every turbo:load event, eg. when navigating to a new page
1546
1615
  setup() {
@@ -1551,14 +1620,16 @@ class tt {
1551
1620
  }), a("autoOpen") === !0 && this.bottomSheet.showBottomSheet());
1552
1621
  }
1553
1622
  nativeBridgeGotConnected() {
1554
- var t, e;
1555
- this.originalBridge || (this.originalBridge = ((t = window.HotwireNative) == null ? void 0 : t.web) || ((e = window.Strada) == null ? void 0 : e.web), this.addBridgeProxy(), this.state.setBridgeIsConnected(!0), this.callNativeBridgeComponent(), this.updateSupportedBridgeComponents(), this.startBridgeComponentObserver());
1623
+ this.originalBridge || (this.originalBridge = window.HotwireNative?.web || window.Strada?.web, this.addBridgeProxy(), this.state.setBridgeIsConnected(!0), this.callNativeBridgeComponent(), this.updateSupportedBridgeComponents(), this.startBridgeComponentObserver());
1556
1624
  }
1557
1625
  callNativeBridgeComponent() {
1558
1626
  this.nativeBridge.bridgeIsConnected() && this.nativeBridge.send("connect", {}, (t) => {
1559
1627
  this.fetchNativeStack();
1560
1628
  });
1561
1629
  }
1630
+ update = h((t) => {
1631
+ this.bottomSheet.update(t);
1632
+ }, 200);
1562
1633
  setupShadowRoot() {
1563
1634
  if (this.shadowContainer.shadowRoot) {
1564
1635
  this.shadowRoot = this.shadowContainer.shadowRoot, this.injectCSSToShadowRoot();
@@ -1579,7 +1650,7 @@ class tt {
1579
1650
  window.console = new Proxy(this.originalConsole, {
1580
1651
  get: (t, e, o) => {
1581
1652
  const s = Reflect.get(t, e, o);
1582
- return (...n) => (this.interceptedConsoleMessage(e, n), s == null ? void 0 : s.apply(t, n));
1653
+ return (...n) => (this.interceptedConsoleMessage(e, n), s?.apply(t, n));
1583
1654
  }
1584
1655
  });
1585
1656
  }
@@ -1603,20 +1674,33 @@ class tt {
1603
1674
  }
1604
1675
  return s.toString().replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
1605
1676
  }).join(" ");
1606
- o.includes("hotwire-native-dev-tools") || o.includes("HotwireDevTools") || (this.state.addConsoleLog(t, o), t === "error" && this.bubble.animateErrorBorder());
1677
+ o.includes("hotwire-native-dev-tools") || o.includes("HotwireDevTools") || (this.state.addConsoleLog(t, o), t === "error" && (m().includes(o) || this.bubble.animateErrorBorder()));
1607
1678
  }
1679
+ // Fetch the current stack from the native side
1680
+ // The debounce on this function is intentionally high,
1681
+ // to ensure the native side has enough time to set the ViewController / Fragment titles.
1682
+ // With a lower debounce, the view controller / fragment title would often be empty.
1683
+ fetchNativeStack = h(() => {
1684
+ this.nativeBridge.send("currentStackInfo", {}, (t) => {
1685
+ this.state.setSupportsNativeStack(!0), this.state.setNativeStack(t.data.stack);
1686
+ });
1687
+ }, 1e3);
1608
1688
  refetchNativeStack() {
1609
1689
  this.nativeBridge.send("currentStackInfo", {}, (t) => {
1610
1690
  this.state.setNativeStack(t.data.stack);
1611
1691
  });
1612
1692
  }
1693
+ injectCSSToShadowRoot = async () => {
1694
+ if (this.shadowRoot.querySelector("style")) return;
1695
+ const t = document.createElement("style");
1696
+ t.textContent = E(), this.shadowRoot.appendChild(t);
1697
+ };
1613
1698
  addEventListeners() {
1614
1699
  this.hasEventListeners || (window.addEventListener("error", (t) => {
1615
1700
  const { message: e, filename: o, lineno: s, colno: n } = t, r = `${e} at ${o}:${s}:${n}`;
1616
1701
  this.interceptedConsoleMessage("error", [r]);
1617
1702
  }), window.addEventListener("unhandledrejection", (t) => {
1618
- var e;
1619
- this.interceptedConsoleMessage("error", [(e = t.reason) == null ? void 0 : e.message]);
1703
+ this.interceptedConsoleMessage("error", [t.reason?.message]);
1620
1704
  }), window.addEventListener(
1621
1705
  "resize",
1622
1706
  () => {
@@ -1691,8 +1775,8 @@ class tt {
1691
1775
  return (/* @__PURE__ */ new Date()).toLocaleTimeString();
1692
1776
  }
1693
1777
  }
1694
- const ot = (i = {}) => {
1695
- const t = new tt(i);
1778
+ const J = (i = {}) => {
1779
+ const t = new X(i);
1696
1780
  t.options.enabled && (t.setup(), document.addEventListener(
1697
1781
  "turbo:load",
1698
1782
  () => {
@@ -1702,6 +1786,6 @@ const ot = (i = {}) => {
1702
1786
  ));
1703
1787
  };
1704
1788
  export {
1705
- ot as setupDevTools
1789
+ J as setupDevTools
1706
1790
  };
1707
1791
  //# sourceMappingURL=hotwire-native-dev-tools.es.js.map