@onekeyfe/react-native-chart-webview 3.0.61 → 3.0.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/ChartWebview.podspec +0 -3
  2. package/android/src/main/java/com/margelo/nitro/chartwebview/ChartWebview.kt +18 -85
  3. package/android/src/main/java/com/margelo/nitro/chartwebview/PooledChartWebView.kt +26 -253
  4. package/ios/ChartWebview.swift +31 -190
  5. package/lib/nitrogen/generated/android/c++/JHybridChartWebviewSpec.cpp +0 -18
  6. package/lib/nitrogen/generated/android/c++/JHybridChartWebviewSpec.hpp +0 -4
  7. package/lib/nitrogen/generated/android/c++/views/JHybridChartWebviewStateUpdater.cpp +0 -8
  8. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/HybridChartWebviewSpec.kt +0 -12
  9. package/lib/nitrogen/generated/ios/c++/HybridChartWebviewSpecSwift.hpp +0 -14
  10. package/lib/nitrogen/generated/ios/c++/views/HybridChartWebviewComponent.mm +0 -10
  11. package/lib/nitrogen/generated/ios/swift/HybridChartWebviewSpec.swift +0 -2
  12. package/lib/nitrogen/generated/ios/swift/HybridChartWebviewSpec_cxx.swift +0 -48
  13. package/lib/nitrogen/generated/shared/c++/HybridChartWebviewSpec.cpp +0 -4
  14. package/lib/nitrogen/generated/shared/c++/HybridChartWebviewSpec.hpp +0 -4
  15. package/lib/nitrogen/generated/shared/c++/views/HybridChartWebviewComponent.cpp +0 -24
  16. package/lib/nitrogen/generated/shared/c++/views/HybridChartWebviewComponent.hpp +0 -2
  17. package/lib/nitrogen/generated/shared/json/ChartWebviewConfig.json +0 -2
  18. package/lib/nitrogen/nitrogen/generated/android/c++/JHybridChartWebviewSpec.cpp +0 -18
  19. package/lib/nitrogen/nitrogen/generated/android/c++/JHybridChartWebviewSpec.hpp +0 -4
  20. package/lib/nitrogen/nitrogen/generated/android/c++/views/JHybridChartWebviewStateUpdater.cpp +0 -8
  21. package/lib/nitrogen/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/HybridChartWebviewSpec.kt +0 -12
  22. package/lib/nitrogen/nitrogen/generated/ios/c++/HybridChartWebviewSpecSwift.hpp +0 -14
  23. package/lib/nitrogen/nitrogen/generated/ios/c++/views/HybridChartWebviewComponent.mm +0 -10
  24. package/lib/nitrogen/nitrogen/generated/ios/swift/HybridChartWebviewSpec.swift +0 -2
  25. package/lib/nitrogen/nitrogen/generated/ios/swift/HybridChartWebviewSpec_cxx.swift +0 -48
  26. package/lib/nitrogen/nitrogen/generated/shared/c++/HybridChartWebviewSpec.cpp +0 -4
  27. package/lib/nitrogen/nitrogen/generated/shared/c++/HybridChartWebviewSpec.hpp +0 -4
  28. package/lib/nitrogen/nitrogen/generated/shared/c++/views/HybridChartWebviewComponent.cpp +0 -24
  29. package/lib/nitrogen/nitrogen/generated/shared/c++/views/HybridChartWebviewComponent.hpp +0 -2
  30. package/lib/nitrogen/nitrogen/generated/shared/json/ChartWebviewConfig.json +0 -2
  31. package/lib/typescript/src/ChartWebview.nitro.d.ts +0 -2
  32. package/lib/typescript/src/ChartWebview.nitro.d.ts.map +1 -1
  33. package/lib/typescript/src/index.d.ts +0 -2
  34. package/lib/typescript/src/index.d.ts.map +1 -1
  35. package/nitrogen/generated/android/c++/JHybridChartWebviewSpec.cpp +0 -18
  36. package/nitrogen/generated/android/c++/JHybridChartWebviewSpec.hpp +0 -4
  37. package/nitrogen/generated/android/c++/views/JHybridChartWebviewStateUpdater.cpp +0 -8
  38. package/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/HybridChartWebviewSpec.kt +0 -12
  39. package/nitrogen/generated/ios/c++/HybridChartWebviewSpecSwift.hpp +0 -14
  40. package/nitrogen/generated/ios/c++/views/HybridChartWebviewComponent.mm +0 -10
  41. package/nitrogen/generated/ios/swift/HybridChartWebviewSpec.swift +0 -2
  42. package/nitrogen/generated/ios/swift/HybridChartWebviewSpec_cxx.swift +0 -48
  43. package/nitrogen/generated/shared/c++/HybridChartWebviewSpec.cpp +0 -4
  44. package/nitrogen/generated/shared/c++/HybridChartWebviewSpec.hpp +0 -4
  45. package/nitrogen/generated/shared/c++/views/HybridChartWebviewComponent.cpp +0 -24
  46. package/nitrogen/generated/shared/c++/views/HybridChartWebviewComponent.hpp +0 -2
  47. package/nitrogen/generated/shared/json/ChartWebviewConfig.json +0 -2
  48. package/package.json +1 -1
  49. package/src/ChartWebview.nitro.ts +0 -18
@@ -1,7 +1,6 @@
1
1
  import Foundation
2
2
  import UIKit
3
3
  import WebKit
4
- import ReactNativeNativeLogger
5
4
 
6
5
  // MARK: - Constants (shared)
7
6
 
@@ -14,25 +13,6 @@ private enum ChartWebviewConst {
14
13
  static let messageHandlerName = "onekeyChart"
15
14
  }
