fit-webview-bridge 0.2.1a1__tar.gz → 0.2.1a4__tar.gz

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.

Potentially problematic release.


This version of fit-webview-bridge might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: fit-webview-bridge
3
- Version: 0.2.1a1
3
+ Version: 0.2.1a4
4
4
  Summary: Qt native WebView bridge with PySide6 bindings
5
5
  Author: FIT Project
6
6
  License: LGPL-3.0-or-later
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fit-webview-bridge"
3
- version = "0.2.1a1"
3
+ version = "0.2.1a4"
4
4
  description = "Qt native WebView bridge with PySide6 bindings"
5
5
  requires-python = ">=3.11,<3.14"
6
6
  dependencies = ["PySide6==6.9.0", "shiboken6==6.9.0", "shiboken6-generator==6.9.0"]
@@ -45,13 +45,13 @@ static NSURL* toNSURL(QUrl u);
45
45
  }
46
46
  @end
47
47
 
48
- // =======================
49
- // Navigation + Download delegate
50
- // =======================
48
+ // ===== WKNavDelegate =====
51
49
  @interface WKNavDelegate : NSObject <WKNavigationDelegate, WKDownloadDelegate>
52
50
  @property(nonatomic, assign) WKWebViewWidget* owner;
53
- // stato download (nel delegate, non toccare i privati del widget)
54
- @property(nonatomic, strong) NSMapTable<WKDownload*, NSString*>* downloadPaths;
51
+ // mappe per download
52
+ @property(nonatomic, strong) NSMapTable<WKDownload*, NSString*>* downloadPaths; // weak key -> strong value
53
+ @property(nonatomic, strong) NSMapTable<NSProgress*, WKDownload*>* progressToDownload; // weak->weak
54
+ @property(nonatomic, strong) NSHashTable<NSProgress*>* completedProgresses; // weak set
55
55
  @end
56
56
 
57
57
  @implementation WKNavDelegate
@@ -59,6 +59,8 @@ static NSURL* toNSURL(QUrl u);
59
59
  - (instancetype)init {
60
60
  if ((self = [super init])) {
61
61
  _downloadPaths = [NSMapTable weakToStrongObjectsMapTable];
62
+ _progressToDownload = [NSMapTable weakToWeakObjectsMapTable];
63
+ _completedProgresses = [NSHashTable weakObjectsHashTable];
62
64
  }
63
65
  return self;
64
66
  }
@@ -118,8 +120,7 @@ decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
118
120
  if (navigationResponse.canShowMIMEType) {
119
121
  decisionHandler(WKNavigationResponsePolicyAllow);
120
122
  } else {
121
- // API moderna: "Download" (non BecomeDownload)
122
- decisionHandler(WKNavigationResponsePolicyDownload);
123
+ decisionHandler(WKNavigationResponsePolicyDownload); // API moderna
123
124
  }
124
125
  }
125
126
 
@@ -130,14 +131,20 @@ navigationAction:(WKNavigationAction *)navigationAction
130
131
  didBecomeDownload:(WKDownload *)download
131
132
  {
132
133
  download.delegate = self;
133
- if (self.owner) {
134
- emit self.owner->downloadStarted(QString(), QString());
135
- }
136
- // Progress via NSProgress (best effort): alcuni siti non lo popolano
137
- [download.progress addObserver:self
138
- forKeyPath:@"fractionCompleted"
139
- options:NSKeyValueObservingOptionNew
134
+ if (self.owner) emit self.owner->downloadStarted(QString(), QString());
135
+
136
+ // KVO su NSProgress (3 keyPath, con INITIAL)
137
+ [download.progress addObserver:self forKeyPath:@"fractionCompleted"
138
+ options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial)
139
+ context:NULL];
140
+ [download.progress addObserver:self forKeyPath:@"completedUnitCount"
141
+ options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial)
142
+ context:NULL];
143
+ [download.progress addObserver:self forKeyPath:@"totalUnitCount"
144
+ options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial)
140
145
  context:NULL];
146
+
147
+ [self.progressToDownload setObject:download forKey:download.progress];
141
148
  }
142
149
 
143
150
  - (void)webView:(WKWebView *)webView
@@ -148,15 +155,22 @@ didBecomeDownload:(WKDownload *)download
148
155
 
149
156
  NSString* suggested = navigationResponse.response.suggestedFilename ?: @"download";
150
157
  if (self.owner) {
151
- QString destDir = self.owner->downloadDirectory();
152
- QString destPath = destDir + "/" + QString::fromUtf8(suggested.UTF8String);
153
- emit self.owner->downloadStarted(QString::fromUtf8(suggested.UTF8String),
154
- destPath);
158
+ QString dir = self.owner->downloadDirectory();
159
+ QString path = dir + "/" + QString::fromUtf8(suggested.UTF8String);
160
+ emit self.owner->downloadStarted(QString::fromUtf8(suggested.UTF8String), path);
155
161
  }
156
- [download.progress addObserver:self
157
- forKeyPath:@"fractionCompleted"
158
- options:NSKeyValueObservingOptionNew
162
+
163
+ [download.progress addObserver:self forKeyPath:@"fractionCompleted"
164
+ options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial)
165
+ context:NULL];
166
+ [download.progress addObserver:self forKeyPath:@"completedUnitCount"
167
+ options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial)
159
168
  context:NULL];
