Esempio n. 1
0
    def __init__(self, uid, title, url, html, width, height, x, y, resizable,
                 fullscreen, min_size, confirm_close, background_color, js_api,
                 text_select, frameless):
        self.uid = uid
        self.title = make_unicode(title)
        self.url = None if html else transform_url(url)
        self.html = html
        self.width = width
        self.height = height
        self.x = x
        self.y = y
        self.resizable = resizable
        self.fullscreen = fullscreen
        self.min_size = min_size
        self.confirm_close = confirm_close
        self.background_color = background_color
        self.js_api = js_api
        self.text_select = text_select
        self.frameless = frameless

        self.loaded = Event()
        self.shown = Event()
        self.gui = None

        self._httpd = None
Esempio n. 2
0
    def __init__(self, uid, title, url, html, width, height, x, y, resizable,
                 fullscreen, min_size, hidden, frameless, minimized,
                 confirm_close, background_color, js_api, text_select):
        self.uid = uid
        self.title = make_unicode(title)
        self.url = None if html else transform_url(url)
        self.html = html
        self.initial_width = width
        self.initial_height = height
        self.initial_x = x
        self.initial_y = y
        self.resizable = resizable
        self.fullscreen = fullscreen
        self.min_size = min_size
        self.confirm_close = confirm_close
        self.background_color = background_color
        self.text_select = text_select
        self.frameless = frameless
        self.hidden = hidden
        self.minimized = minimized

        self._js_api = js_api
        self._functions = {}

        self.closed = Event()
        self.closing = Event()
        self.loaded = Event()
        self.shown = Event()

        self.gui = None
        self._httpd = None
        self._is_http_server = False
Esempio n. 3
0
    def __init__(self, uid, title, url, html, width, height, x, y, resizable, fullscreen,
                 min_size, hidden, frameless, easy_drag, minimized, on_top, confirm_close,
                 background_color, js_api, text_select, transparent):
        self.uid = uid
        self.title = make_unicode(title)
        self.original_url = None if html else url  # original URL provided by user
        self.real_url = None  # transformed URL for internal HTTP server
        self.html = html
        self.initial_width = width
        self.initial_height = height
        self.initial_x = x
        self.initial_y = y
        self.resizable = resizable
        self.fullscreen = fullscreen
        self.min_size = min_size
        self.confirm_close = confirm_close
        self.background_color = background_color
        self.text_select = text_select
        self.frameless = frameless
        self.easy_drag = easy_drag
        self.hidden = hidden
        self.on_top = on_top
        self.minimized = minimized
        self.transparent = transparent

        self._js_api = js_api
        self._functions = {}

        self.closed = Event()
        self.closing = Event(True)
        self.loaded = Event()
        self.shown = Event()

        self.gui = None
        self._is_http_server = False
