tkinterweb 4.17.1__py3-none-any.whl → 4.17.2__py3-none-any.whl
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.
- tkinterweb/bindings.py +2 -2
- tkinterweb/handlers.py +35 -19
- tkinterweb/htmlwidgets.py +8 -4
- tkinterweb/utilities.py +1 -1
- {tkinterweb-4.17.1.dist-info → tkinterweb-4.17.2.dist-info}/METADATA +1 -1
- {tkinterweb-4.17.1.dist-info → tkinterweb-4.17.2.dist-info}/RECORD +9 -9
- {tkinterweb-4.17.1.dist-info → tkinterweb-4.17.2.dist-info}/LICENSE.md +0 -0
- {tkinterweb-4.17.1.dist-info → tkinterweb-4.17.2.dist-info}/WHEEL +0 -0
- {tkinterweb-4.17.1.dist-info → tkinterweb-4.17.2.dist-info}/top_level.txt +0 -0
tkinterweb/bindings.py
CHANGED
|
@@ -735,7 +735,7 @@ It is likely that not all dependencies are installed. Make sure Cairo is install
|
|
|
735
735
|
thread.start()
|
|
736
736
|
|
|
737
737
|
def _begin_download(self):
|
|
738
|
-
# NOTE: this
|
|
738
|
+
# NOTE: this runs in a thread
|
|
739
739
|
|
|
740
740
|
thread = utilities.get_current_thread()
|
|
741
741
|
self.active_threads.append(thread)
|
|
@@ -743,7 +743,7 @@ It is likely that not all dependencies are installed. Make sure Cairo is install
|
|
|
743
743
|
return thread
|
|
744
744
|
|
|
745
745
|
def _finish_download(self, thread):
|
|
746
|
-
# NOTE: this
|
|
746
|
+
# NOTE: this runs in a thread
|
|
747
747
|
|
|
748
748
|
self.active_threads.remove(thread)
|
|
749
749
|
if len(self.active_threads) == 0:
|
tkinterweb/handlers.py
CHANGED
|
@@ -479,7 +479,7 @@ class ScriptManager(utilities.BaseManager):
|
|
|
479
479
|
|
|
480
480
|
def fetch_scripts(self, attributes, url=None, data=None):
|
|
481
481
|
"Fetch and run scripts"
|
|
482
|
-
# NOTE: this
|
|
482
|
+
# NOTE: this runs in a thread
|
|
483
483
|
|
|
484
484
|
thread = self.html._begin_download()
|
|
485
485
|
|
|
@@ -520,7 +520,7 @@ class StyleManager(utilities.BaseManager):
|
|
|
520
520
|
|
|
521
521
|
def _on_style(self, attributes, tag_contents):
|
|
522
522
|
"Handle <style> elements."
|
|
523
|
-
self.
|
|
523
|
+
self._finish_fetching_styles(data=tag_contents)
|
|
524
524
|
|
|
525
525
|
def _on_link(self, node):
|
|
526
526
|
"Handle <link> elements."
|
|
@@ -536,7 +536,10 @@ class StyleManager(utilities.BaseManager):
|
|
|
536
536
|
("stylesheet" in rel)
|
|
537
537
|
and ("all" in media or "screen" in media)
|
|
538
538
|
):
|
|
539
|
-
|
|
539
|
+
if url.startswith("file://"):
|
|
540
|
+
self.fetch_styles(node, url)
|
|
541
|
+
else:
|
|
542
|
+
self.html._thread_check(self.fetch_styles, node, url)
|
|
540
543
|
# Onload is fired if and when the stylesheet is parsed
|
|
541
544
|
elif "icon" in rel:
|
|
542
545
|
self.html.icon = url
|
|
@@ -564,25 +567,25 @@ class StyleManager(utilities.BaseManager):
|
|
|
564
567
|
newurl = f"url('{newurl}')"
|
|
565
568
|
return newurl
|
|
566
569
|
|
|
567
|
-
def fetch_styles(self, node=None, url=None
|
|
570
|
+
def fetch_styles(self, node=None, url=None):
|
|
568
571
|
"Fetch stylesheets and parse the CSS code they contain"
|
|
569
|
-
# NOTE: this
|
|
572
|
+
# NOTE: this runs in a thread
|
|
570
573
|
|
|
571
574
|
thread = self.html._begin_download()
|
|
572
575
|
if url and thread.isrunning():
|
|
573
576
|
self.html.post_message(f"Fetching stylesheet from {utilities.shorten(url)}", True)
|
|
574
577
|
try:
|
|
575
578
|
data = self.html.download_url(url)[1]
|
|
579
|
+
if data and thread.isrunning():
|
|
580
|
+
self.html.post_to_queue(lambda node=node, url=url, data=data: self._finish_fetching_styles(node, url, data))
|
|
581
|
+
|
|
576
582
|
except Exception as error:
|
|
577
583
|
self.html.post_to_queue(lambda message=f"ERROR: could not load stylesheet {url}: {error}",
|
|
578
584
|
url=url: self.html._finish_resource_load(message, url, "stylesheet", False))
|
|
579
|
-
|
|
580
|
-
if data and thread.isrunning():
|
|
581
|
-
self.html.post_to_queue(lambda node=node, url=url, data=data: self._finish_fetching_styles(node, url, data))
|
|
582
585
|
|
|
583
586
|
self.html._finish_download(thread)
|
|
584
587
|
|
|
585
|
-
def _finish_fetching_styles(self, node, url, data):
|
|
588
|
+
def _finish_fetching_styles(self, node=None, url=None, data=None):
|
|
586
589
|
# NOTE: this must run in the main thread
|
|
587
590
|
|
|
588
591
|
self.html._style_count += 1
|
|
@@ -689,13 +692,16 @@ class ImageManager(utilities.BaseManager):
|
|
|
689
692
|
else:
|
|
690
693
|
url = url.split("), url(", 1)[0].replace("'", "").replace('"', "")
|
|
691
694
|
url = self.html.resolve_url(url)
|
|
692
|
-
|
|
695
|
+
if url.startswith("file://"):
|
|
696
|
+
self.fetch_images(url, name)
|
|
697
|
+
else:
|
|
698
|
+
self.html._thread_check(self.fetch_images, url, name)
|
|
693
699
|
|
|
694
700
|
return list((name, self.html.register(self._on_image_delete)))
|
|
695
701
|
|
|
696
702
|
def fetch_images(self, url, name):
|
|
697
703
|
"Fetch images and display them in the document."
|
|
698
|
-
# NOTE: this
|
|
704
|
+
# NOTE: this runs in a thread
|
|
699
705
|
|
|
700
706
|
thread = self.html._begin_download()
|
|
701
707
|
if thread.isrunning():
|
|
@@ -717,7 +723,7 @@ class ImageManager(utilities.BaseManager):
|
|
|
717
723
|
|
|
718
724
|
def check_images(self, data, name, url, filetype):
|
|
719
725
|
"Invert images if needed and convert SVG images to PNGs."
|
|
720
|
-
# NOTE: this
|
|
726
|
+
# NOTE: this runs in a thread
|
|
721
727
|
|
|
722
728
|
data_is_image = False
|
|
723
729
|
if "svg" in filetype:
|
|
@@ -887,7 +893,10 @@ class ObjectManager(utilities.BaseManager):
|
|
|
887
893
|
return
|
|
888
894
|
|
|
889
895
|
self.html.post_message(f"Creating object from {utilities.shorten(data)}")
|
|
890
|
-
|
|
896
|
+
if data.startswith("file://"):
|
|
897
|
+
self.fetch_objects(node, data, straight=True)
|
|
898
|
+
else:
|
|
899
|
+
self.html._thread_check(self.fetch_objects, node, data)
|
|
891
900
|
|
|
892
901
|
def _on_object_value_change(self, node, attribute, value):
|
|
893
902
|
if attribute == "data":
|
|
@@ -898,10 +907,11 @@ class ObjectManager(utilities.BaseManager):
|
|
|
898
907
|
# Force reset because it might contain widgets that are added internally
|
|
899
908
|
self.html.widget_manager.map_node(node, True)
|
|
900
909
|
|
|
901
|
-
def fetch_objects(self, node, url):
|
|
902
|
-
# NOTE: this
|
|
910
|
+
def fetch_objects(self, node, url, straight=False):
|
|
911
|
+
# NOTE: this runs in a thread
|
|
903
912
|
|
|
904
913
|
thread = self.html._begin_download()
|
|
914
|
+
|
|
905
915
|
if thread.isrunning():
|
|
906
916
|
try:
|
|
907
917
|
url, data, filetype, code = self.html.download_url(url)
|
|
@@ -910,9 +920,15 @@ class ObjectManager(utilities.BaseManager):
|
|
|
910
920
|
if filetype.startswith("image"):
|
|
911
921
|
name = self.html.image_manager.allocate_image_name()
|
|
912
922
|
data, data_is_image = self.html.image_manager.check_images(data, name, url, filetype)
|
|
913
|
-
|
|
923
|
+
if straight:
|
|
924
|
+
self._finish_fetching_image_objects(node, data, name, url, filetype, data_is_image)
|
|
925
|
+
else:
|
|
926
|
+
self.html.post_to_queue(lambda node=node, data=data, name=name, url=url, filetype=filetype, data_is_image=data_is_image: self._finish_fetching_image_objects(node, data, name, url, filetype, data_is_image))
|
|
914
927
|
elif filetype == "text/html":
|
|
915
|
-
|
|
928
|
+
if straight:
|
|
929
|
+
self._finish_fetching_HTML_objects(node, data, url, filetype)
|
|
930
|
+
else:
|
|
931
|
+
self.html.post_to_queue(lambda node=node, data=data, url=url, filetype=filetype: self._finish_fetching_HTML_objects(node, data, url, filetype))
|
|
916
932
|
|
|
917
933
|
except Exception as error:
|
|
918
934
|
self.html.post_message(f"ERROR: could not load object element with data {url}: {error}", True)
|
|
@@ -920,9 +936,9 @@ class ObjectManager(utilities.BaseManager):
|
|
|
920
936
|
self.html._finish_download(thread)
|
|
921
937
|
|
|
922
938
|
def _finish_fetching_image_objects(self, node, data, name, url, filetype, data_is_image):
|
|
923
|
-
# NOTE: this must run in the main thread
|
|
939
|
+
# NOTE: this must run in the main thread
|
|
924
940
|
|
|
925
|
-
image = self.html.image_manager.finish_fetching_images(
|
|
941
|
+
image = self.html.image_manager.finish_fetching_images(data, name, filetype, url, data_is_image)
|
|
926
942
|
self.html.override_node_properties(node, "-tkhtml-replacement-image", f"url({image})")
|
|
927
943
|
self.html.event_manager.post_element_event(node, "onload", None, utilities.ELEMENT_LOADED_EVENT)
|
|
928
944
|
|
tkinterweb/htmlwidgets.py
CHANGED
|
@@ -437,7 +437,7 @@ class HtmlFrame(Frame):
|
|
|
437
437
|
file_url = "file://" + str(file_url)
|
|
438
438
|
self._current_url = file_url
|
|
439
439
|
self._html.post_event(utilities.URL_CHANGED_EVENT)
|
|
440
|
-
self.
|
|
440
|
+
self.load_url(file_url, decode, force)
|
|
441
441
|
|
|
442
442
|
def load_website(self, website_url, decode=None, force=False):
|
|
443
443
|
"""Convenience method to load a website.
|
|
@@ -482,7 +482,8 @@ class HtmlFrame(Frame):
|
|
|
482
482
|
|
|
483
483
|
if self._thread_in_progress:
|
|
484
484
|
self._thread_in_progress.stop()
|
|
485
|
-
|
|
485
|
+
|
|
486
|
+
if self._html.threading_enabled and not url.startswith("file://"):
|
|
486
487
|
thread = utilities.StoppableThread(target=self._continue_loading, args=(
|
|
487
488
|
url,), kwargs={"decode": decode, "force": force, "thread_safe": True})
|
|
488
489
|
self._thread_in_progress = thread
|
|
@@ -1131,6 +1132,9 @@ class HtmlFrame(Frame):
|
|
|
1131
1132
|
|
|
1132
1133
|
if self.unshrink:
|
|
1133
1134
|
if event.x and self._prev_configure != (event.width, event.x):
|
|
1135
|
+
# if not self._html.using_tkhtml30:
|
|
1136
|
+
# self._html.configure(textwrap=False)
|
|
1137
|
+
# self.after(10, lambda: self._html.configure(textwrap=True))
|
|
1134
1138
|
self.after_idle(lambda: self._html.configure(
|
|
1135
1139
|
width=self.winfo_screenwidth(),
|
|
1136
1140
|
height=event.height)
|
|
@@ -1183,7 +1187,7 @@ class HtmlFrame(Frame):
|
|
|
1183
1187
|
|
|
1184
1188
|
def _continue_loading(self, url, data="", method="GET", decode=None, force=False, thread_safe=False):
|
|
1185
1189
|
"Finish loading urls and handle URI fragments."
|
|
1186
|
-
# NOTE: this
|
|
1190
|
+
# NOTE: this runs in a thread
|
|
1187
1191
|
|
|
1188
1192
|
code = 404
|
|
1189
1193
|
self._current_url = url
|
|
@@ -1271,7 +1275,7 @@ class HtmlFrame(Frame):
|
|
|
1271
1275
|
if self._current_url != url:
|
|
1272
1276
|
self._html.post_event(utilities.URL_CHANGED_EVENT)
|
|
1273
1277
|
text = self._get_about_page("about:image", name)
|
|
1274
|
-
self._html.image_manager.finish_fetching_images(
|
|
1278
|
+
self._html.image_manager.finish_fetching_images(data, name, url, filetype, data_is_image)
|
|
1275
1279
|
self.load_html(text, url)
|
|
1276
1280
|
|
|
1277
1281
|
def _finish_loading_nothing(self):
|
tkinterweb/utilities.py
CHANGED
|
@@ -31,7 +31,7 @@ __title__ = "TkinterWeb"
|
|
|
31
31
|
__author__ = "Andrew Clarke"
|
|
32
32
|
__copyright__ = "(c) 2021-2025 Andrew Clarke"
|
|
33
33
|
__license__ = "MIT"
|
|
34
|
-
__version__ = "4.17.
|
|
34
|
+
__version__ = "4.17.2"
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
ROOT_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), "resources")
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
tkinterweb/__init__.py,sha256=mKnt2RjNd0zMntvkmT4dn5iyytsko7fJJb-rnx4H82E,4690
|
|
2
|
-
tkinterweb/bindings.py,sha256=
|
|
2
|
+
tkinterweb/bindings.py,sha256=4orI0ZHiMlYG_lMcNOxzFJS8hOWYvjuoPzYsPyEp1NM,73362
|
|
3
3
|
tkinterweb/dom.py,sha256=6zEZUGMSdWuwu1-MQOpt1XJN-w_Aku1HGY5P2iM2ksE,43546
|
|
4
4
|
tkinterweb/extensions.py,sha256=QfV13omkMoeXe17JPbeJjykwXtWTcZ24mKuB7NoBgVI,46555
|
|
5
|
-
tkinterweb/handlers.py,sha256=
|
|
6
|
-
tkinterweb/htmlwidgets.py,sha256=
|
|
5
|
+
tkinterweb/handlers.py,sha256=iYzDgiHeF_wlXXPS2jI-sicq7KaGEDYq43fHbLZsaH0,42776
|
|
6
|
+
tkinterweb/htmlwidgets.py,sha256=sLsF3aQKoVBomFyaPrAvwmWkZ5DgNP1Q1U46Fs_osdc,104317
|
|
7
7
|
tkinterweb/imageutils.py,sha256=Du6vX00Isx7z1Q6sVV4po9ycYrP_iDG22ScG04U_huQ,5368
|
|
8
8
|
tkinterweb/js.py,sha256=Wlameh5KGK3GKzBCczaWYWT1L6-5uOWHt1HCZmzrjLk,3597
|
|
9
9
|
tkinterweb/subwidgets.py,sha256=wT4gtUnUE5j9UA8lrKCjLaysWqHav-_46NF97uMswDo,28200
|
|
10
|
-
tkinterweb/utilities.py,sha256=
|
|
10
|
+
tkinterweb/utilities.py,sha256=iRjqA3ULlLueVO38M9azbmIYk7RFtv98fmdA9SDWpwA,43463
|
|
11
11
|
tkinterweb/resources/combobox-2.3.tm,sha256=flofzRxHJMeEj0I--4iLT9SWIo9G1MSIwY0h940tG-U,65083
|
|
12
12
|
tkinterweb/resources/pkgIndex.tcl,sha256=Zp99aTL170d0TbVrWS-6uzaIaykUQbRO0krvmJhcduA,77
|
|
13
|
-
tkinterweb-4.17.
|
|
14
|
-
tkinterweb-4.17.
|
|
15
|
-
tkinterweb-4.17.
|
|
16
|
-
tkinterweb-4.17.
|
|
17
|
-
tkinterweb-4.17.
|
|
13
|
+
tkinterweb-4.17.2.dist-info/LICENSE.md,sha256=Jf8BR3uTR9RLMAA2osul_ZRkvoYRgmlqq1Pd-xt0uMY,1074
|
|
14
|
+
tkinterweb-4.17.2.dist-info/METADATA,sha256=aULx21SFHyyc_nV0YaNCSclu4IT0mA6sgCgXwagzOhI,3133
|
|
15
|
+
tkinterweb-4.17.2.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
16
|
+
tkinterweb-4.17.2.dist-info/top_level.txt,sha256=QVZQjAzSgzBGwOl41qcOyvkYAwy1FXLlnvwtYvE9Ur4,11
|
|
17
|
+
tkinterweb-4.17.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|