VertexEngine-WebEngine 1.0__tar.gz → 1.1__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.
Files changed (19) hide show
  1. {vertexengine_webengine-1.0 → vertexengine_webengine-1.1}/PKG-INFO +11 -5
  2. {vertexengine_webengine-1.0 → vertexengine_webengine-1.1}/README.md +9 -4
  3. {vertexengine_webengine-1.0 → vertexengine_webengine-1.1}/pyproject.toml +3 -2
  4. vertexengine_webengine-1.1/src/VertexEngine/BrowserTools/Tabs.py +70 -0
  5. vertexengine_webengine-1.1/src/VertexEngine/WebEngine/WebEngine.py +85 -0
  6. vertexengine_webengine-1.1/src/VertexEngine/WebView/WebPage.py +22 -0
  7. vertexengine_webengine-1.1/src/VertexEngine/WebView/bridge.py +19 -0
  8. {vertexengine_webengine-1.0 → vertexengine_webengine-1.1}/src/VertexEngine/WebView/profile.py +11 -0
  9. vertexengine_webengine-1.1/src/VertexEngine/main.py +17 -0
  10. vertexengine_webengine-1.1/src/VertexEngine/test.py +61 -0
  11. {vertexengine_webengine-1.0 → vertexengine_webengine-1.1}/src/VertexEngine_WebEngine.egg-info/PKG-INFO +11 -5
  12. {vertexengine_webengine-1.0 → vertexengine_webengine-1.1}/src/VertexEngine_WebEngine.egg-info/SOURCES.txt +3 -0
  13. {vertexengine_webengine-1.0 → vertexengine_webengine-1.1}/src/VertexEngine_WebEngine.egg-info/requires.txt +1 -0
  14. vertexengine_webengine-1.0/src/VertexEngine/WebEngine/WebEngine.py +0 -32
  15. vertexengine_webengine-1.0/src/VertexEngine/WebView/WebPage.py +0 -37
  16. vertexengine_webengine-1.0/src/VertexEngine/WebView/bridge.py +0 -7
  17. {vertexengine_webengine-1.0 → vertexengine_webengine-1.1}/setup.cfg +0 -0
  18. {vertexengine_webengine-1.0 → vertexengine_webengine-1.1}/src/VertexEngine_WebEngine.egg-info/dependency_links.txt +0 -0
  19. {vertexengine_webengine-1.0 → vertexengine_webengine-1.1}/src/VertexEngine_WebEngine.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: VertexEngine-WebEngine
3
- Version: 1.0
3
+ Version: 1.1
4
4
  Author-email: Tyrel Miguel <annbasilan0828@gmail.com>
5
5
  License: MIT
6
6
  Project-URL: Documentation, https://vertexenginedocs.netlify.app/
@@ -8,10 +8,20 @@ Requires-Python: >=3.10
8
8
  Description-Content-Type: text/markdown
9
9
  Requires-Dist: pygame>=2.0
10
10
  Requires-Dist: PyQt6>=6.7
11
+ Requires-Dist: VertexEngine>=1.0.1
11
12
 
12
13
  # VertexEngine/Vertex-WebEngine
13
14
  VertexEngine-WebEngine is a WebEngine built for the VertexEngine SDK. It's a seperate package.
14
15
 