16
15
 
17
- // MARK: - Diagnostic logging (DEBUG instrumentation)
18
- //
19
- // Routes the chart-webview native lifecycle into the shared OneKeyLog file
20
- // (app-latest.log) so the offline / prewarm / pool-ownership chain is visible
21
- // alongside the JS `market => chart => *` events. Tag is "ChartWV". Raw NSLog
22
- // is NOT enough — it never reaches app-latest.log, which is why the native side
23
- // was previously invisible during log analysis. Truncates payloads to keep the
24
- // file readable and avoid leaking message bodies.
25
- enum ChartWVLog {
26
- static func i(_ msg: String) { OneKeyLog.info("ChartWV", msg) }
27
- static func w(_ msg: String) { OneKeyLog.warn("ChartWV", msg) }
28
- static func e(_ msg: String) { OneKeyLog.error("ChartWV", msg) }
29
- /// Truncate a (possibly large / sensitive) payload for logging.
30
- static func clip(_ s: String?, _ n: Int = 120) -> String {
31
- guard let s = s else { return "nil" }
32
- return s.count <= n ? s : String(s.prefix(n)) + "…(\(s.count))"
33
- }
34
- }
35
-
36
16
  // MARK: - ChartContainerView (window-attach detection)
37
17
 
38
18
  /// The host's `view`. Reports when it is attached to / detached from a window so
