def __init__(self, form, window): self.pywebview_window = window self.web_view = WebView() life = ISupportInitialize(self.web_view) life.BeginInit() form.Controls.Add(self.web_view) self.js_result_semaphore = Semaphore(0) self.web_view.Dock = WinForms.DockStyle.Fill self.web_view.DpiAware = True self.web_view.IsIndexedDBEnabled = True self.web_view.IsJavaScriptEnabled = True self.web_view.IsScriptNotifyAllowed = True self.web_view.IsPrivateNetworkClientServerCapabilityEnabled = True self.web_view.DefaultBackgroundColor = form.BackColor self.web_view.ScriptNotify += self.on_script_notify self.web_view.NewWindowRequested += self.on_new_window_request self.web_view.NavigationCompleted += self.on_navigation_completed # This must be before loading URL. Otherwise the webview will remain empty life.EndInit() self.temp_html = None self.url = None _allow_localhost() if window.url: self.load_url(window.url) elif window.html: self.load_html(window.html, '') else: self.load_html(default_html, '')
class EdgeHTML: def __init__(self, form, window): self.pywebview_window = window self.web_view = WebView() life = ISupportInitialize(self.web_view) life.BeginInit() form.Controls.Add(self.web_view) self.js_result_semaphore = Semaphore(0) self.web_view.Dock = WinForms.DockStyle.Fill self.web_view.DpiAware = True self.web_view.IsIndexedDBEnabled = True self.web_view.IsJavaScriptEnabled = True self.web_view.IsScriptNotifyAllowed = True self.web_view.IsPrivateNetworkClientServerCapabilityEnabled = True self.web_view.DefaultBackgroundColor = form.BackColor self.web_view.ScriptNotify += self.on_script_notify self.web_view.NewWindowRequested += self.on_new_window_request self.web_view.NavigationCompleted += self.on_navigation_completed # This must be before loading URL. Otherwise the webview will remain empty life.EndInit() self.httpd = None # HTTP server for load_html self.tmpdir = None self.url = None self.ishtml = False _allow_localhost() if window.url: self.load_url(window.url) elif window.html: self.load_html(window.html, '') else: self.load_html(default_html, '') def evaluate_js(self, script): try: result = self.web_view.InvokeScript('eval', (script,)) except Exception as e: logger.exception('Error occurred in script') result = None self.js_result = None if result is None or result == '' else json.loads(result) self.js_result_semaphore.release() def get_current_url(self): return self.url def load_html(self, html, base_uri): self.tmpdir = tempfile.mkdtemp() self.temp_html = os.path.join(self.tmpdir, 'index.html') with open(self.temp_html, 'w', encoding='utf-8') as f: f.write(inject_base_uri(html, base_uri)) if self.httpd: self.httpd.shutdown() url, _ = start_server('file://' + self.temp_html) self.ishtml = True self.web_view.Navigate(url) def load_url(self, url): self.ishtml = False # WebViewControl as of 5.1.1 crashes on file:// urls. Stupid workaround to make it work if url.startswith('file://'): url = start_server(self.url) self.web_view.Navigate(url) def on_script_notify(self, _, args): try: func_name, func_param, value_id = json.loads(args.Value) if func_name == 'alert': WinForms.MessageBox.Show(func_param) elif func_name == 'console': print(func_param) else: js_bridge_call(self.pywebview_window, func_name, func_param, value_id) except Exception as e: logger.exception('Exception occured during on_script_notify') def on_new_window_request(self, _, args): webbrowser.open(str(args.get_Uri())) args.set_Handled(True) def on_navigation_completed(self, _, args): try: if self.tmpdir and os.path.exists(self.tmpdir): shutil.rmtree(self.tmpdir) self.tmpdir = None except Exception as e: logger.exception('Failed deleting %s' % self.tmpdir) url = str(args.Uri) self.url = None if self.ishtml else url self.web_view.InvokeScript('eval', ('window.alert = (msg) => window.external.notify(JSON.stringify(["alert", msg+"", ""]))',)) if _debug: self.web_view.InvokeScript('eval', ('window.console = { log: (msg) => window.external.notify(JSON.stringify(["console", msg+"", ""]))}',)) self.web_view.InvokeScript('eval', (parse_api_js(self.pywebview_window, 'edgehtml'),)) if not self.pywebview_window.text_select: self.web_view.InvokeScript('eval', (disable_text_select,)) self.pywebview_window.loaded.set()
class EdgeHTML: def __init__(self, form, window): self.pywebview_window = window self.web_view = WebView() life = ISupportInitialize(self.web_view) life.BeginInit() form.Controls.Add(self.web_view) self.js_result_semaphore = Semaphore(0) self.web_view.Dock = WinForms.DockStyle.Fill self.web_view.DpiAware = True self.web_view.IsIndexedDBEnabled = True self.web_view.IsJavaScriptEnabled = True self.web_view.IsScriptNotifyAllowed = True self.web_view.IsPrivateNetworkClientServerCapabilityEnabled = True self.web_view.DefaultBackgroundColor = form.BackColor self.web_view.ScriptNotify += self.on_script_notify self.web_view.NewWindowRequested += self.on_new_window_request self.web_view.NavigationCompleted += self.on_navigation_completed # This must be before loading URL. Otherwise the webview will remain empty life.EndInit() self.temp_html = None self.url = None _allow_localhost() if window.url: self.load_url(window.url) elif window.html: self.load_html(window.html, '') else: self.load_html(default_html, '') def evaluate_js(self, script): try: result = self.web_view.InvokeScript('eval', (script, )) except Exception as e: logger.exception('Error occurred in script') result = None self.js_result = None if result is None or result == '' else json.loads( result) self.js_result_semaphore.release() def get_current_url(self): return self.url def load_html(self, html, base_uri): file_name = '%s.html' % uuid4().hex self.temp_html = os.path.join(WinForms.Application.StartupPath, file_name) with open(self.temp_html, 'w') as f: f.write(inject_base_uri(html, base_uri)) self.web_view.NavigateToLocal(file_name) def load_url(self, url): self.temp_html = None # WebViewControl as of 5.1.1 crashes on file:// urls. Stupid workaround to make it work if url.startswith('file://'): path = url.replace('file://', '') if not os.path.exists(path): raise WebViewException('File %s does not exist' % path) with open(path) as f: html = f.read() self.load_html(html, 'file://' + os.path.dirname(path) + '\\') else: self.web_view.Navigate(url) def on_script_notify(self, _, args): func_name, func_param = json.loads(args.Value) if func_name == 'alert': WinForms.MessageBox.Show(func_param) elif func_name == 'console': print(func_param) else: js_bridge_call(self.pywebview_window, func_name, func_param) def on_new_window_request(self, _, args): webbrowser.open(str(args.get_Uri())) args.set_Handled(True) def on_navigation_completed(self, _, args): try: if self.temp_html and os.path.exists(self.temp_html): os.remove(self.temp_html) self.temp_html = None except Exception as e: logger.exception('Failed deleting %s' % self.temp_html) url = str(args.Uri) self.url = None if url.startswith('ms-local-stream:') else url self.web_view.InvokeScript('eval', ( 'window.alert = (msg) => window.external.notify(JSON.stringify(["alert", msg+""]))', )) if _debug: self.web_view.InvokeScript('eval', ( 'window.console = { log: (msg) => window.external.notify(JSON.stringify(["console", msg+""]))}', )) self.web_view.InvokeScript( 'eval', (parse_api_js(self.pywebview_window.js_api, 'edgehtml'), )) if not self.pywebview_window.text_select: self.web_view.InvokeScript('eval', (disable_text_select, )) self.pywebview_window.loaded.set()