Esempio n. 4
0
class Window:
    def __init__(self, uid, title, url, html, width, height, x, y, resizable,
                 fullscreen, min_size, hidden, frameless, easy_drag, minimized,
                 on_top, confirm_close, background_color, js_api, text_select,
                 transparent, localization):
        self.uid = uid
        self.title = make_unicode(title)
        self.original_url = None if html else url  # original URL provided by user
        self.real_url = None  # transformed URL for internal HTTP server
        self.html = html
        self.initial_width = width
        self.initial_height = height
        self.initial_x = x
        self.initial_y = y
        self.resizable = resizable
        self.fullscreen = fullscreen
        self.min_size = min_size
        self.confirm_close = confirm_close
        self.background_color = background_color
        self.text_select = text_select
        self.frameless = frameless
        self.easy_drag = easy_drag
        self.hidden = hidden
        self.on_top = on_top
        self.minimized = minimized
        self.transparent = transparent
        self.localization_override = localization

        self._js_api = js_api
        self._functions = {}

        self.closed = Event()
        self.closing = Event(True)
        self.loaded = Event()
        self.shown = Event()

        self.gui = None
        self._is_http_server = False

    def _initialize(self, gui, multiprocessing, http_server):
        self.gui = gui
        self.loaded._initialize(multiprocessing)
        self.shown._initialize(multiprocessing)
        self._is_http_server = http_server

        # WebViewControl as of 5.1.1 crashes on file:// urls. Stupid workaround to make it work
        if (gui.renderer == "edgehtml" and self.original_url
                and isinstance(self.original_url, str)
                and (self.original_url.startswith('file://')
                     or '://' not in self.original_url)):
            self._is_http_server = True

        self.real_url = resolve_url(self.original_url, self._is_http_server)

        self.localization = original_localization.copy()
        if self.localization_override:
            self.localization.update(self.localization_override)

    @property
    def width(self):
        self.shown.wait(15)
        width, _ = self.gui.get_size(self.uid)
        return width

    @property
    def height(self):
        self.shown.wait(15)
        _, height = self.gui.get_size(self.uid)
        return height

    @property
    def x(self):
        self.shown.wait(15)
        x, _ = self.gui.get_position(self.uid)
        return x

    @property
    def y(self):
        self.shown.wait(15)
        _, y = self.gui.get_position(self.uid)
        return y

    @property
    def on_top(self):
        return self.__on_top

    @on_top.setter
    def on_top(self, on_top):
        self.__on_top = on_top
        if hasattr(self, 'gui') and self.gui != None:
            self.gui.set_on_top(self.uid, on_top)

    @_loaded_call
    def get_elements(self, selector):
        # check for GTK's WebKit2 version
        if hasattr(self.gui, 'old_webkit') and self.gui.old_webkit:
            raise NotImplementedError(
                'get_elements requires WebKit2 2.2 or greater')

        code = """
            var elements = document.querySelectorAll('%s');
            var serializedElements = [];

            for (var i = 0; i < elements.length; i++) {
                var node = pywebview.domJSON.toJSON(elements[i], {
                    metadata: false,
                    serialProperties: true
                });
                serializedElements.push(node);
            }

            serializedElements;
        """ % selector

        return self.evaluate_js(code)

    @_shown_call
    def load_url(self, url):
        """
        Load a new URL into a previously created WebView window. This function must be invoked after WebView windows is
        created with create_window(). Otherwise an exception is thrown.
        :param url: url to load
        :param uid: uid of the target instance
        """
        self.url = url
        self.real_url = resolve_url(
            url, self._is_http_server or self.gui.renderer == 'edgehtml')

        self.gui.load_url(self.real_url, self.uid)

    @_shown_call
    def load_html(self, content, base_uri=base_uri()):
        """
        Load a new content into a previously created WebView window. This function must be invoked after WebView windows is
        created with create_window(). Otherwise an exception is thrown.
        :param content: Content to load.
        :param base_uri: Base URI for resolving links. Default is the directory of the application entry point.
        :param uid: uid of the target instance
        """

        content = make_unicode(content)
        self.gui.load_html(content, base_uri, self.uid)

    @_loaded_call
    def load_css(self, stylesheet):
        code = css.src % stylesheet.replace('\n', '').replace(
            '\r', '').replace('"', "'")
        self.gui.evaluate_js(code, self.uid)

    @_shown_call
    def set_title(self, title):
        """
        Set a new title of the window
        """
        self.gui.set_title(title, self.uid)

    @_loaded_call
    def get_current_url(self):
        """
        Get the URL currently loaded in the target webview
        """
        return self.gui.get_current_url(self.uid)

    @_shown_call
    def destroy(self):
        """
        Destroy a web view window
        """
        self.gui.destroy_window(self.uid)

    @_shown_call
    def show(self):
        """
        Show a web view window.
        """
        self.gui.show(self.uid)

    @_shown_call
    def hide(self):
        """
        Hide a web view window.
        """
        self.gui.hide(self.uid)

    @_shown_call
    def set_window_size(self, width, height):
        """
        Resize window
        :param width: desired width of target window
        :param height: desired height of target window
        """
        logger.warning(
            'This function is deprecated and will be removed in future releases. Use resize() instead'
        )
        self.gui.resize(width, height, self.uid)

    @_shown_call
    def resize(self, width, height):
        """
        Resize window
        :param width: desired width of target window
        :param height: desired height of target window
        """
        self.gui.resize(width, height, self.uid)

    @_shown_call
    def minimize(self):
        """
        Minimize window.
        """
        self.gui.minimize(self.uid)

    @_shown_call
    def restore(self):
        """
        Restore minimized window.
        """
        self.gui.restore(self.uid)

    @_shown_call
    def toggle_fullscreen(self):
        """
        Toggle fullscreen mode
        """
        self.gui.toggle_fullscreen(self.uid)

    @_shown_call
    def move(self, x, y):
        """
        Move Window
        :param x: desired x coordinate of target window
        :param y: desired y coordinate of target window
        """
        self.gui.move(x, y, self.uid)

    @_loaded_call
    def evaluate_js(self, script):
        """
        Evaluate given JavaScript code and return the result
        :param script: The JavaScript code to be evaluated
        :return: Return value of the evaluated code
        """
        escaped_script = 'JSON.stringify(eval("{0}"))'.format(
            escape_string(script))
        return self.gui.evaluate_js(escaped_script, self.uid)

    @_shown_call
    def create_file_dialog(self,
                           dialog_type=10,
                           directory='',
                           allow_multiple=False,
                           save_filename='',
                           file_types=()):
        """
        Create a file dialog
        :param dialog_type: Dialog type: open file (OPEN_DIALOG), save file (SAVE_DIALOG), open folder (OPEN_FOLDER). Default
                            is open file.
        :param directory: Initial directory
        :param allow_multiple: Allow multiple selection. Default is false.
        :param save_filename: Default filename for save file dialog.
        :param file_types: Allowed file types in open file dialog. Should be a tuple of strings in the format:
            filetypes = ('Description (*.extension[;*.extension[;...]])', ...)
        :return: A tuple of selected files, None if cancelled.
        """
        if type(file_types) != tuple and type(file_types) != list:
            raise TypeError('file_types must be a tuple of strings')
        for f in file_types:
            parse_file_type(f)

        if not os.path.exists(directory):
            directory = ''

        return self.gui.create_file_dialog(dialog_type, directory,
                                           allow_multiple, save_filename,
                                           file_types, self.uid)

    def expose(self, *functions):
        if not all(map(callable, functions)):
            raise TypeError('Parameter must be a function')

        func_list = []

        for func in functions:
            name = func.__name__
            self._functions[name] = func

            try:
                params = list(inspect.getfullargspec(func).args)  # Python 3
            except AttributeError:
                params = list(inspect.getargspec(func).args)  # Python 2

            func_list.append({'func': name, 'params': params})

        if self.loaded.is_set():
            self.evaluate_js('window.pywebview._createApi(%s)' % func_list)