16
+ ## Help
17
+ The documentation is in the following link:
18
+ [Project Documentation](https://vertexenginedocs.netlify.app/) for help.
19
+
20
+ ## Change Logs (1.1), NEW!
21
+ ### Version 1.1
22
+ - Added 1 New Library!
23
+ ~ BrowserTools.Tabs
24
+
15
25
  ## How to install Pyinstaller
16
26
  Step 1. Type in:
17
27
  pip install pyinstaller
@@ -35,10 +45,6 @@ pip install VertexEngine-WebEngine
35
45
 
36
46
  Step 2: Wait a few min, don't worry if it takes 1 hr or more, it will finish
37
47
 
38
- ## Help
39
- The documentation is in the following link:
40
- [Project Documentation](https://vertexenginedocs.netlify.app/) for help.
41
-
42
48
  ## Dependencies
43
49
  Vertex obviously has heavy dependencies since it's a game engine, the following requirements are:
44
50
 
@@ -1,6 +1,15 @@
1
1
  # VertexEngine/Vertex-WebEngine
2
2
  VertexEngine-WebEngine is a WebEngine built for the VertexEngine SDK. It's a seperate package.
3
3
 
4
+ ## Help
5
+ The documentation is in the following link:
6
+ [Project Documentation](https://vertexenginedocs.netlify.app/) for help.
7
+
8
+ ## Change Logs (1.1), NEW!
9
+ ### Version 1.1
10
+ - Added 1 New Library!
11
+ ~ BrowserTools.Tabs
12
+
4
13
  ## How to install Pyinstaller
5
14
  Step 1. Type in:
6
15
  pip install pyinstaller
@@ -24,10 +33,6 @@ pip install VertexEngine-WebEngine
24
33
 
25
34
  Step 2: Wait a few min, don't worry if it takes 1 hr or more, it will finish
26
35
 
27
- ## Help
28
- The documentation is in the following link:
29
- [Project Documentation](https://vertexenginedocs.netlify.app/) for help.
30
-
31
36
  ## Dependencies
32
37
  Vertex obviously has heavy dependencies since it's a game engine, the following requirements are:
33
38
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "VertexEngine-WebEngine"
7
- version = "1.0"
7
+ version = "1.1"
8
8
  authors = [
9
9
  { name="Tyrel Miguel", email="annbasilan0828@gmail.com" }
10
10
  ]
@@ -14,7 +14,8 @@ requires-python = ">=3.10"
14
14
 
15
15
  dependencies = [
16
16
  "pygame>=2.0",
17
- "PyQt6>=6.7"
17
+ "PyQt6>=6.7",
18
+ "VertexEngine>=1.0.1"
18
19
  ]
19
20
 
20
21
  [tool.setuptools.packages.find]
@@ -0,0 +1,70 @@
1
+ from PyQt6.QtWidgets import QTabWidget, QWidget
2
+ from PyQt6.QtCore import QUrl
3
+ from PyQt6.QtGui import QKeySequence, QShortcut
4
+
5
+ from WebEngine.WebEngine import WebEngine
6
+
7
+
8
+ class BrowserTabs(QTabWidget):
9
+ def __init__(self, parent=None):
10
+ super().__init__(parent)
11
+
12
+ self.setTabsClosable(True)
13
+ self.setMovable(True)
14
+
15
+ self.tabCloseRequested.connect(self.close_tab)
16
+ self.currentChanged.connect(self.on_tab_changed)
17
+
18
+ # Keyboard shortcuts
19
+ QShortcut(QKeySequence("Ctrl+T"), self).activated.connect(self.new_tab)
20
+ QShortcut(QKeySequence("Ctrl+W"), self).activated.connect(self.close_current_tab)
21
+
22
+ self.new_tab("vertex://home")
23
+
24
+ # ➕ Create tab
25
+ def new_tab(self, url="vertex://home"):
26
+ engine = WebEngine(self)
27
+
28
+ index = self.addTab(engine, "New Tab")
29
+ self.setCurrentIndex(index)
30
+
31
+ if url.startswith("vertex://"):
32
+ engine.load_home()
33
+ else:
34
+ engine.load(QUrl(url))
35
+
36
+ # Update tab title
37
+ engine.page().titleChanged.connect(
38
+ lambda title, e=engine: self.update_tab_title(e, title)
39
+ )
40
+
41
+ # ❌ Close tab by index
42
+ def close_tab(self, index):
43
+ if self.count() <= 1:
44
+ return
45
+
46
+ widget = self.widget(index)
47
+ self.removeTab(index)
48
+ widget.deleteLater()
49
+
50
+ # ❌ Close current tab
51
+ def close_current_tab(self):
52
+ self.close_tab(self.currentIndex())
53
+
54
+ def safe_remove(self, index):
55
+ if 0 <= index < self.count():
56
+ self.removeTab(index)
57
+
58
+ def update_tab_title(self, engine, title):
59
+ index = self.indexOf(engine)
60
+ if index != -1:
61
+ self.setTabText(index, title[:24])
62
+
63
+ # 🔀 Tab switch handler
64
+ def on_tab_changed(self, index):
65
+ engine = self.widget(index)
66
+ if not engine:
67
+ return
68
+
69
+ url = engine.url().toString()
70
+ print("🔀 Switched to tab:", url)
@@ -0,0 +1,85 @@
1
+ from PyQt6.QtWebEngineWidgets import QWebEngineView
2
+ from PyQt6.QtGui import QKeySequence, QShortcut
3
+ from PyQt6.QtWebChannel import QWebChannel
4
+
5
+ from WebView.profile import WebProfile
6
+ from WebView.WebPage import WebPage
7
+ from WebView.bridge import JSBridge
8
+
9
+ class WebEngine(QWebEngineView):
10
+ def __init__(self, parent=None):
11
+ super().__init__(parent)
12
+
13
+ self.profile = WebProfile(parent=self)
14
+ self.webpage = WebPage(self.profile, self)
15
+ self.setPage(self.webpage)
16
+
17
+ # JS Bridge
18
+ self.channel = QWebChannel()
19
+ self.bridge = JSBridge(self.webpage)
20
+ self.channel.registerObject("bridge", self.bridge)
21
+ self.webpage.setWebChannel(self.channel)
22
+
23
+ # DevTools
24
+ self._devtools = None
25
+ QShortcut(QKeySequence("Ctrl+Shift+I"), self).activated.connect(self.toggle_devtools)
26
+
27
+ self.load_home()
28
+
29
+ def toggle_devtools(self):
30
+ if self._devtools is None:
31
+ self._devtools = QWebEngineView()
32
+ self.webpage.setDevToolsPage(self._devtools.page())
33
+ self._devtools.resize(800, 600)
34
+ self._devtools.show()
35
+ else:
36
+ self._devtools.close()
37
+ self._devtools = None
38
+
39
+ def load_home(self):
40
+ html = """
41
+ <!DOCTYPE html>
42
+ <html>
43
+ <head>
44
+ <meta charset="utf-8">
45
+ <script src="qrc:///qtwebchannel/qwebchannel.js"></script>
46
+ <style>
47
+ body {
48
+ background:#0f0f14;
49
+ color:white;
50
+ font-family:monospace;
51
+ text-align:center;
52
+ margin-top:20vh;
53
+ }
54
+ button {
55
+ padding:10px 20px;
56
+ font-size:16px;
57
+ }
58
+ </style>
59
+ </head>
60
+ <body>
61
+
62
+ <h1>🔥 Vertex WebEngine</h1>
63
+ <button onclick="openSite()">Open example.com</button>
64
+
65
+ <script>
66
+ new QWebChannel(qt.webChannelTransport, channel => {
67
+ window.bridge = channel.objects.bridge;
68
+ bridge.log("Home loaded");
69
+ });
70
+
71
+ function openSite() {
72
+ bridge.emit("open_url", JSON.stringify({
73
+ url: "https://example.com"
74
+ }));
75
+ }
76
+ </script>
77
+
78
+ </body>
79
+ </html>
80
+ """
81
+ self.webpage.setHtml(html)
82
+
83
+ def load_url(self, url):
84
+ from PyQt6.QtCore import QUrl
85
+ self.load(QUrl(url))
@@ -0,0 +1,22 @@
1
+ from PyQt6.QtWebEngineCore import QWebEnginePage
2
+
3
+ class WebPage(QWebEnginePage):
4
+
5
+ BLOCKED = ["malware", "phishing"]
6
+
7
+ def __init__(self, profile, parent=None):
8
+ super().__init__(profile, parent)
9
+
10
+ def acceptNavigationRequest(self, url, nav_type, is_main_frame):
11
+ url_str = url.toString()
12
+ print("➡️ Navigating to:", url_str)
13
+
14
+ for bad in self.BLOCKED:
15
+ if bad in url_str:
16
+ print("🚫 Blocked URL")
17
+ return False
18
+
19
+ return True
20
+
21
+ def javaScriptConsoleMessage(self, level, message, line, source):
22
+ print(f"[JS:{level.name}] {message} ({source}:{line})")
@@ -0,0 +1,19 @@
1
+ from PyQt6.QtCore import QObject, pyqtSlot
2
+ from PyQt6.QtCore import QUrl
3
+ import json
4
+
5
+ class JSBridge(QObject):
6
+ def __init__(self, page):
7
+ super().__init__()
8
+ self.page = page
9
+
10
+ @pyqtSlot(str)
11
+ def log(self, msg):
12
+ print("[JS → Python]", msg)
13
+
14
+ @pyqtSlot(str, str)
15
+ def emit(self, event, payload):
16
+ data = json.loads(payload)
17
+
18
+ if event == "open_url":
19
+ self.page.load(QUrl(data["url"]))
@@ -1,9 +1,12 @@
1
1
  from PyQt6.QtWebEngineCore import QWebEngineProfile
2
+ import os
2
3
 
3
4
  class WebProfile(QWebEngineProfile):
4
5
  def __init__(self, name="CustomProfile", parent=None):
5
6
  super().__init__(name, parent)
6
7
 
8
+ os.makedirs("downloads", exist_ok=True)
9
+
7
10
  self.setHttpUserAgent(
8
11
  "VertexWebEngine/1.0 (PyQt6)"
9
12
  )
@@ -14,3 +17,11 @@ class WebProfile(QWebEngineProfile):
14
17
 
15
18
  self.setCachePath("webcache")
16
19
  self.setPersistentStoragePath("webstorage")
20
+
21
+ self.downloadRequested.connect(self.on_download)
22
+
23
+ def on_download(self, download):
24
+ path = f"downloads/{download.downloadFileName()}"
25
+ download.setPath(path)
26
+ download.accept()
27
+ print("⬇️ Downloading:", path)
@@ -0,0 +1,17 @@
1
+ import sys
2
+ from PyQt6.QtWidgets import QApplication, QMainWindow
3
+
4
+ from BrowserTools.Tabs import BrowserTabs
5
+
6
+ app = QApplication(sys.argv)
7
+
8
+ window = QMainWindow()
9
+ window.setWindowTitle("Vertex Browser")
10
+
11
+ tabs = BrowserTabs()
12
+ window.setCentralWidget(tabs)
13
+
14
+ window.resize(1280, 800)
15
+ window.show()
16
+
17
+ sys.exit(app.exec())
@@ -0,0 +1,61 @@
1
+ from PyQt6.QtWidgets import (
2
+ QMainWindow, QWidget, QVBoxLayout,
3
+ QHBoxLayout, QPushButton, QLineEdit
4
+ )
5
+ from VertexEngine.WebEngine.WebEngine import WebEngine
6
+
7
+
8
+ class MainWindow(QMainWindow):
9
+ def __init__(self):
10
+ super().__init__()
11
+
12
+ self.setWindowTitle("Vertex Browser")
13
+ self.resize(1100, 700)
14
+
15
+ # Central widget
16
+ central = QWidget()
17
+ self.setCentralWidget(central)
18
+
19
+ layout = QVBoxLayout(central)
20
+
21
+ # 🔧 Toolbar
22
+ toolbar = QHBoxLayout()
23
+
24
+ self.back_btn = QPushButton("←")
25
+ self.reload_btn = QPushButton("⟳")
26
+ self.home_btn = QPushButton("🏠")
27
+ self.url_bar = QLineEdit()
28
+
29
+ toolbar.addWidget(self.back_btn)
30
+ toolbar.addWidget(self.reload_btn)
31
+ toolbar.addWidget(self.home_btn)
32
+ toolbar.addWidget(self.url_bar)
33
+
34
+ layout.addLayout(toolbar)
35
+
36
+ # 🌐 WebEngine
37
+ self.web = WebEngine()
38
+ layout.addWidget(self.web)
39
+
40
+ # 🔗 Signals
41
+ self.back_btn.clicked.connect(self.web.back)
42
+ self.reload_btn.clicked.connect(self.web.reload)
43
+ self.home_btn.clicked.connect(self.go_home)
44
+ self.url_bar.returnPressed.connect(self.load_url)
45
+
46
+ self.web.urlChanged.connect(self.update_url)
47
+
48
+ # 🏠 Home
49
+ self.go_home()
50
+
51
+ def load_url(self):
52
+ url = self.url_bar.text()
53
+ if not url.startswith("http"):
54
+ url = "https://" + url
55
+ self.web.load_url(url)
56
+
57
+ def update_url(self, qurl):
58
+ self.url_bar.setText(qurl.toString())
59
+
60
+ def go_home(self):
61
+ self.web.load_url("https://example.com")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: VertexEngine-WebEngine
3
- Version: 1.0
3
+ Version: 1.1
4
4
  Author-email: Tyrel Miguel <annbasilan0828@gmail.com>
5
5
  License: MIT
6
6
  Project-URL: Documentation, https://vertexenginedocs.netlify.app/
@@ -8,10 +8,20 @@ Requires-Python: >=3.10
8
8
  Description-Content-Type: text/markdown
9
9
  Requires-Dist: pygame>=2.0
10
10
  Requires-Dist: PyQt6>=6.7
11
+ Requires-Dist: VertexEngine>=1.0.1
11
12
 
12
13
  # VertexEngine/Vertex-WebEngine
13
14
  VertexEngine-WebEngine is a WebEngine built for the VertexEngine SDK. It's a seperate package.
14
15
 
16
+ ## Help
17
+ The documentation is in the following link:
18
+ [Project Documentation](https://vertexenginedocs.netlify.app/) for help.
19
+
20
+ ## Change Logs (1.1), NEW!
21
+ ### Version 1.1
22
+ - Added 1 New Library!
23
+ ~ BrowserTools.Tabs
24
+
15
25
  ## How to install Pyinstaller
16
26
  Step 1. Type in:
17
27
  pip install pyinstaller
@@ -35,10 +45,6 @@ pip install VertexEngine-WebEngine
35
45
 
36
46
  Step 2: Wait a few min, don't worry if it takes 1 hr or more, it will finish
37
47
 
38
- ## Help
39
- The documentation is in the following link:
40
- [Project Documentation](https://vertexenginedocs.netlify.app/) for help.
41
-
42
48
  ## Dependencies
43
49
  Vertex obviously has heavy dependencies since it's a game engine, the following requirements are:
44
50
 
@@ -1,5 +1,8 @@
1
1
  README.md
2
2
  pyproject.toml
3
+ src/VertexEngine/main.py
4
+ src/VertexEngine/test.py
5
+ src/VertexEngine/BrowserTools/Tabs.py
3
6
  src/VertexEngine/WebEngine/WebEngine.py
4
7
  src/VertexEngine/WebView/WebPage.py
5
8
  src/VertexEngine/WebView/bridge.py
@@ -1,2 +1,3 @@
1
1
  pygame>=2.0
2
2
  PyQt6>=6.7
3
+ VertexEngine>=1.0.1
@@ -1,32 +0,0 @@
1
- from PyQt6.QtWebEngineWidgets import QWebEngineView
2
- from PyQt6.QtWebChannel import QWebChannel
3
- from PyQt6.QtCore import QUrl
4
-
5
- from VertexEngine.WebView.profile import WebProfile
6
- from VertexEngine.WebView.WebPage import WebPage
7
- from VertexEngine.WebView.bridge import JSBridge
8
-
9
-
10
- class WebEngine(QWebEngineView):
11
- def __init__(self, parent=None):
12
- super().__init__(parent)
13
-
14
- # 1️⃣ Profile
15
- self.profile = WebProfile()
16
-
17
- # 2️⃣ Page
18
- self.page = WebPage(self.profile, self)
19
- self.setPage(self.page)
20
-
21
- # 3️⃣ WebChannel
22
- self.channel = QWebChannel(self.page)
23
-
24
- # 4️⃣ JS Bridge
25
- self.bridge = JSBridge()
26
- self.channel.registerObject("bridge", self.bridge)
27
-
28
- # 5️⃣ Attach channel to page
29
- self.page.setWebChannel(self.channel)
30
-
31
- def load_url(self, url: str):
32
- self.load(QUrl(url))
@@ -1,37 +0,0 @@
1
- from PyQt6.QtWebEngineCore import QWebEnginePage
2
-
3
-
4
- class WebPage(QWebEnginePage):
5
- def load_default_html(self):
6
- html = """
7
- <!DOCTYPE html>
8
- <html>
9
- <head>
10
- <meta charset="utf-8">
11
- <script src="qrc:///qtwebchannel/qwebchannel.js"></script>
12
- </head>
13
- <body>
14
- <h1>Vertex WebEngine</h1>
15
-
16
- <script>
17
- new QWebChannel(qt.webChannelTransport, function (channel) {
18
- window.bridge = channel.objects.bridge;
19
- bridge.log("HELLO FROM INLINE HTML 🚀");
20
- });
21
- </script>
22
- </body>
23
- </html>
24
- """
25
-
26
- self.setHtml(html) # ✅ THIS is the correct call
27
-
28
- def javaScriptConsoleMessage(self, level, message, line, source):
29
- print(f"[JS:{level.name}] {message} ({source}:{line})")
30
-
31
- def acceptNavigationRequest(self, url, nav_type, is_main_frame):
32
- print("Navigating to:", url.toString())
33
-
34
- if "malware" in url.toString():
35
- return False
36
-
37
- return True
@@ -1,7 +0,0 @@
1
- from PyQt6.QtWebChannel import QWebChannel
2
- from PyQt6.QtCore import QObject, pyqtSlot
3
-
4
- class JSBridge(QObject):
5
- @pyqtSlot(str)
6
- def log(self, msg):
7
- print("[JS → Python]", msg)