@capgo/capacitor-inappbrowser 8.12.2-beta.pr634.545.1 → 8.12.2-beta.pr634.551.1

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.
@@ -278,18 +278,18 @@ enum ReloadGestureSupport {
278
278
  return currentPullDistance >= armedPullDistance * 0.9
279
279
  }
280
280
 
281
- /// Resting offset for the current adjusted top inset (safe-area aware).
282
- /// - Parameter forceToRestingTop: After gesture reload, always snap to resting top (fixes clipped header).
283
- /// Otherwise only un-overscroll after a cancelled pull.
281
+ /// Resting offset after gesture reload.
282
+ /// Plugin safe-area uses CSS variables with `contentInset = .zero`, so forced reset is always `0`.
283
+ /// - Parameter forceToRestingTop: After gesture reload, snap to top. Otherwise only un-overscroll.
284
284
  static func contentOffsetYAfterReloadReset(
285
285
  currentY: CGFloat,
286
286
  adjustedContentInsetTop: CGFloat,
287
287
  forceToRestingTop: Bool = false
288
288
  ) -> CGFloat {
289
- let restingY = -adjustedContentInsetTop
290
289
  if forceToRestingTop {
291
- return restingY
290
+ return 0
292
291
  }
292
+ let restingY = -adjustedContentInsetTop
293
293
  return currentY < restingY ? restingY : currentY
294
294
  }
295
295
  }
@@ -9,6 +9,10 @@ extension WKWebViewController {
9
9
  targetWebView.scrollView.refreshControl = nil
10
10
  }
11
11
 
