Ejemplo n.º 1
0
    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()
Ejemplo n.º 2
0
    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()