169
+ [download.progress addObserver:self forKeyPath:@"totalUnitCount"
170
+ options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial)
171
+ context:NULL];
172
+
173
+ [self.progressToDownload setObject:download forKey:download.progress];
160
174
  }
161
175
 
162
176
  #pragma mark - Scegli destinazione
@@ -188,9 +202,7 @@ completionHandler:(void (^)(NSURL * _Nullable destination))completionHandler
188
202
 
189
203
  QString qdir = self.owner->downloadDirectory();
190
204
  NSString* dir = [NSString stringWithUTF8String:qdir.toUtf8().constData()];
191
- if (!dir.length) {
192
- dir = [NSHomeDirectory() stringByAppendingPathComponent:@"Downloads"];
193
- }
205
+ if (!dir.length) dir = [NSHomeDirectory() stringByAppendingPathComponent:@"Downloads"];
194
206
 
195
207
  [[NSFileManager defaultManager] createDirectoryAtPath:dir
196
208
  withIntermediateDirectories:YES
@@ -212,41 +224,58 @@ completionHandler:(void (^)(NSURL * _Nullable destination))completionHandler
212
224
  - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)obj
213
225
  change:(NSDictionary *)change context:(void *)ctx
214
226
  {
215
- if (![keyPath isEqualToString:@"fractionCompleted"]) {
227
+ if (![obj isKindOfClass:[NSProgress class]] || !self.owner) {
216
228
  [super observeValueForKeyPath:keyPath ofObject:obj change:change context:ctx];
217
229
  return;
218
230
  }
219
- if (!self.owner) return;
220
-
221
231
  NSProgress* prog = (NSProgress*)obj;
222
- int64_t total = prog.totalUnitCount; // può essere -1 (sconosciuto)
232
+
233
+ // ignora aggiornamenti dopo il completamento
234
+ if ([self.completedProgresses containsObject:prog]) return;
235
+
236
+ int64_t total = prog.totalUnitCount; // -1 se sconosciuto
223
237
  int64_t done = prog.completedUnitCount;
224
- emit self.owner->downloadProgress(done, total >= 0 ? total : -1);
238
+
239
+ dispatch_async(dispatch_get_main_queue(), ^{
240
+ emit self.owner->downloadProgress(done, (total >= 0 ? total : -1));
241
+ });
225
242
  }
226
243
 
227
244
  - (void)downloadDidFinish:(WKDownload *)download {
228
245
  if (!self.owner) return;
229
246
 
230
- @try { [download.progress removeObserver:self forKeyPath:@"fractionCompleted"]; } @catch (...) {}
247
+ @try {
248
+ [download.progress removeObserver:self forKeyPath:@"fractionCompleted"];
249
+ [download.progress removeObserver:self forKeyPath:@"completedUnitCount"];
250
+ [download.progress removeObserver:self forKeyPath:@"totalUnitCount"];
251
+ } @catch (...) {}
252
+
253
+ [self.completedProgresses addObject:download.progress];
231
254
 
232
255
  NSString* finalPath = [self.downloadPaths objectForKey:download];
233
- if (finalPath) {
234
- emit self.owner->downloadFinished(QString::fromUtf8(finalPath.UTF8String));
235
- [self.downloadPaths removeObjectForKey:download];
236
- } else {
237
- emit self.owner->downloadFinished(QString());
238
- }
256
+ emit self.owner->downloadFinished(finalPath ? QString::fromUtf8(finalPath.UTF8String) : QString());
257
+ if (finalPath) [self.downloadPaths removeObjectForKey:download];
258
+ [self.progressToDownload removeObjectForKey:download.progress];
239
259
  }
240
260
 
241
261
  - (void)download:(WKDownload *)download didFailWithError:(NSError *)error resumeData:(NSData *)resumeData {
242
262
  if (!self.owner) return;
243
263
 
244
- @try { [download.progress removeObserver:self forKeyPath:@"fractionCompleted"]; } @catch (...) {}
264
+ @try {
265
+ [download.progress removeObserver:self forKeyPath:@"fractionCompleted"];
266
+ [download.progress removeObserver:self forKeyPath:@"completedUnitCount"];
267
+ [download.progress removeObserver:self forKeyPath:@"totalUnitCount"];
268
+ } @catch (...) {}
245
269
 
246
- NSString* finalPath = [self.downloadPaths objectForKey:download];
247
- QString qpath = finalPath ? QString::fromUtf8(finalPath.UTF8String) : QString();
248
- emit self.owner->downloadFailed(qpath, QString::fromUtf8(error.localizedDescription.UTF8String));
270
+ [self.completedProgresses addObject:download.progress];
271
+
272
+ NSString* finalPath = [self.downloadPaths objectForKey:download];
273
+ emit self.owner->downloadFailed(
274
+ finalPath ? QString::fromUtf8(finalPath.UTF8String) : QString(),
275
+ QString::fromUtf8(error.localizedDescription.UTF8String)
276
+ );
249
277
  if (finalPath) [self.downloadPaths removeObjectForKey:download];
278
+ [self.progressToDownload removeObjectForKey:download.progress];
250
279
  }
251
280
 
252
281
  @end