Repository URL to install this package:
|
Version:
7.2.1 ▾
|
# (C) Copyright 2004-2021 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
""" Traits UI MS Internet Explorer editor.
"""
import re
import webbrowser
import wx
if wx.Platform == "__WXMSW__":
# The new version of IEHTMLWindow (wx 2.8.8.0) is mostly compatible with
# the old one, but it has changed the API for handling COM events, so we
# cannot use it.
try:
import wx.lib.iewin_old as iewin
except ImportError:
import wx.lib.iewin as iewin
from traits.api import Bool, Event, Property, Str
from traitsui.wx.editor import Editor
from traitsui.basic_editor_factory import BasicEditorFactory
# -------------------------------------------------------------------------
# Constants
# -------------------------------------------------------------------------
RELATIVE_OBJECTS_PATTERN = re.compile(
r'src=["\'](?!https?:)([\s\w/\.]+?)["\']', re.IGNORECASE
)
class _IEHTMLEditor(Editor):
""" Traits UI MS Internet Explorer editor.
"""
# -------------------------------------------------------------------------
# Trait definitions:
# -------------------------------------------------------------------------
#: Is the table editor is scrollable? This value overrides the default.
scrollable = True
#: External objects referenced in the HTML are relative to this url
base_url = Str()
#: Event fired when the browser home page should be displayed:
home = Event()
#: Event fired when the browser should show the previous page:
back = Event()
#: Event fired when the browser should show the next page:
forward = Event()
#: Event fired when the browser should stop loading the current page:
stop = Event()
#: Event fired when the browser should refresh the current page:
refresh = Event()
#: Event fired when the browser should search the current page:
search = Event()
#: The current browser status:
status = Str()
#: The current browser page title:
title = Str()
#: The URL of the page that just finished loading:
page_loaded = Str()
#: The current page content as HTML:
html = Property()
def init(self, parent):
""" Finishes initializing the editor by creating the underlying toolkit
widget.
"""
self.control = ie = iewin.IEHtmlWindow(
parent, -1, style=wx.NO_FULL_REPAINT_ON_RESIZE
)
self.set_tooltip()
factory = self.factory
self.base_url = factory.base_url
self.sync_value(factory.home, "home", "from")
self.sync_value(factory.back, "back", "from")
self.sync_value(factory.forward, "forward", "from")
self.sync_value(factory.stop, "stop", "from")
self.sync_value(factory.refresh, "refresh", "from")
self.sync_value(factory.search, "search", "from")
self.sync_value(factory.status, "status", "to")
self.sync_value(factory.title, "title", "to")
self.sync_value(factory.page_loaded, "page_loaded", "to")
self.sync_value(factory.html, "html", "to")
self.sync_value(factory.base_url_name, "base_url", "from")
parent.Bind(iewin.EVT_StatusTextChange, ie, id=self._status_modified)
parent.Bind(iewin.EVT_TitleChange, ie, id=self._title_modified)
parent.Bind(iewin.EVT_DocumentComplete, ie, id=self._page_loaded_modified)
parent.Bind(iewin.EVT_NewWindow2, ie, id=self._new_window_modified)
parent.Bind(iewin.EVT_BeforeNavigate2, ie, id=self._navigate_requested)
def update_editor(self):
""" Updates the editor when the object trait changes externally to the
editor.
"""
value = self.str_value.strip()
# We can correct URLs via the BeforeNavigate Event, but the COM
# interface provides no such option for images. Sadly, we are forced
# to take a more brute force approach.
if self.base_url:
rep = lambda m: r'src="%s%s"' % (self.base_url, m.group(1))
value = re.sub(RELATIVE_OBJECTS_PATTERN, rep, value)
if value == "":
self.control.LoadString("<html><body></body></html>")
elif value[:1] == "<":
self.control.LoadString(value)
elif (value[:4] != "http") or (value.find("://") < 0):
try:
with open(value, "rb") as file:
self.control.LoadStream(file)
except:
pass
else:
self.control.Navigate(value)
# -- Property Implementations ---------------------------------------------
def _get_html(self):
return self.control.GetText()
def _set_html(self, value):
self.control.LoadString(value)
# -- Event Handlers -------------------------------------------------------
def _home_changed(self):
self.control.GoHome()
def _back_changed(self):
self.control.GoBack()
def _forward_changed(self):
self.control.GoForward()
def _stop_changed(self):
self.control.Stop()
def _search_changed(self):
self.control.GoSearch()
def _refresh_changed(self):
self.control.Refresh(iewin.REFRESH_COMPLETELY)
def _status_modified(self, event):
self.status = event.Text
def _title_modified(self, event):
self.title = event.Text
def _page_loaded_modified(self, event):
self.page_loaded = event.URL
self.trait_property_changed("html", "", self.html)
def _new_window_modified(self, event):
# If the event is cancelled, new windows can be disabled.
# At this point we've opted to allow new windows
pass
def _navigate_requested(self, event):
# The way NavigateToString works is to navigate to about:blank then
# load the supplied HTML into the document property. This borks
# relative URLs.
if event.URL.startswith("about:"):
base = self.base_url
if not base.endswith("/"):
base += "/"
event.URL = base + event.URL[6:]
if self.factory.open_externally:
event.Cancel = True
webbrowser.get("windows-default").open_new(event.URL)
# -------------------------------------------------------------------------
# Create the editor factory object:
# -------------------------------------------------------------------------
# wxPython editor factory for MS Internet Explorer editors:
class IEHTMLEditor(BasicEditorFactory):
#: The editor class to be created:
klass = _IEHTMLEditor
#: External objects referenced in the HTML are relative to this url
base_url = Str()
#: The object trait containing the base URL
base_url_name = Str()
#: Should links be opened in an external browser?
open_externally = Bool(False)
#: Optional name of trait used to tell browser to show Home page:
home = Str()
#: Optional name of trait used to tell browser to view the previous page:
back = Str()
#: Optional name of trait used to tell browser to view the next page:
forward = Str()
#: Optional name of trait used to tell browser to stop loading page:
stop = Str()
#: Optional name of trait used to tell browser to refresh the current page:
refresh = Str()
#: Optional name of trait used to tell browser to search the current page:
search = Str()
#: Optional name of trait used to contain the current browser status:
status = Str()
#: Optional name of trait used to contain the current browser page title:
title = Str()
#: Optional name of trait used to contain the URL of the page that just
#: completed loading:
page_loaded = Str()
#: Optional name of trait used to get/set the page content as HTML:
html = Str()