12
+ // UIRefreshControl can leave sticky insets that clip the page header after reload.
13
+ targetWebView.scrollView.contentInset = .zero
14
+ targetWebView.scrollView.scrollIndicatorInsets = .zero
15
+
12
16
  guard enableReloadGesture, !disableOverscroll else {
13
17
  pendingReloadFromGesture = false
14
18
  reloadGestureArmedPullDistance = 0
@@ -41,7 +45,6 @@ extension WKWebViewController {
41
45
  isDragging: scrollView.isDragging
42
46
  ) {
43
47
  pendingReloadFromGesture = true
44
- // Capture the real activation pull distance from UIRefreshControl.
45
48
  reloadGestureArmedPullDistance = ReloadGestureSupport.pullDistance(
46
49
  contentOffsetY: scrollView.contentOffset.y,
47
50
  adjustedContentInsetTop: scrollView.adjustedContentInset.top
@@ -75,18 +78,16 @@ extension WKWebViewController {
75
78
  } else if !reloadFromGestureInProgress,
76
79
  scrollView.refreshControl?.isRefreshing == true {
77
80
  scrollView.refreshControl?.endRefreshing()
78
- resetReloadGestureScrollState(on: scrollView, forceToRestingTop: false)
81
+ hardResetReloadGestureScroll(on: scrollView)
79
82
  }
80
83
 
81
84
  case .cancelled, .failed:
82
- // System interruption — never commit a reload.
83
85
  pendingReloadFromGesture = false
84
86
  reloadGestureArmedPullDistance = 0
85
- // Don't touch an in-flight gesture reload's spinner / scroll.
86
87
  guard !reloadFromGestureInProgress else { break }
87
88
  if scrollView.refreshControl?.isRefreshing == true {
88
89
  scrollView.refreshControl?.endRefreshing()
89
- resetReloadGestureScrollState(on: scrollView, forceToRestingTop: false)
90
+ hardResetReloadGestureScroll(on: scrollView)
90
91
  }
91
92
 
92
93
  default:
@@ -98,21 +99,35 @@ extension WKWebViewController {
98
99
  pendingReloadFromGesture = false
99
100
  reloadGestureArmedPullDistance = 0
100
101
  reloadFromGestureInProgress = true
101
- // Track this navigation so cancelled prior loads don't clear gesture state early.
102
- reloadGestureNavigation = self.capableWebView?.reload()
102
+
103
+ guard let webView = self.capableWebView else {
104
+ stopReloadGesture()
105
+ return
106
+ }
107
+
108
+ // `reload()` preserves broken scroll/inset state after UIRefreshControl.
109
+ // A fresh URL load matches a normal navigation and resets scroll like the reporter's "proper" reload.
110
+ if let url = webView.url {
111
+ reloadGestureNavigation = webView.load(URLRequest(url: url))
112
+ } else {
113
+ reloadGestureNavigation = webView.reload()
114
+ }
115
+
103
116
  if reloadGestureNavigation == nil {
104
117
  stopReloadGesture()
105
118
  }
106
119
  }
107
120
 
108
- private func resetReloadGestureScrollState(on scrollView: UIScrollView, forceToRestingTop: Bool) {
121
+ private func hardResetReloadGestureScroll(on scrollView: UIScrollView) {
122
+ scrollView.contentInset = .zero
123
+ scrollView.scrollIndicatorInsets = .zero
109
124
  let resetY = ReloadGestureSupport.contentOffsetYAfterReloadReset(
110
125
  currentY: scrollView.contentOffset.y,
111
- adjustedContentInsetTop: scrollView.adjustedContentInset.top,
112
- forceToRestingTop: forceToRestingTop
126
+ adjustedContentInsetTop: 0,
127
+ forceToRestingTop: true
113
128
  )
114
- if resetY != scrollView.contentOffset.y {
115
- scrollView.setContentOffset(CGPoint(x: scrollView.contentOffset.x, y: resetY), animated: false)
129
+ if scrollView.contentOffset.y != resetY || scrollView.contentOffset.x != 0 {
130
+ scrollView.setContentOffset(CGPoint(x: 0, y: resetY), animated: false)
116
131
  }
117
132
  }
118
133
 
@@ -121,7 +136,6 @@ extension WKWebViewController {
121
136
  reloadFromGestureInProgress: reloadFromGestureInProgress
122
137
  ) else { return }
123
138
 
124
- // Ignore unrelated navigation callbacks while a gesture reload is in flight.
125
139
  if let expected = reloadGestureNavigation,
126
140
  let navigation,
127
141
  expected !== navigation {
@@ -134,22 +148,23 @@ extension WKWebViewController {
134
148
  reloadGestureArmedPullDistance = 0
135
149
 
136
150
  guard let activeWebView = self.capableWebView else { return }
137
- let scrollView = activeWebView.scrollView
138
- scrollView.refreshControl?.endRefreshing()
151
+ activeWebView.scrollView.refreshControl?.endRefreshing()
139
152
 
140
- // UIRefreshControl + WKWebView.reload() often leave offset at 0 instead of
141
- // -adjustedContentInset.top (clips header ~safe-area) and block the next pull.
153
+ // Reset after the current runloop so WKWebView finishes applying navigation scroll state.
142
154
  DispatchQueue.main.async { [weak self] in
143
155
  guard let self, let activeWebView = self.capableWebView else { return }
144
156
  let scrollView = activeWebView.scrollView
145
157
  scrollView.refreshControl?.endRefreshing()
146
- self.resetReloadGestureScrollState(on: scrollView, forceToRestingTop: true)
158
+ self.hardResetReloadGestureScroll(on: scrollView)
147
159
  self.configureReloadGesture(for: activeWebView)
148
- // Rebind can change adjusted insets; snap again to the new resting top.
149
- self.resetReloadGestureScrollState(
150
- on: activeWebView.scrollView,
151
- forceToRestingTop: true
152
- )
160
+ self.hardResetReloadGestureScroll(on: activeWebView.scrollView)
161
+ activeWebView.evaluateJavaScript("window.scrollTo(0, 0);", completionHandler: nil)
162
+
163
+ // One more pass after layout / JS scroll restoration.
164
+ DispatchQueue.main.async { [weak self] in
165
+ guard let self, let activeWebView = self.capableWebView else { return }
166
+ self.hardResetReloadGestureScroll(on: activeWebView.scrollView)
167
+ }
153
168
  }
154
169
  }
155
170
  }
@@ -3523,10 +3523,11 @@ extension WKWebViewController: WKNavigationDelegate {
3523
3523
  delegate?.webViewController?(self, didFinish: url)
3524
3524
  }
3525
3525
  self.injectJavaScriptInterface()
3526
+ // End refresh + clear sticky insets before safe-area sync zeroes contentInset.
3527
+ stopReloadGesture(for: navigation)
3526
3528
  lastInjectedSafeAreaInsets = nil
3527
3529
  syncWebViewSafeAreaLayout()
3528
3530
  emit("browserPageLoaded")
3529
- stopReloadGesture(for: navigation)
3530
3531
  }
3531
3532
 
3532
3533
  public func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-inappbrowser",
3
- "version": "8.12.2-beta.pr634.545.1",
3
+ "version": "8.12.2-beta.pr634.551.1",
4
4
  "description": "Capacitor plugin in app browser",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",