Esempio n. 5
0
class Window:
    def __init__(self, uid, title, url, html, width, height, resizable, fullscreen,
                 min_size, confirm_close, background_color, js_api, text_select, frameless):
        self.uid = uid
        self.title = make_unicode(title)
        self.url = None if html else transform_url(url)
        self.html = html
        self.width = width
        self.height = height
        self.resizable = resizable
        self.fullscreen = fullscreen
        self.min_size = min_size
        self.confirm_close = confirm_close
        self.background_color = background_color
        self.js_api = js_api
        self.text_select = text_select
        self.frameless = frameless

        self.loaded = Event()
        self.shown = Event()
        self.gui = None

        self._httpd = None

    def _initialize(self, gui, multiprocessing, http_server):
        self.gui = gui
        self.loaded._initialize(multiprocessing)
        self.shown._initialize(multiprocessing)

        if http_server and self.url and self.url.startswith('file://'):
            self.url, self._httpd = start_server(self.url)

    @_loaded_call
    def get_elements(self, selector):
        # check for GTK's WebKit2 version
        if hasattr(self.gui, 'old_webkit') and self.gui.old_webkit:
            raise NotImplementedError('get_elements requires WebKit2 2.2 or greater')

        code = """
            var elements = document.querySelectorAll('%s');
            var serializedElements = [];

            for (var i = 0; i < elements.length; i++) {
                var node = pywebview.domJSON.toJSON(elements[i], {
                    metadata: false,
                    serialProperties: true
                });
                serializedElements.push(node);
            }

            serializedElements;
        """ % selector

        return self.evaluate_js(code)

    @_shown_call
    def load_url(self, url):
        """
        Load a new URL into a previously created WebView window. This function must be invoked after WebView windows is
        created with create_window(). Otherwise an exception is thrown.
        :param url: url to load
        :param uid: uid of the target instance
        """
        if self._httpd:
            self._httpd.shutdown()
            self._httpd = None

        url = transform_url(url)

        if (self._httpd or self.gui.renderer == 'edgehtml') and url.startswith('file://'):
            url, self._httpd = start_server(url)

        self.gui.load_url(url, self.uid)

    @_shown_call
    def load_html(self, content, base_uri=base_uri()):
        """
        Load a new content into a previously created WebView window. This function must be invoked after WebView windows is
        created with create_window(). Otherwise an exception is thrown.
        :param content: Content to load.
        :param base_uri: Base URI for resolving links. Default is the directory of the application entry point.
        :param uid: uid of the target instance
        """

        if self._httpd:
            self._httpd.shutdown()

        content = make_unicode(content)
        self.gui.load_html(content, base_uri, self.uid)

    @_loaded_call
    def load_css(self, stylesheet):
        code = css.src % stylesheet.replace('\n', '').replace('\r', '').replace('"', "'")
        self.gui.evaluate_js(code, self.uid)

    @_shown_call
    def set_title(self, title):
        """
        Set a new title of the window
        """
        self.gui.set_title(title, self.uid)

    @_loaded_call
    def get_current_url(self):
        """
        Get the URL currently loaded in the target webview
        """
        return self.gui.get_current_url(self.uid)

    @_shown_call
    def destroy(self):
        """
        Destroy a web view window
        """
        self.gui.destroy_window(self.uid)

    @_shown_call
    def toggle_fullscreen(self):
        """
        Toggle fullscreen mode
        """
        self.gui.toggle_fullscreen(self.uid)

    @_shown_call
    def set_window_size(self, width, height):
        """
        Set Window Size
        :param width: desired width of target window
        :param height: desired height of target window
        """
        self.gui.set_window_size(width, height, self.uid)

    @_loaded_call
    def evaluate_js(self, script):
        """
        Evaluate given JavaScript code and return the result
        :param script: The JavaScript code to be evaluated
        :return: Return value of the evaluated code
        """
        escaped_script = 'JSON.stringify(eval("{0}"))'.format(escape_string(script))
        return self.gui.evaluate_js(escaped_script, self.uid)

    @_shown_call
    def create_file_dialog(self, dialog_type=10, directory='', allow_multiple=False, save_filename='', file_types=()):
        """
        Create a file dialog
        :param dialog_type: Dialog type: open file (OPEN_DIALOG), save file (SAVE_DIALOG), open folder (OPEN_FOLDER). Default
                            is open file.
        :param directory: Initial directory
        :param allow_multiple: Allow multiple selection. Default is false.
        :param save_filename: Default filename for save file dialog.
        :param file_types: Allowed file types in open file dialog. Should be a tuple of strings in the format:
            filetypes = ('Description (*.extension[;*.extension[;...]])', ...)
        :return: A tuple of selected files, None if cancelled.
        """
        if type(file_types) != tuple and type(file_types) != list:
            raise TypeError('file_types must be a tuple of strings')
        for f in file_types:
            parse_file_type(f)

        if not os.path.exists(directory):
            directory = ''

        return self.gui.create_file_dialog(dialog_type, directory, allow_multiple, save_filename, file_types, self.uid)