@@ -89,12 +69,9 @@ class HybridChartWebview: HybridChartWebviewSpec {
89
69
 
90
70
  override init() {
91
71
  super.init()
92
- ChartWVLog.i("host.init id=\(instanceId)")
93
72
  container.onWindowChange = { [weak self] attached in
94
- guard let self = self else { return }
95
- ChartWVLog.i("host.windowChange id=\(self.instanceId) attached=\(attached) reuseKey=\(self.reuseKey ?? "nil") pooled=\(String(describing: self.pooled)) active=\(String(describing: self.active))")
96
- self.attached = attached
97
- self.scheduleReconcile()
73
+ self?.attached = attached
74
+ self?.scheduleReconcile()
98
75
  }
99
76
  }
100
77
 
@@ -120,24 +97,15 @@ class HybridChartWebview: HybridChartWebviewSpec {
120
97
 
121
98
  // MARK: - Props (source)
122
99
 
123
- // Source/bridge setters call applySource (synchronous) NOT scheduleReconcile,
124
- // which loops (reconcile -> setSource -> prop re-apply -> reconcile ...).
125
- // applySource sets warmDriver + warm-boots the page even when this host is not
126
- // the visible owner, so a bridge prop arriving after the window-attach reconcile
127
- // still makes this host the warm driver (page->native callbacks fall back to it).
128
- var uri: String? { didSet { applySource() } }
129
- var localBundle: String? { didSet { applySource() } }
130
- var entry: String? { didSet { applySource() } }
131
- var paramsJson: String? { didSet { applySource() } }
132
- // ANDROID ONLY. iOS serves offline content from the onekey-chart:// custom
133
- // scheme (https can't be intercepted here), so this host stores the prop to
134
- // satisfy the generated spec but never reads it — offline origin/behavior is
135
- // unchanged on iOS.
136
- var assetHost: String?
100
+ var uri: String? { didSet { applySourceIfOwner() } }
101
+ var localBundle: String? { didSet { applySourceIfOwner() } }
102
+ var entry: String? { didSet { applySourceIfOwner() } }
103
+ var paramsJson: String? { didSet { applySourceIfOwner() } }
137
104
 
138
105
  // Document-start bridge JS (single source of truth in the TS layer). Handed to
139
- // the pooled WebView when we claim it, before its first load.
140
- var bridgeScript: String? { didSet { applySource() } }
106
+ // the pooled WebView when we claim it, before its first load. Re-applying the
107
+ // source on change triggers a deferred load if this prop lands after the source.
108
+ var bridgeScript: String? { didSet { applySourceIfOwner() } }
141
109
 
142
110
  // MARK: - Props (singleton)
143
111
 
@@ -164,20 +132,6 @@ class HybridChartWebview: HybridChartWebviewSpec {
164
132
  }
165
133
  }
166
134
 
167
- // MARK: - Props (debugging)
168
-
169
- // Make the backing WKWebView inspectable (Safari Web Inspector). Driven by the
170
- // app's "Enable Native Webview Debugging" dev-mode toggle, mirroring the main
171
- // react-native-webview (which sets WKWebView.isInspectable). nil => default to
172
- // the DEBUG build behavior (see PooledChartWebView.applyInspectable). Applied to
173
- // the backing WebView both here (on prop change) and at WebView creation, since
174
- // `backing` is nil until the first reconcile assigns it.
175
- var webviewDebuggingEnabled: Bool? {
176
- didSet {
177
- backing?.setInspectable(webviewDebuggingEnabled)
178
- }
179
- }
180
-
181
135
  // MARK: - Props (events)
182
136
 
183
137
  var onMessage: ((_ message: String) -> Void)?
@@ -186,10 +140,6 @@ class HybridChartWebview: HybridChartWebviewSpec {
186
140
 
187
141
  // Called by the backing PooledChartWebView while this host is the owner.
188
142
  func handleMessage(_ message: String) {
189
- // page -> native. Truncated; OneKeyLog rate-limits/dedups repeats so streaming
190
- // data won't flood. Key for Q2 (market chart no data): shows the page's
191
- // $private kline requests and whether replies come back.
192
- ChartWVLog.i("msg.in id=\(instanceId) \(ChartWVLog.clip(message, 200))")
193
143
  // The chart reports it has painted the new symbol after a switch; that's our
194
144
  // cue to drop the snapshot we held over the switch and reveal the live chart.
195
145
  if message.contains(HybridChartWebview.renderReadyMarker) { onContentRendered() }
@@ -217,25 +167,6 @@ class HybridChartWebview: HybridChartWebviewSpec {
217
167
 
218
168
  private func wantsOwnership() -> Bool { attached && (active != false) }
219
169
 
220
- // Apply the source synchronously on a source/bridge prop change. For a pooled
221
- // host this ALSO registers it as the warmDriver and warm-boots the page even
222
- // when it is not the visible owner, so page->native callbacks (bars-state /
223
- // load-end) fall back to it when no host owns the pool. No scheduleReconcile —
224
- // that loops. `backing` is nil until the first reconcile assigns it (reuseKey /
225
- // pooled / active setters still scheduleReconcile), so warmDriver is set on the
226
- // first prop change after the pool entry is acquired.
227
- private func applySource() {
228
- guard let pooled = backing else { return }
229
- if isPooled(), let bs = bridgeScript, !bs.isEmpty {
230
- pooled.setBridgeScript(bs)
231
- pooled.warmDriver = self
232
- pooled.setSource(uri: uri, localBundle: localBundle, entry: entry, paramsJson: paramsJson)
233
- } else if pooled.owner === self {
234
- pooled.setBridgeScript(bridgeScript ?? "")
235
- pooled.setSource(uri: uri, localBundle: localBundle, entry: entry, paramsJson: paramsJson)
236
- }
237
- }
238
-
239
170
  // A single React commit applies props one at a time, so the intermediate
240
171
  // states are inconsistent (e.g. `pooled` re-applied while `active` is still
241
172
  // stale). Reacting to each setter synchronously makes the wrong host claim
@@ -263,9 +194,6 @@ class HybridChartWebview: HybridChartWebviewSpec {
263
194
  let key = effectiveKey()
264
195
  let pooled = ChartWebviewPool.shared.acquireShared(key: key)
265
196
  backing = pooled
266
- // Apply this host's debug preference to the (possibly freshly created) backing
267
- // WebView. Mirrors the main react-native-webview toggling WKWebView.isInspectable.
268
- pooled.setInspectable(webviewDebuggingEnabled)
269
197
  // Refcount the entry once per host (reconcile runs many times). Balanced by
270
198
  // releaseShared in deinit. If the reuseKey changed, release the old one first.
271
199
  if adoptedPoolKey != key {
@@ -273,36 +201,13 @@ class HybridChartWebview: HybridChartWebviewSpec {
273
201
  ChartWebviewPool.shared.adopt(key: key)
274
202
  adoptedPoolKey = key
275
203
  }
276
- ChartWVLog.i("reconcilePooled id=\(instanceId) key=\(key) wantsOwnership=\(wantsOwnership()) (attached=\(attached) active=\(String(describing: active))) bridgeLen=\((bridgeScript ?? "").count) localBundle=\(localBundle ?? "nil") entry=\(entry ?? "nil")")
277
-
278
- // Q1 FIX: WARM-BOOT the shared offline page as soon as ANY referencing host
279
- // has the document-start bridge + a source — even when this host is NOT the
280
- // visible owner (the offscreen prewarm runs with attached=false/active=false,
281
- // so the old code, which only loaded inside `wantsOwnership()`, never booted
282
- // the page until a real chart screen attached+focused). LOAD is now decoupled
283
- // from view ownership: ownership below still governs attach / reveal / snapshot.
284
- // Idempotent across hosts — the unified URL is constant (setSource logs
285
- // SAME_URL), and setBridgeScript no-ops once registered.
286
- if let bs = bridgeScript, !bs.isEmpty {
287
- ChartWVLog.i("reconcilePooled.WARM id=\(instanceId) key=\(key) (owner-independent boot; wantsOwnership=\(wantsOwnership()))")
288
- pooled.setBridgeScript(bs)
289
- // Q1 FIX (data): register as the warm DRIVER (NOT owner — the YIELD branch
290
- // below clears `owner`, which is why the previous provisional-owner attempt
291
- // was wiped in the same reconcile). didFinish / page messages fall back to
292
- // warmDriver when there's no visible owner, so the page is driven its symbol
293
- // the instant it loads instead of waiting ~5s for a focused host to claim.
294
- pooled.warmDriver = self
295
- ChartWVLog.i("reconcilePooled.WARM_DRIVER id=\(instanceId) key=\(key)")
296
- // setSource internally guards (bridgeRegistered / SAME_URL / NO_URL), so this
297
- // is idempotent and a no-op when there is nothing new to load.
298
- pooled.setSource(uri: uri, localBundle: localBundle, entry: entry, paramsJson: paramsJson)
299
- }
300
-
301
204
  if wantsOwnership() {
302
- let wasOwner = pooled.owner === self
303
205
  pooled.owner = self
304
- ChartWVLog.i("reconcilePooled.CLAIM id=\(instanceId) key=\(key) wasOwner=\(wasOwner)")
206
+ // Register the document-start bridge before the first load (the prop is set
207
+ // by now; the pool may have been created earlier by a window-attach reconcile).
208
+ pooled.setBridgeScript(bridgeScript ?? "")
305
209
  pooled.attach(to: container)
210
+ pooled.setSource(uri: uri, localBundle: localBundle, entry: entry, paramsJson: paramsJson)
306
211
  // Keep a fresh frame of OUR content while we own the WebView, so that when
307
212
  // we later go inactive (and the shared WebView reloads the other slot's
308
213
  // chart) our slot freezes to its own last frame, not the other content.
@@ -319,7 +224,6 @@ class HybridChartWebview: HybridChartWebviewSpec {
319
224
  // Inactive: give up ownership only if we still hold it, and freeze to our
320
225
  // own last captured frame. We do NOT detach (that races a rapid re-claim).
321
226
  let wasOwner = pooled.owner === self
322
- ChartWVLog.i("reconcilePooled.YIELD id=\(instanceId) key=\(key) wasOwner=\(wasOwner) (attached=\(attached) active=\(String(describing: active)))")
323
227
  if wasOwner { pooled.owner = nil }
324
228
  stopOwnCapture()
325
229
  showPlaceholder(ownSnapshot)
@@ -358,13 +262,19 @@ class HybridChartWebview: HybridChartWebviewSpec {
358
262
  guard wantsOwnership() else { return }
359
263
  let pooled = backing ?? PooledChartWebView(key: effectiveKey())
360
264
  backing = pooled
361
- pooled.setInspectable(webviewDebuggingEnabled)
362
265
  pooled.owner = self
363
266
  pooled.setBridgeScript(bridgeScript ?? "")
364
267
  pooled.attach(to: container)
365
268
  pooled.setSource(uri: uri, localBundle: localBundle, entry: entry, paramsJson: paramsJson)
366
269
  }
367
270
 
271
+ private func applySourceIfOwner() {
272
+ guard let pooled = backing, pooled.owner === self else { return }
273
+ // Register the bridge before any load setSource may trigger (setSource defers
274
+ // loading until the bridge is registered).
275
+ pooled.setBridgeScript(bridgeScript ?? "")
276
+ pooled.setSource(uri: uri, localBundle: localBundle, entry: entry, paramsJson: paramsJson)
277
+ }
368
278
 
369
279
  // MARK: - Snapshot placeholder (shown while this host is inactive)
370
280
 
@@ -442,13 +352,6 @@ final class PooledChartWebView {
442
352
 
443
353
  let key: String
444
354
  weak var owner: HybridChartWebview?
445
- // Q1 FIX (data): the host that warm-booted the page and can drive its symbol /
446
- // service its callbacks while there is no VISIBLE owner yet. Separate from
447
- // `owner` because the reconcile YIELD branch clears `owner` to nil (so a
448
- // provisional owner never survived to nav.didFinish). Callbacks fall back to
449
- // this when `owner` is nil, so the page is told its symbol the instant it loads
450
- // instead of waiting ~5s for a focused host to attach/claim.
451
- weak var warmDriver: HybridChartWebview?
452
355
 
453
356
  // The page's user-content controller, kept so the document-start bridge can be
454
357
  // added lazily (see setBridgeScript) once the host has the prop value.
@@ -463,11 +366,6 @@ final class PooledChartWebView {
463
366
  private var lastLoadedUrl: String?
464
367
  private var attachGeneration = 0
465
368
 
466
- // Whether the backing WKWebView should be inspectable (Safari Web Inspector).
467
- // nil until a host applies its debug preference; defaults to the DEBUG build
468
- // behavior (see resolvedInspectable), mirroring the main react-native-webview.
469
- private var inspectablePreference: Bool?
470
-
471
369
  /// Read by the scheme handler to resolve offline files.
472
370
  fileprivate var currentLocalBundle: String?
473
371
 
@@ -481,7 +379,7 @@ final class PooledChartWebView {
481
379
  init(key: String) {
482
380
  self.key = key
483
381
  PooledChartWebView.liveCount += 1
484
- ChartWVLog.i("pool.CREATE key=\(key) liveCount=\(PooledChartWebView.liveCount)")
382
+ NSLog("[ChartWebviewPool] WebView CREATED key=\(key) liveCount=\(PooledChartWebView.liveCount)")
485
383
  setupWebView()
486
384
  }
487
385
 
@@ -490,10 +388,7 @@ final class PooledChartWebView {
490
388
  // subsequent calls are no-ops. Done lazily because the first reconcile
491
389
  // (window-attach) can run before the bridgeScript prop is applied.
492
390
  func setBridgeScript(_ bridgeScript: String) {
493
- guard !bridgeScript.isEmpty, let userContent = userContent else {
494
- ChartWVLog.w("setBridgeScript.SKIP key=\(key) empty=\(bridgeScript.isEmpty) hasUserContent=\(userContent != nil) -> bridgeRegistered stays \(bridgeRegistered)")
495
- return
496
- }
391
+ guard !bridgeScript.isEmpty, let userContent = userContent else { return }
497
392
  // Re-register if a second host sharing the reuseKey supplies a DIFFERENT script
498
393
  // instead of silently dropping it (fix #4). In the app's single-reuseKey +
499
394
  // constant-bridge reality this never fires; not latching keeps it correct.
@@ -504,7 +399,6 @@ final class PooledChartWebView {
504
399
  }
505
400
  bridgeRegistered = true
506
401
  registeredBridgeScript = bridgeScript
507
- ChartWVLog.i("setBridgeScript.REGISTERED key=\(key) len=\(bridgeScript.count)")
508
402
  let handlerName = ChartWebviewConst.messageHandlerName
509
403
  let shim = "(function(){window.__chartNativePost=function(s){"
510
404
  + "window.webkit.messageHandlers.\(handlerName).postMessage(s);};})();"
@@ -548,37 +442,10 @@ final class PooledChartWebView {
548
442
  webView.navigationDelegate = proxy
549
443
  webView.uiDelegate = proxy
550
444
  webView.scrollView.bounces = false
551
- self.webView = webView
552
- // Honor the app's dev-mode webview-debug toggle instead of an unconditional
553
- // `true`. nil (no preference applied yet) falls back to the DEBUG build default.
554
- applyInspectable()
555
- }
556
-
557
- // Set the host-driven debug preference and apply it to the live WebView. Called
558
- // both on the prop change and at host claim, so the (possibly newly created)
559
- // WebView always reflects the latest toggle value.
560
- func setInspectable(_ enabled: Bool?) {
561
- inspectablePreference = enabled
562
- applyInspectable()
563
- }
564
-
565
- // Resolve the effective inspectable value: explicit preference if set, otherwise
566
- // the DEBUG build default (mirrors the main react-native-webview, which is
567
- // inspectable in dev builds even without the toggle).
568
- private func resolvedInspectable() -> Bool {
569
- if let pref = inspectablePreference { return pref }
570
- #if DEBUG
571
- return true
572
- #else
573
- return false
574
- #endif
575
- }
576
-
577
- private func applyInspectable() {
578
- guard let webView = webView else { return }
579
445
  if #available(iOS 16.4, *) {
580
- webView.isInspectable = resolvedInspectable()
446
+ webView.isInspectable = true
581
447
  }
448
+ self.webView = webView
582
449
  }
583
450
 
584
451
  // MARK: - Reparenting
@@ -631,7 +498,7 @@ final class PooledChartWebView {
631
498
  self.userContent = nil
632
499
  self.webView = nil
633
500
  PooledChartWebView.liveCount -= 1
634
- ChartWVLog.i("pool.DESTROY key=\(self.key) liveCount=\(PooledChartWebView.liveCount)")
501
+ NSLog("[ChartWebviewPool] WebView DESTROYED key=\(self.key) liveCount=\(PooledChartWebView.liveCount)")
635
502
  }
636
503
  }
637
504
 
@@ -703,26 +570,15 @@ final class PooledChartWebView {
703
570
  // Never load before the document-start bridge is registered — otherwise the
704
571
  // page boots without the bridge and its first $private requests are lost. The
705
572
  // host re-calls setSource once the bridgeScript prop arrives.
706
- guard bridgeRegistered else {
707
- ChartWVLog.w("setSource.BLOCKED key=\(key) bridgeRegistered=false -> NOT loading (will retry when bridgeScript arrives). uri=\(ChartWVLog.clip(uri)) localBundle=\(localBundle ?? "nil")")
708
- return
709
- }
573
+ guard bridgeRegistered else { return }
710
574
  currentLocalBundle = localBundle
711
- guard let urlString = computeTargetUrl(uri: uri, localBundle: localBundle, entry: entry, paramsJson: paramsJson) else {
712
- ChartWVLog.w("setSource.NO_URL key=\(key) uri=\(ChartWVLog.clip(uri)) localBundle=\(localBundle ?? "nil") entry=\(entry ?? "nil") -> nothing to load")
713
- return
714
- }
715
- guard urlString != lastLoadedUrl else {
716
- ChartWVLog.i("setSource.SAME_URL key=\(key) skip reload url=\(ChartWVLog.clip(urlString))")
717
- return
718
- }
575
+ guard let urlString = computeTargetUrl(uri: uri, localBundle: localBundle, entry: entry, paramsJson: paramsJson) else { return }
576
+ guard urlString != lastLoadedUrl else { return }
719
577
  guard let url = URL(string: urlString) else {
720
- ChartWVLog.e("setSource.INVALID_URL key=\(key) url=\(ChartWVLog.clip(urlString))")
721
578
  owner?.handleError("Invalid url: \(urlString)")
722
579
  return
723
580
  }
724
581
  lastLoadedUrl = urlString
725
- ChartWVLog.i("setSource.LOAD key=\(key) url=\(ChartWVLog.clip(urlString))")
726
582
  runOnMain { [weak self] in self?.webView?.load(URLRequest(url: url)) }
727
583
  }
728
584
 
@@ -766,12 +622,8 @@ final class PooledChartWebView {
766
622
  // MARK: - Bridge methods
767
623
 
768
624
  func postMessage(_ message: String) {
769
- ChartWVLog.i("msg.out key=\(key) \(ChartWVLog.clip(message, 200))")
770
625
  runOnMain { [weak self] in
771
- guard let self = self, let webView = self.webView else {
772
- ChartWVLog.w("msg.out.DROPPED no webView")
773
- return
774
- }
626
+ guard let self = self, let webView = self.webView else { return }
775
627
  let jsStringLiteral = self.jsStringLiteral(from: message)
776
628
  let js = "window.postMessage(JSON.parse(\(jsStringLiteral)), '*')"
777
629
  webView.evaluateJavaScript(js, completionHandler: nil)
@@ -825,9 +677,7 @@ extension ChartWebViewProxy: WKScriptMessageHandler {
825
677
  didReceive message: WKScriptMessage
826
678
  ) {
827
679
  guard message.name == ChartWebviewConst.messageHandlerName else { return }
828
- // Q1 FIX: route page->native messages ($private data requests) to the warm
829
- // driver when there's no visible owner, so they aren't dropped during warm.
830
- let owner = pooled?.owner ?? pooled?.warmDriver
680
+ let owner = pooled?.owner
831
681
  if let body = message.body as? String {
832
682
  owner?.handleMessage(body)
833
683
  } else if let data = try? JSONSerialization.data(withJSONObject: message.body, options: []),
@@ -843,22 +693,16 @@ extension ChartWebViewProxy: WKScriptMessageHandler {
843
693
 
844
694
  extension ChartWebViewProxy: WKNavigationDelegate {
845
695
  func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
846
- // Q1 FIX: fall back to warmDriver when there's no visible owner yet, so the
847
- // page's load-complete callback (-> JS onLoadEnd -> SYMBOL_CHANGE) fires now.
848
- let target = pooled?.owner ?? pooled?.warmDriver
849
- ChartWVLog.i("nav.didFinish url=\(ChartWVLog.clip(webView.url?.absoluteString)) hasOwner=\(pooled?.owner != nil) viaWarmDriver=\(pooled?.owner == nil && pooled?.warmDriver != nil)")
850
- target?.handleLoadEnd()
696
+ pooled?.owner?.handleLoadEnd()
851
697
  // Prime the snapshot so the first move already has a frame to mask with.
852
698
  pooled?.refreshSnapshotSoon()
853
699
  }
854
700
 
855
701
  func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
856
- ChartWVLog.e("nav.didFail url=\(ChartWVLog.clip(webView.url?.absoluteString)) error=\(error.localizedDescription)")
857
702
  pooled?.owner?.handleError(error.localizedDescription)
858
703
  }
859
704
 
860
705
  func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
861
- ChartWVLog.e("nav.didFailProvisional url=\(ChartWVLog.clip(webView.url?.absoluteString)) error=\(error.localizedDescription)")
862
706
  pooled?.owner?.handleError(error.localizedDescription)
863
707
  }
864
708
  }
@@ -879,7 +723,6 @@ extension ChartWebViewProxy: WKURLSchemeHandler {
879
723
  }
880
724
 
881
725
  guard let localBundle = pooled?.currentLocalBundle, !localBundle.isEmpty else {
882
- ChartWVLog.e("scheme.NO_BUNDLE url=\(ChartWVLog.clip(url.absoluteString)) -> 404 (currentLocalBundle empty)")
883
726
  respondNotFound(url: url, task: urlSchemeTask)
884
727
  return
885
728
  }
@@ -890,11 +733,9 @@ extension ChartWebViewProxy: WKURLSchemeHandler {
890
733
 
891
734
  guard let fileURL = resolveBundleFileURL(localBundle: localBundle, relativePath: relativePath),
892
735
  let data = try? Data(contentsOf: fileURL) else {
893
- ChartWVLog.e("scheme.404 bundle=\(localBundle) path=\(relativePath) (resolved=\(resolveBundleFileURL(localBundle: localBundle, relativePath: relativePath)?.path ?? "nil")) -> Not Found")
894
736
  respondNotFound(url: url, task: urlSchemeTask)
895
737
  return
896
738
  }
897
- ChartWVLog.i("scheme.serve bundle=\(localBundle) path=\(relativePath) bytes=\(data.count)")
898
739
 
899
740
  let headers: [String: String] = [
900
741
  "Content-Type": mimeTypeForPath(fileURL.pathExtension),
@@ -81,15 +81,6 @@ namespace margelo::nitro::chartwebview {
81
81
  static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* paramsJson */)>("setParamsJson");
82
82
  method(_javaPart, paramsJson.has_value() ? jni::make_jstring(paramsJson.value()) : nullptr);
83
83
  }
84
- std::optional<std::string> JHybridChartWebviewSpec::getAssetHost() {
85
- static const auto method = javaClassStatic()->getMethod<jni::local_ref<jni::JString>()>("getAssetHost");
86
- auto __result = method(_javaPart);
87
- return __result != nullptr ? std::make_optional(__result->toStdString()) : std::nullopt;
88
- }
89
- void JHybridChartWebviewSpec::setAssetHost(const std::optional<std::string>& assetHost) {
90
- static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* assetHost */)>("setAssetHost");
91
- method(_javaPart, assetHost.has_value() ? jni::make_jstring(assetHost.value()) : nullptr);
92
- }
93
84
  std::optional<std::string> JHybridChartWebviewSpec::getBridgeScript() {
94
85
  static const auto method = javaClassStatic()->getMethod<jni::local_ref<jni::JString>()>("getBridgeScript");
95
86
  auto __result = method(_javaPart);
@@ -126,15 +117,6 @@ namespace margelo::nitro::chartwebview {
126
117
  static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JBoolean> /* active */)>("setActive");
127
118
  method(_javaPart, active.has_value() ? jni::JBoolean::valueOf(active.value()) : nullptr);
128
119
  }
129
- std::optional<bool> JHybridChartWebviewSpec::getWebviewDebuggingEnabled() {
130
- static const auto method = javaClassStatic()->getMethod<jni::local_ref<jni::JBoolean>()>("getWebviewDebuggingEnabled");
131
- auto __result = method(_javaPart);
132
- return __result != nullptr ? std::make_optional(static_cast<bool>(__result->value())) : std::nullopt;
133
- }
134
- void JHybridChartWebviewSpec::setWebviewDebuggingEnabled(std::optional<bool> webviewDebuggingEnabled) {
135
- static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JBoolean> /* webviewDebuggingEnabled */)>("setWebviewDebuggingEnabled");
136
- method(_javaPart, webviewDebuggingEnabled.has_value() ? jni::JBoolean::valueOf(webviewDebuggingEnabled.value()) : nullptr);
137
- }
138
120
  std::optional<std::function<void(const std::string& /* message */)>> JHybridChartWebviewSpec::getOnMessage() {
139
121
  static const auto method = javaClassStatic()->getMethod<jni::local_ref<JFunc_void_std__string::javaobject>()>("getOnMessage_cxx");
140
122
  auto __result = method(_javaPart);
@@ -58,8 +58,6 @@ namespace margelo::nitro::chartwebview {
58
58
  void setEntry(const std::optional<std::string>& entry) override;
59
59
  std::optional<std::string> getParamsJson() override;
60
60
  void setParamsJson(const std::optional<std::string>& paramsJson) override;
61
- std::optional<std::string> getAssetHost() override;
62
- void setAssetHost(const std::optional<std::string>& assetHost) override;
63
61
  std::optional<std::string> getBridgeScript() override;
64
62
  void setBridgeScript(const std::optional<std::string>& bridgeScript) override;
65
63
  std::optional<std::string> getReuseKey() override;
@@ -68,8 +66,6 @@ namespace margelo::nitro::chartwebview {
68
66
  void setPooled(std::optional<bool> pooled) override;
69
67
  std::optional<bool> getActive() override;
70
68
  void setActive(std::optional<bool> active) override;
71
- std::optional<bool> getWebviewDebuggingEnabled() override;
72
- void setWebviewDebuggingEnabled(std::optional<bool> webviewDebuggingEnabled) override;
73
69
  std::optional<std::function<void(const std::string& /* message */)>> getOnMessage() override;
74
70
  void setOnMessage(const std::optional<std::function<void(const std::string& /* message */)>>& onMessage) override;
75
71
  std::optional<std::function<void()>> getOnLoadEnd() override;
@@ -52,10 +52,6 @@ void JHybridChartWebviewStateUpdater::updateViewProps(jni::alias_ref<jni::JClass
52
52
  view->setParamsJson(props.paramsJson.value);
53
53
  // TODO: Set isDirty = false
54
54
  }
55
- if (props.assetHost.isDirty) {
56
- view->setAssetHost(props.assetHost.value);
57
- // TODO: Set isDirty = false
58
- }
59
55
  if (props.bridgeScript.isDirty) {
60
56
  view->setBridgeScript(props.bridgeScript.value);
61
57
  // TODO: Set isDirty = false
@@ -72,10 +68,6 @@ void JHybridChartWebviewStateUpdater::updateViewProps(jni::alias_ref<jni::JClass
72
68
  view->setActive(props.active.value);
73
69
  // TODO: Set isDirty = false
74
70
  }
75
- if (props.webviewDebuggingEnabled.isDirty) {
76
- view->setWebviewDebuggingEnabled(props.webviewDebuggingEnabled.value);
77
- // TODO: Set isDirty = false
78
- }
79
71
  if (props.onMessage.isDirty) {
80
72
  view->setOnMessage(props.onMessage.value);
81
73
  // TODO: Set isDirty = false
@@ -66,12 +66,6 @@ abstract class HybridChartWebviewSpec: HybridView() {
66
66
  @set:Keep
67
67
  abstract var paramsJson: String?
68
68
 
69
- @get:DoNotStrip
70
- @get:Keep
71
- @set:DoNotStrip
72
- @set:Keep
73
- abstract var assetHost: String?
74
-
75
69
  @get:DoNotStrip
76
70
  @get:Keep
77
71
  @set:DoNotStrip
@@ -96,12 +90,6 @@ abstract class HybridChartWebviewSpec: HybridView() {
96
90
  @set:Keep
97
91
  abstract var active: Boolean?
98
92
 
99
- @get:DoNotStrip
100
- @get:Keep
101
- @set:DoNotStrip
102
- @set:Keep
103
- abstract var webviewDebuggingEnabled: Boolean?
104
-
105
93
  abstract var onMessage: ((message: String) -> Unit)?
106
94
 
107
95
  private var onMessage_cxx: Func_void_std__string?
@@ -86,13 +86,6 @@ namespace margelo::nitro::chartwebview {
86
86
  inline void setParamsJson(const std::optional<std::string>& paramsJson) noexcept override {
87
87
  _swiftPart.setParamsJson(paramsJson);
88
88
  }
89
- inline std::optional<std::string> getAssetHost() noexcept override {
90
- auto __result = _swiftPart.getAssetHost();
91
- return __result;
92
- }
93
- inline void setAssetHost(const std::optional<std::string>& assetHost) noexcept override {
94
- _swiftPart.setAssetHost(assetHost);
95
- }
96
89
  inline std::optional<std::string> getBridgeScript() noexcept override {
97
90
  auto __result = _swiftPart.getBridgeScript();
98
91
  return __result;
@@ -121,13 +114,6 @@ namespace margelo::nitro::chartwebview {
121
114
  inline void setActive(std::optional<bool> active) noexcept override {
122
115
  _swiftPart.setActive(active);
123
116
  }
124
- inline std::optional<bool> getWebviewDebuggingEnabled() noexcept override {
125
- auto __result = _swiftPart.getWebviewDebuggingEnabled();
126
- return __result;
127
- }
128
- inline void setWebviewDebuggingEnabled(std::optional<bool> webviewDebuggingEnabled) noexcept override {
129
- _swiftPart.setWebviewDebuggingEnabled(webviewDebuggingEnabled);
130
- }
131
117
  inline std::optional<std::function<void(const std::string& /* message */)>> getOnMessage() noexcept override {
132
118
  auto __result = _swiftPart.getOnMessage();
133
119
  return __result;
@@ -91,11 +91,6 @@ using namespace margelo::nitro::chartwebview::views;
91
91
  swiftPart.setParamsJson(newViewProps.paramsJson.value);
92
92
  newViewProps.paramsJson.isDirty = false;
93
93
  }
94
- // assetHost: optional
95
- if (newViewProps.assetHost.isDirty) {
96
- swiftPart.setAssetHost(newViewProps.assetHost.value);
97
- newViewProps.assetHost.isDirty = false;
98
- }
99
94
  // bridgeScript: optional
100
95
  if (newViewProps.bridgeScript.isDirty) {
101
96
  swiftPart.setBridgeScript(newViewProps.bridgeScript.value);
@@ -116,11 +111,6 @@ using namespace margelo::nitro::chartwebview::views;
116
111
  swiftPart.setActive(newViewProps.active.value);
117
112
  newViewProps.active.isDirty = false;
118
113
  }
119
- // webviewDebuggingEnabled: optional
120
- if (newViewProps.webviewDebuggingEnabled.isDirty) {
121
- swiftPart.setWebviewDebuggingEnabled(newViewProps.webviewDebuggingEnabled.value);
122
- newViewProps.webviewDebuggingEnabled.isDirty = false;
123
- }
124
114
  // onMessage: optional
125
115
  if (newViewProps.onMessage.isDirty) {
126
116
  swiftPart.setOnMessage(newViewProps.onMessage.value);
@@ -15,12 +15,10 @@ public protocol HybridChartWebviewSpec_protocol: HybridObject, HybridView {
15
15
  var localBundle: String? { get set }
16
16
  var entry: String? { get set }
17
17
  var paramsJson: String? { get set }
18
- var assetHost: String? { get set }
19
18
  var bridgeScript: String? { get set }
20
19
  var reuseKey: String? { get set }
21
20
  var pooled: Bool? { get set }
22
21
  var active: Bool? { get set }
23
- var webviewDebuggingEnabled: Bool? { get set }
24
22
  var onMessage: ((_ message: String) -> Void)? { get set }
25
23
  var onLoadEnd: (() -> Void)? { get set }
26
24
  var onError: ((_ message: String) -> Void)? { get set }
@@ -210,30 +210,6 @@ open class HybridChartWebviewSpec_cxx {
210
210
  }
211
211
  }
212
212
 
213
- public final var assetHost: bridge.std__optional_std__string_ {
214
- @inline(__always)
215
- get {
216
- return { () -> bridge.std__optional_std__string_ in
217
- if let __unwrappedValue = self.__implementation.assetHost {
218
- return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))
219
- } else {
220
- return .init()
221
- }
222
- }()
223
- }
224
- @inline(__always)
225
- set {
226
- self.__implementation.assetHost = { () -> String? in
227
- if bridge.has_value_std__optional_std__string_(newValue) {
228
- let __unwrapped = bridge.get_std__optional_std__string_(newValue)
229
- return String(__unwrapped)
230
- } else {
231
- return nil
232
- }
233
- }()
234
- }
235
- }
236
-
237
213
  public final var bridgeScript: bridge.std__optional_std__string_ {
238
214
  @inline(__always)
239
215
  get {
@@ -330,30 +306,6 @@ open class HybridChartWebviewSpec_cxx {
330
306
  }
331
307
  }
332
308
 
333
- public final var webviewDebuggingEnabled: bridge.std__optional_bool_ {
334
- @inline(__always)
335
- get {
336
- return { () -> bridge.std__optional_bool_ in
337
- if let __unwrappedValue = self.__implementation.webviewDebuggingEnabled {
338
- return bridge.create_std__optional_bool_(__unwrappedValue)
339
- } else {
340
- return .init()
341
- }
342
- }()
343
- }
344
- @inline(__always)
345
- set {
346
- self.__implementation.webviewDebuggingEnabled = { () -> Bool? in
347
- if bridge.has_value_std__optional_bool_(newValue) {
348
- let __unwrapped = bridge.get_std__optional_bool_(newValue)
349
- return __unwrapped
350
- } else {
351
- return nil
352
- }
353
- }()
354
- }
355
- }
356
-
357
309
  public final var onMessage: bridge.std__optional_std__function_void_const_std__string_____message______ {
358
310
  @inline(__always)
359
311
  get {
@@ -22,8 +22,6 @@ namespace margelo::nitro::chartwebview {
22
22
  prototype.registerHybridSetter("entry", &HybridChartWebviewSpec::setEntry);
23
23
  prototype.registerHybridGetter("paramsJson", &HybridChartWebviewSpec::getParamsJson);
24
24
  prototype.registerHybridSetter("paramsJson", &HybridChartWebviewSpec::setParamsJson);
25
- prototype.registerHybridGetter("assetHost", &HybridChartWebviewSpec::getAssetHost);
26
- prototype.registerHybridSetter("assetHost", &HybridChartWebviewSpec::setAssetHost);
27
25
  prototype.registerHybridGetter("bridgeScript", &HybridChartWebviewSpec::getBridgeScript);
28
26
  prototype.registerHybridSetter("bridgeScript", &HybridChartWebviewSpec::setBridgeScript);
29
27
  prototype.registerHybridGetter("reuseKey", &HybridChartWebviewSpec::getReuseKey);
@@ -32,8 +30,6 @@ namespace margelo::nitro::chartwebview {
32
30
  prototype.registerHybridSetter("pooled", &HybridChartWebviewSpec::setPooled);
33
31
  prototype.registerHybridGetter("active", &HybridChartWebviewSpec::getActive);
34
32
  prototype.registerHybridSetter("active", &HybridChartWebviewSpec::setActive);
35
- prototype.registerHybridGetter("webviewDebuggingEnabled", &HybridChartWebviewSpec::getWebviewDebuggingEnabled);
36
- prototype.registerHybridSetter("webviewDebuggingEnabled", &HybridChartWebviewSpec::setWebviewDebuggingEnabled);
37
33
  prototype.registerHybridGetter("onMessage", &HybridChartWebviewSpec::getOnMessage);
38
34
  prototype.registerHybridSetter("onMessage", &HybridChartWebviewSpec::setOnMessage);
39
35
  prototype.registerHybridGetter("onLoadEnd", &HybridChartWebviewSpec::getOnLoadEnd);