fit-webview-bridge 0.2.3a1__tar.gz → 0.2.3a2__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.3a1
3
+ Version: 0.2.3a2
4
4
  Summary: Qt native WebView bridge with PySide6 bindings
5
5
  Author: FIT Project
6
6
  License: LGPL-3.0-or-later
@@ -11,6 +11,7 @@ from PySide6.QtCore import QUrl
11
11
  from PySide6.QtWidgets import (
12
12
  QApplication,
13
13
  QHBoxLayout,
14
+ QLineEdit,
14
15
  QMainWindow,
15
16
  QPushButton,
16
17
  QVBoxLayout,
@@ -27,7 +28,7 @@ except Exception:
27
28
  from _wkwebview import WKWebViewWidget
28
29
 
29
30
 
30
- HOME_URL = "https://google.it"
31
+ HOME_URL = "https://github.com/fit-project"
31
32
 
32
33
 
33
34
  class Main(QMainWindow):
@@ -38,15 +39,21 @@ class Main(QMainWindow):
38
39
  root = QVBoxLayout(central)
39
40
  self.setCentralWidget(central)
40
41
 
41
- # --- toolbar semplice ---
42
+ # --- toolbar: back/forward/home + address bar + go ---
42
43
  bar = QHBoxLayout()
43
44
  self.btnBack = QPushButton("◀︎ Back")
44
45
  self.btnFwd = QPushButton("Forward ▶︎")
45
46
  self.btnHome = QPushButton("🏠 Home")
47
+
48
+ self.address = QLineEdit() # ← barra indirizzi
49
+ self.address.setPlaceholderText("Digita un URL o una ricerca…")
50
+ self.btnGo = QPushButton("Go")
51
+
46
52
  bar.addWidget(self.btnBack)
47
53
  bar.addWidget(self.btnFwd)
48
54
  bar.addWidget(self.btnHome)
49
- bar.addStretch(1)
55
+ bar.addWidget(self.address, 1) # ← occupa spazio elastico
56
+ bar.addWidget(self.btnGo)
50
57
  root.addLayout(bar)
51
58
 
52
59
  # --- webview ---
@@ -68,6 +75,20 @@ class Main(QMainWindow):
68
75
  self.btnFwd.clicked.connect(self.view.forward)
69
76
  self.btnHome.clicked.connect(lambda: self.view.setUrl(QUrl(HOME_URL)))
70
77
 
78
+ # --- address bar: invio / bottone Go ---
79
+ def navigate_from_address():
80
+ text = (self.address.text() or "").strip()
81
+ if not text:
82
+ return
83
+ url = QUrl.fromUserInput(text) # gestisce http/https, domini, file, ecc.
84
+ self.view.setUrl(url)
85
+
86
+ self.address.returnPressed.connect(navigate_from_address)
87
+ self.btnGo.clicked.connect(navigate_from_address)
88
+
89
+ # mantieni sincronizzata la barra con la URL corrente
90
+ self.view.urlChanged.connect(lambda u: self.address.setText(u.toString()))
91
+
71
92
  # --- eventi download: print semplici ---
72
93
  self.view.downloadStarted.connect(
73
94
  lambda name, path: print(f"[download] started: name='{name}' path='{path}'")
@@ -82,7 +103,6 @@ class Main(QMainWindow):
82
103
  )
83
104
 
84
105
  def on_finished(info):
85
- # Proviamo a leggere i getter se disponibili; fallback a repr
86
106
  try:
87
107
  fname = info.fileName() if hasattr(info, "fileName") else None
88
108
  directory = info.directory() if hasattr(info, "directory") else None
@@ -98,8 +118,9 @@ class Main(QMainWindow):
98
118
 
99
119
  self.view.downloadFinished.connect(on_finished)
100
120
 
101
- # carica home
121
+ # carica home e imposta barra
102
122
  self.view.setUrl(QUrl(HOME_URL))
123
+ self.address.setText(HOME_URL)
103
124
 
104
125
 
105
126
  if __name__ == "__main__":
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fit-webview-bridge"
3
- version = "0.2.3a1"
3
+ version = "0.2.3a2"
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"]
@@ -73,6 +73,8 @@ static NSURL* toNSURL(QUrl u);
73
73
  @end
74
74
 
75
75
 
76
+ static inline NSString* FITURLStr(NSURL *u) { return u ? u.absoluteString : @"(nil)"; }
77
+
76
78
  static NSString* FIT_CurrentLang(void) {
77
79
  NSString *lang = NSLocale.preferredLanguages.firstObject ?: @"en";
78
80
  // normalizza es. "it-IT" -> "it"
@@ -299,6 +301,9 @@ static NSString* fit_uniquePath(NSString* baseDir, NSString* filename) {
299
301
  @property(nonatomic, strong) NSMapTable<WKDownload*, NSNumber*>* expectedTotals; // weak->strong
300
302
  @property(nonatomic, strong) NSMapTable<WKDownload*, NSURL*>* sourceURLs; // weak->strong
301
303
  @property(nonatomic, strong) NSMapTable<WKDownload*, NSString*>* suggestedNames; // weak->strong
304
+ @property(nonatomic, strong) NSURL* pendingPopupParentURL;
305
+ @property(nonatomic, strong) NSURL* pendingPopupChildURL;
306
+ @property(nonatomic, assign) WKWebView* webView;
302
307
  @end
303
308
 
304
309
  @implementation WKNavDelegate
@@ -316,17 +321,15 @@ static NSString* fit_uniquePath(NSString* baseDir, NSString* filename) {
316
321
  }
317
322
 
318
323
  #pragma mark - Navigazione
319
-
320
-
321
324
  // 1a) Navigation: intercetta click con targetFrame == nil (tipico di _blank)
322
325
  - (void)webView:(WKWebView *)webView
323
326
  decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
324
327
  decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
325
328
  {
326
- // Se è un _blank, no-op qui: ci pensa createWebView... (sopra)
327
329
  decisionHandler(WKNavigationActionPolicyAllow);
328
330
  }
329
331
 
332
+
330
333
  // 1b) UI: invocato quando la pagina chiede esplicitamente una nuova webview
331
334
  - (WKWebView *)webView:(WKWebView *)webView
332
335
  createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration
@@ -334,8 +337,18 @@ createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration
334
337
  windowFeatures:(WKWindowFeatures *)windowFeatures
335
338
  {
336
339
  if (navigationAction.targetFrame == nil || !navigationAction.targetFrame.isMainFrame) {
337
- [webView loadRequest:navigationAction.request]; // apri nella stessa webview
340
+ NSURL *parent = webView.URL;
341
+ NSURL *child = navigationAction.request.URL;
342
+
343
+ // salva coppia padre/figlio per il “ritorno” post-download
344
+ self.pendingPopupParentURL = parent;
345
+ self.pendingPopupChildURL = child;
346
+
347
+ if (child) {
348
+ [webView loadRequest:navigationAction.request]; // apri nella stessa webview
349
+ }
338
350
  }
351
+
339
352
  return nil; // restituisci nil per NON creare una nuova finestra
340
353
  }
341
354
 
@@ -390,10 +403,27 @@ createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration
390
403
  decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse
391
404
  decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
392
405
  {
406
+ NSURLResponse *resp = navigationResponse.response;
407
+ NSURL *url = resp.URL;
408
+
409
+ BOOL isAttachment = NO;
410
+ if ([resp isKindOfClass:NSHTTPURLResponse.class]) {
411
+ NSHTTPURLResponse *http = (NSHTTPURLResponse *)resp;
412
+ NSString *cd = http.allHeaderFields[@"Content-Disposition"];
413
+ if (cd && [[cd lowercaseString] containsString:@"attachment"]) {
414
+ isAttachment = YES;
415
+ }
416
+ }
417
+
418
+ if (isAttachment) {
419
+ decisionHandler(WKNavigationResponsePolicyDownload);
420
+ return;
421
+ }
422
+
393
423
  if (navigationResponse.canShowMIMEType) {
394
424
  decisionHandler(WKNavigationResponsePolicyAllow);
395
425
  } else {
396
- decisionHandler(WKNavigationResponsePolicyDownload); // API moderna
426
+ decisionHandler(WKNavigationResponsePolicyDownload);
397
427
  }
398
428
  }
399
429
 
@@ -582,6 +612,42 @@ completionHandler:(void (^)(NSURL * _Nullable destination))completionHandler
582
612
  DownloadInfo* info = new DownloadInfo(qFileName, qDir, qUrl, self.owner);
583
613
  emit self.owner->downloadFinished(info);
584
614
 
615
+
616
+
617
+ WKWebView *webView = self.webView;
618
+ NSURL *srcURL = [self.sourceURLs objectForKey:download];
619
+
620
+ if (webView && self.pendingPopupChildURL && srcURL &&
621
+ [srcURL isEqual:self.pendingPopupChildURL]) {
622
+
623
+ WKBackForwardList *bf = webView.backForwardList;
624
+ NSURL *current = webView.URL;
625
+ NSURL *backURL = bf.backItem.URL;
626
+
627
+ // CASI:
628
+ // A) Sei sul FIGLIO → torna indietro alla PARENT
629
+ if (current && [current isEqual:self.pendingPopupChildURL]) {
630
+ [webView goBack];
631
+ }
632
+ // B) Sei già sulla PARENT → non fare nulla
633
+ else if (current && [current isEqual:self.pendingPopupParentURL]) {
634
+ // niente
635
+ }
636
+ // C) Non sei sul child, ma l’item precedente è la PARENT → goBack
637
+ else if (backURL && [backURL isEqual:self.pendingPopupParentURL]) {
638
+ [webView goBack];
639
+ }
640
+ // D) Fallback: carica esplicitamente la PARENT
641
+ else if (self.pendingPopupParentURL) {
642
+ [webView loadRequest:[NSURLRequest requestWithURL:self.pendingPopupParentURL]];
643
+ } else {
644
+ //Niente
645
+ }
646
+
647
+ // pulizia stato
648
+ self.pendingPopupChildURL = nil;
649
+ self.pendingPopupParentURL = nil;
650
+ }
585
651
  // 5) cleanup mappe
586
652
  if (finalPath) [self.downloadPaths removeObjectForKey:download];
587
653
  [self.progressToDownload removeObjectForKey:download.progress];
@@ -609,6 +675,20 @@ completionHandler:(void (^)(NSURL * _Nullable destination))completionHandler
609
675
  QString::fromUtf8(error.localizedDescription.UTF8String)
610
676
  );
611
677
 
678
+ // 🔙 Se il download proviene dal "figlio", torna alla "pagina padre"
679
+ WKWebView *webView = self.webView;
680
+ NSURL *src = [self.sourceURLs objectForKey:download];
681
+ if (webView && self.pendingPopupChildURL && src && [src isEqual:self.pendingPopupChildURL]) {
682
+ if (webView.canGoBack) {
683
+ [webView goBack];
684
+ } else if (self.pendingPopupParentURL) {
685
+ [webView loadRequest:[NSURLRequest requestWithURL:self.pendingPopupParentURL]];
686
+ }
687
+ // ripulisci lo stato
688
+ self.pendingPopupChildURL = nil;
689
+ self.pendingPopupParentURL = nil;
690
+ }
691
+
612
692
  // cleanup mappe
613
693
  if (finalPath) [self.downloadPaths removeObjectForKey:download];
614
694
  [self.progressToDownload removeObjectForKey:download.progress];
@@ -656,6 +736,11 @@ WKWebViewWidget::WKWebViewWidget(QWidget* parent)
656
736
  cfg.defaultWebpagePreferences.allowsContentJavaScript = YES;
657
737
  }
658
738
 
739
+ // ✅ Consenti window.open() senza creare una nuova finestra UI
740
+ @try {
741
+ cfg.preferences.javaScriptCanOpenWindowsAutomatically = YES;
742
+ } @catch (...) {}
743
+
659
744
  // --- Fullscreen HTML5 (via KVC tollerante) ---
660
745
  @try {
661
746
  [cfg.preferences setValue:@YES forKey:@"fullScreenEnabled"];
@@ -722,8 +807,8 @@ WKWebViewWidget::WKWebViewWidget(QWidget* parent)
722
807
 
723
808
  d->delegate = [WKNavDelegate new];
724
809
  d->delegate.owner = this;
810
+ d->delegate.webView = d->wk;
725
811
  [d->wk setNavigationDelegate:d->delegate];
726
-
727
812
  [d->wk setUIDelegate:d->delegate];
728
813
  }
729
814