1269 lines
43 KiB
Cython
1269 lines
43 KiB
Cython
# Copyright (C) 2007-2015 various contributors (see AUTHORS)
|
|
#
|
|
# This file is part of Python-EFL.
|
|
#
|
|
# Python-EFL is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
# License as published by the Free Software Foundation; either
|
|
# version 3 of the License, or (at your option) any later version.
|
|
#
|
|
# Python-EFL is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public License
|
|
# along with this Python-EFL. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
"""
|
|
|
|
A web widget is used for displaying web pages (HTML/CSS/JS)
|
|
using WebKit-EFL. You must have compiled Elementary with
|
|
ewebkit support.
|
|
|
|
Signals that you can add callbacks for are:
|
|
|
|
- ``download,request``: A file download has been requested. Event info is
|
|
a WebDownload instance
|
|
- ``editorclient,contents,changed``: Editor client's contents changed
|
|
- ``editorclient,selection,changed``: Editor client's selection changed
|
|
- ``frame,created``: A new frame was created. Event info is an
|
|
Evas_Object which can be handled with WebKit's ewk_frame API
|
|
- ``icon,received``: An icon was received by the main frame
|
|
- ``inputmethod,changed``: Input method changed. Event info is an
|
|
Eina_Bool indicating whether it's enabled or not
|
|
- ``js,windowobject,clear``: JS window object has been cleared
|
|
- ``link,hover,in``: Mouse cursor is hovering over a link. Event info
|
|
is a tuple, where the first string contains the URL the link
|
|
points to, and the second one the title of the link
|
|
- ``link,hover,out``: Mouse cursor left the link
|
|
- ``load,document,finished``: Loading of a document finished. Event info
|
|
is the frame that finished loading
|
|
- ``load,error``: Load failed. Event info is a WebFrameLoadError instance
|
|
- ``load,finished``: Load finished. Event info is None on success, on
|
|
error it's a WebFrameLoadError instance
|
|
- ``load,newwindow,show``: A new window was created and is ready to be
|
|
shown
|
|
- ``load,progress``: Overall load progress. Event info is
|
|
a double containing a value between 0.0 and 1.0
|
|
- ``load,provisional``: Started provisional load
|
|
- ``load,started``: Loading of a document started
|
|
- ``menubar,visible,get``: Queries if the menubar is visible. Event info
|
|
is a bool where the callback should set True if
|
|
the menubar is visible, or False in case it's not
|
|
- ``menubar,visible,set``: Informs menubar visibility. Event info is
|
|
a bool indicating the visibility
|
|
- ``popup,created``: A dropdown widget was activated, requesting its
|
|
popup menu to be created. Event info is a WebMenu instance
|
|
- ``popup,willdelete``: The web object is ready to destroy the popup
|
|
object created. Event info is a WebMenu instance
|
|
- ``ready``: Page is fully loaded
|
|
- ``scrollbars,visible,get``: Queries visibility of scrollbars. Event
|
|
info is a bool where the visibility state should be set
|
|
- ``scrollbars,visible,set``: Informs scrollbars visibility. Event info
|
|
is an Eina_Bool with the visibility state set
|
|
- ``statusbar,text,set``: Text of the statusbar changed. Event info is
|
|
a string with the new text
|
|
- ``statusbar,visible,get``: Queries visibility of the status bar.
|
|
Event info is a bool where the visibility state should be
|
|
set.
|
|
- ``statusbar,visible,set``: Informs statusbar visibility. Event info is
|
|
an Eina_Bool with the visibility value
|
|
- ``title,changed``: Title of the main frame changed. Event info is a
|
|
string with the new title
|
|
- ``toolbars,visible,get``: Queries visibility of toolbars. Event info
|
|
is a bool where the visibility state should be set
|
|
- ``toolbars,visible,set``: Informs the visibility of toolbars. Event
|
|
info is an Eina_Bool with the visibility state
|
|
- ``tooltip,text,set``: Show and set text of a tooltip. Event info is
|
|
a string with the text to show
|
|
- ``uri,changed``: URI of the main frame changed. Event info is a string (deprecated. use ``url,changed`` instead)
|
|
- ``url,changed``: URL of the main frame changed. Event info is a string
|
|
with the new URI
|
|
- ``view,resized``: The web object internal's view changed sized
|
|
- ``windows,close,request``: A JavaScript request to close the current
|
|
window was requested
|
|
- ``zoom,animated,end``: Animated zoom finished
|
|
- ``focused`` : When the web has received focus. (since 1.8)
|
|
- ``unfocused`` : When the web has lost focus. (since 1.8)
|
|
|
|
available styles:
|
|
|
|
- ``default``
|
|
|
|
|
|
Enumerations
|
|
------------
|
|
|
|
.. _Elm_Web_Window_Feature:
|
|
|
|
Web window features
|
|
===================
|
|
|
|
.. data:: ELM_WEB_WINDOW_FEATURE_TOOLBAR
|
|
|
|
Toolbar
|
|
|
|
.. data:: ELM_WEB_WINDOW_FEATURE_STATUSBAR
|
|
|
|
Status bar
|
|
|
|
.. data:: ELM_WEB_WINDOW_FEATURE_SCROLLBARS
|
|
|
|
Scrollbars
|
|
|
|
.. data:: ELM_WEB_WINDOW_FEATURE_MENUBAR
|
|
|
|
Menu bar
|
|
|
|
.. data:: ELM_WEB_WINDOW_FEATURE_LOCATIONBAR
|
|
|
|
Location bar
|
|
|
|
.. data:: ELM_WEB_WINDOW_FEATURE_FULLSCREEN
|
|
|
|
Fullscreen
|
|
|
|
|
|
.. _Elm_Web_Zoom_Mode:
|
|
|
|
Web zoom modes
|
|
==============
|
|
|
|
.. data:: ELM_WEB_ZOOM_MODE_MANUAL
|
|
|
|
Zoom controlled normally by :py:attr:`~Web.zoom`
|
|
|
|
.. data:: ELM_WEB_ZOOM_MODE_AUTO_FIT
|
|
|
|
Zoom until content fits in web object.
|
|
|
|
.. data:: ELM_WEB_ZOOM_MODE_AUTO_FILL
|
|
|
|
Zoom until content fills web object.
|
|
|
|
"""
|
|
|
|
from cpython cimport PyUnicode_AsUTF8String
|
|
from libc.stdint cimport uintptr_t
|
|
|
|
from efl.eo cimport _object_mapping_register, object_from_instance
|
|
from efl.utils.deprecated cimport DEPRECATED
|
|
from efl.utils.conversions cimport _ctouni
|
|
from efl.evas cimport Object as evasObject
|
|
from object cimport Object
|
|
|
|
import traceback
|
|
|
|
cimport enums
|
|
|
|
ELM_WEB_WINDOW_FEATURE_TOOLBAR = enums.ELM_WEB_WINDOW_FEATURE_TOOLBAR
|
|
ELM_WEB_WINDOW_FEATURE_STATUSBAR = enums.ELM_WEB_WINDOW_FEATURE_STATUSBAR
|
|
ELM_WEB_WINDOW_FEATURE_SCROLLBARS = enums.ELM_WEB_WINDOW_FEATURE_SCROLLBARS
|
|
ELM_WEB_WINDOW_FEATURE_MENUBAR = enums.ELM_WEB_WINDOW_FEATURE_MENUBAR
|
|
ELM_WEB_WINDOW_FEATURE_LOCATIONBAR = enums.ELM_WEB_WINDOW_FEATURE_LOCATIONBAR
|
|
ELM_WEB_WINDOW_FEATURE_FULLSCREEN = enums.ELM_WEB_WINDOW_FEATURE_FULLSCREEN
|
|
|
|
ELM_WEB_ZOOM_MODE_MANUAL = enums.ELM_WEB_ZOOM_MODE_MANUAL
|
|
ELM_WEB_ZOOM_MODE_AUTO_FIT = enums.ELM_WEB_ZOOM_MODE_AUTO_FIT
|
|
ELM_WEB_ZOOM_MODE_AUTO_FILL = enums.ELM_WEB_ZOOM_MODE_AUTO_FILL
|
|
|
|
def _cb_string_conv(uintptr_t addr):
|
|
cdef const char *s = <const char *>addr
|
|
return _ctouni(s) if s is not NULL else None
|
|
|
|
def _cb_bool_conv(uintptr_t addr):
|
|
cdef Eina_Bool *info = <Eina_Bool *>addr
|
|
if info == NULL:
|
|
return None
|
|
return info[0]
|
|
|
|
def _web_double_conv(uintptr_t addr):
|
|
cdef double *info = <double *>addr
|
|
if info == NULL:
|
|
return None
|
|
return info[0]
|
|
|
|
def _web_load_frame_error_conv(uintptr_t addr):
|
|
cdef Elm_Web_Frame_Load_Error *err = <Elm_Web_Frame_Load_Error *>addr
|
|
if err == NULL:
|
|
return None
|
|
ret = {"code": err.code, "is_cancellation": bool(err.is_cancellation),
|
|
"domain": _ctouni(err.domain) if err.domain else None,
|
|
"description": _ctouni(err.description) if err.description else None,
|
|
"failing_url": _ctouni(err.failing_url) if err.failing_url else None,
|
|
"frame": object_from_instance(err.frame) if err.frame else None}
|
|
|
|
return ret
|
|
|
|
|
|
def _web_link_hover_in_conv(uintptr_t addr):
|
|
cdef char **info = <char **>addr
|
|
if info == NULL:
|
|
url = title = None
|
|
else:
|
|
url = None if info[0] == NULL else info[0]
|
|
title = None if info[1] == NULL else info[1]
|
|
return (url, title)
|
|
|
|
|
|
cdef void _web_console_message_hook(void *data, Evas_Object *obj, const char *message, unsigned int line_number, const char *source_id) with gil:
|
|
cdef Web self = <Web>data
|
|
|
|
try:
|
|
self._console_message_hook(self, _ctouni(message), line_number, _ctouni(source_id))
|
|
except Exception:
|
|
traceback.print_exc()
|
|
|
|
cdef class WebWindowFeatures(object):
|
|
|
|
cdef Elm_Web_Window_Features *wf
|
|
|
|
def property_get(self, Elm_Web_Window_Feature_Flag flag):
|
|
"""
|
|
|
|
Get boolean properties from Elm_Web_Window_Features
|
|
(such as statusbar, menubar, etc) that are on a window.
|
|
|
|
:param flag: The web window feature flag whose value is required.
|
|
|
|
:return: True if the flag is set, False otherwise
|
|
|
|
"""
|
|
return bool(elm_web_window_features_property_get(self.wf, flag))
|
|
|
|
property region:
|
|
"""
|
|
|
|
TODO : Add documentation.
|
|
|
|
:type: Tuple of ints (x, y, w, h)
|
|
|
|
"""
|
|
def __get__(self):
|
|
cdef Evas_Coord x, y, w, h
|
|
elm_web_window_features_region_get(self.wf, &x, &y, &w, &h)
|
|
return x, y, w, h
|
|
|
|
def ref(self):
|
|
"""
|
|
|
|
.. versionadded:: 1.8
|
|
|
|
"""
|
|
elm_web_window_features_ref(self.wf)
|
|
|
|
def unref(self):
|
|
"""
|
|
|
|
.. versionadded:: 1.8
|
|
|
|
"""
|
|
elm_web_window_features_unref(self.wf)
|
|
|
|
|
|
cdef class Web(Object):
|
|
"""
|
|
|
|
This class actually implements the widget.
|
|
|
|
"""
|
|
|
|
cdef object _console_message_hook
|
|
|
|
def __init__(self,evasObject parent, *args, **kwargs):
|
|
"""Web(...)
|
|
|
|
:param parent: The parent object
|
|
:type parent: :py:class:`efl.evas.Object`
|
|
:param \**kwargs: All the remaining keyword arguments are interpreted
|
|
as properties of the instance
|
|
|
|
"""
|
|
self._set_obj(elm_web_add(parent.obj))
|
|
self._set_properties_from_keyword_args(kwargs)
|
|
|
|
property zoom_mode:
|
|
"""The zoom mode to use
|
|
|
|
The modes can be any of those defined in ::Elm_Web_Zoom_Mode, except
|
|
::ELM_WEB_ZOOM_MODE_LAST. The default is ::ELM_WEB_ZOOM_MODE_MANUAL.
|
|
|
|
::ELM_WEB_ZOOM_MODE_MANUAL means the zoom level will be controlled
|
|
with the elm_web_zoom_set() function.
|
|
::ELM_WEB_ZOOM_MODE_AUTO_FIT will calculate the needed zoom level to
|
|
make sure the entirety of the web object's contents are shown.
|
|
::ELM_WEB_ZOOM_MODE_AUTO_FILL will calculate the needed zoom level to
|
|
fit the contents in the web object's size, without leaving any space
|
|
unused.
|
|
|
|
:type: :ref:`Elm_Web_Zoom_Mode`
|
|
|
|
"""
|
|
def __set__(self, Elm_Web_Zoom_Mode mode):
|
|
elm_web_zoom_mode_set(self.obj, mode)
|
|
|
|
def __get__(self):
|
|
return elm_web_zoom_mode_get(self.obj)
|
|
|
|
def zoom_mode_set(self, Elm_Web_Zoom_Mode mode):
|
|
elm_web_zoom_mode_set(self.obj, mode)
|
|
|
|
def zoom_mode_get(self):
|
|
return elm_web_zoom_mode_get(self.obj)
|
|
|
|
|
|
# TODO:
|
|
# property webkit_view:
|
|
# """
|
|
|
|
# Get internal ewk_view object from web object.
|
|
|
|
# Elementary may not provide some low level features of EWebKit,
|
|
# instead of cluttering the API with proxy methods we opted to
|
|
# return the internal reference. Be careful using it as it may
|
|
# interfere with elm_web behavior.
|
|
|
|
# :return: The internal ewk_view object or **None** if it does not
|
|
# exist. (Failure to create or Elementary compiled without
|
|
# ewebkit)
|
|
|
|
# :see: elm_web_add()
|
|
|
|
# """
|
|
# def __get__(self):
|
|
# return object_from_instance(elm_web_webkit_view_get(self.obj))
|
|
|
|
def webkit_view_get(self):
|
|
cdef Evas_Object *obj = elm_web_webkit_view_get(self.obj)
|
|
return object_from_instance(obj)
|
|
|
|
# TODO:
|
|
# def window_create_hook_set(self, func, func_data=None):
|
|
# """
|
|
|
|
# Sets the function to call when a new window is requested
|
|
|
|
# This hook will be called when a request to create a new window is
|
|
# issued from the web page loaded.
|
|
# There is no default implementation for this feature, so leaving this
|
|
# unset or passing **None** in @p func will prevent new windows from
|
|
# opening.
|
|
|
|
# :param func: The hook function to be called when a window is requested
|
|
# :param data: User data
|
|
|
|
# """
|
|
# elm_web_window_create_hook_set(self.obj,
|
|
# Elm_Web_Window_Open func,
|
|
# void *data)
|
|
|
|
# def dialog_alert_hook_set(self, func, func_data=None):
|
|
# """
|
|
|
|
# Sets the function to call when an alert dialog
|
|
|
|
# This hook will be called when a JavaScript alert dialog is requested.
|
|
# If no function is set or **None** is passed in @p func, the default
|
|
# implementation will take place.
|
|
|
|
# :param func: The callback function to be used
|
|
# :param data: User data
|
|
|
|
# :see: elm_web_inwin_mode_set()
|
|
|
|
# """
|
|
# elm_web_dialog_alert_hook_set(self.obj,
|
|
# Elm_Web_Dialog_Alert func,
|
|
# void *data)
|
|
|
|
# def dialog_confirm_hook_set(self, func, func_data=None):
|
|
# """
|
|
|
|
# Sets the function to call when an confirm dialog
|
|
|
|
# This hook will be called when a JavaScript confirm dialog is requested.
|
|
# If no function is set or **None** is passed in @p func, the default
|
|
# implementation will take place.
|
|
|
|
# :param func: The callback function to be used
|
|
# :param data: User data
|
|
|
|
# :see: elm_web_inwin_mode_set()
|
|
|
|
# """
|
|
# elm_web_dialog_confirm_hook_set(self.obj,
|
|
# Elm_Web_Dialog_Confirm func,
|
|
# void *data)
|
|
|
|
# def dialog_prompt_hook_set(self, func, func_data=None):
|
|
# """
|
|
|
|
# Sets the function to call when an prompt dialog
|
|
|
|
# This hook will be called when a JavaScript prompt dialog is requested.
|
|
# If no function is set or **None** is passed in @p func, the default
|
|
# implementation will take place.
|
|
|
|
# :param func: The callback function to be used
|
|
# :param data: User data
|
|
|
|
# :see: elm_web_inwin_mode_set()
|
|
|
|
# """
|
|
# elm_web_dialog_prompt_hook_set(self.obj,
|
|
# Elm_Web_Dialog_Prompt func,
|
|
# void *data)
|
|
|
|
# def dialog_file_selector_hook_set(self, func, func_data=None):
|
|
# """
|
|
|
|
# Sets the function to call when an file selector dialog
|
|
|
|
# This hook will be called when a JavaScript file selector dialog is
|
|
# requested.
|
|
# If no function is set or **None** is passed in @p func, the default
|
|
# implementation will take place.
|
|
|
|
# :param func: The callback function to be used
|
|
# :param data: User data
|
|
|
|
# :see: elm_web_inwin_mode_set()
|
|
|
|
# """
|
|
# elm_web_dialog_file_selector_hook_set(self.obj,
|
|
# Elm_Web_Dialog_File_Selector func,
|
|
# void *data)
|
|
|
|
def console_message_hook_set(self, func, func_data=None):
|
|
"""
|
|
|
|
Sets the function to call when a console message is emitted from JS
|
|
|
|
This hook will be called when a console message is emitted from
|
|
JavaScript. There is no default implementation for this feature.
|
|
|
|
:param func: The callback function to be used
|
|
:param data: User data
|
|
|
|
"""
|
|
self._console_message_hook = func
|
|
if func:
|
|
elm_web_console_message_hook_set(self.obj,
|
|
_web_console_message_hook,
|
|
<void *>self)
|
|
else:
|
|
elm_web_console_message_hook_set(self.obj, NULL, NULL)
|
|
|
|
property useragent:
|
|
"""
|
|
|
|
useragent of a elm_web object
|
|
|
|
:type: string
|
|
|
|
"""
|
|
def __set__(self, user_agent):
|
|
if isinstance(user_agent, unicode):
|
|
user_agent = PyUnicode_AsUTF8String(user_agent)
|
|
elm_web_useragent_set(self.obj, user_agent)
|
|
|
|
def __get__(self):
|
|
return _ctouni(elm_web_useragent_get(self.obj))
|
|
|
|
def useragent_set(self, user_agent):
|
|
if isinstance(user_agent, unicode):
|
|
user_agent = PyUnicode_AsUTF8String(user_agent)
|
|
elm_web_useragent_set(self.obj, user_agent)
|
|
|
|
def useragent_get(self):
|
|
return _ctouni(elm_web_useragent_get(self.obj))
|
|
|
|
# TODO: Not implemented in ewebkit2 backend (yet?)
|
|
# property tab_propagate:
|
|
# """Whether to use tab propagation
|
|
|
|
# If tab propagation is enabled, whenever the user presses the Tab key,
|
|
# Elementary will handle it and switch focus to the next widget.
|
|
# The default value is disabled, where WebKit will handle the Tab key to
|
|
# cycle focus though its internal objects, jumping to the next widget
|
|
# only when that cycle ends.
|
|
|
|
# :type: bool
|
|
|
|
# """
|
|
# def __get__(self):
|
|
# return bool(elm_web_tab_propagate_get(self.obj))
|
|
|
|
# def __set__(self, bint propagate):
|
|
# elm_web_tab_propagate_set(self.obj, propagate)
|
|
|
|
property url:
|
|
"""
|
|
|
|
The URL for the web object
|
|
|
|
It must be a full URL, with resource included, in the form
|
|
http://www.enlightenment.org or file:///tmp/something.html
|
|
|
|
The returned string must not be freed and is guaranteed to be
|
|
stringshared.
|
|
|
|
:type: string
|
|
|
|
:raise RuntimeError: if url could not be set
|
|
|
|
.. versionadded:: 1.8
|
|
|
|
"""
|
|
def __set__(self, url):
|
|
if isinstance(url, unicode): url = PyUnicode_AsUTF8String(url)
|
|
if not elm_web_url_set(self.obj, url):
|
|
raise RuntimeWarning("Cannot set url")
|
|
|
|
def __get__(self):
|
|
return _ctouni(elm_web_url_get(self.obj))
|
|
|
|
def url_set(self, url):
|
|
if isinstance(url, unicode): url = PyUnicode_AsUTF8String(url)
|
|
if not elm_web_url_set(self.obj, url):
|
|
raise RuntimeWarning("Cannot set url")
|
|
|
|
def url_get(self):
|
|
return _ctouni(elm_web_url_get(self.obj))
|
|
|
|
property uri:
|
|
"""
|
|
|
|
.. deprecated:: 1.8
|
|
Use property "url" instead.
|
|
|
|
"""
|
|
def __get__(self):
|
|
return self.uri_get()
|
|
|
|
def __set__(self, value):
|
|
self.uri_set(value)
|
|
|
|
@DEPRECATED("1.8", "Use property url instead.")
|
|
def uri_set(self, uri):
|
|
return bool(elm_web_url_set(self.obj, uri))
|
|
|
|
@DEPRECATED("1.8", "Use property url instead.")
|
|
def uri_get(self):
|
|
return _ctouni(elm_web_url_get(self.obj))
|
|
|
|
property title:
|
|
"""
|
|
|
|
Get the current title
|
|
|
|
The returned string must not be freed and is guaranteed to be
|
|
stringshared.
|
|
|
|
:type: string
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(elm_web_title_get(self.obj))
|
|
|
|
property bg_color:
|
|
"""
|
|
|
|
The background color to be used by the web object
|
|
|
|
This is the color that will be used by default when the loaded page
|
|
does not set it's own. Color values are pre-multiplied.
|
|
|
|
:param r: Red component
|
|
:param g: Green component
|
|
:param b: Blue component
|
|
:param a: Alpha component
|
|
|
|
"""
|
|
def __set__(self, value):
|
|
cdef int r, g, b, a
|
|
r, g, b, a = value
|
|
elm_web_bg_color_set(self.obj, r, g, b, a)
|
|
|
|
def __get__(self):
|
|
cdef int r, g, b, a
|
|
elm_web_bg_color_get(self.obj, &r, &g, &b, &a)
|
|
return r, g, b, a
|
|
|
|
property selection:
|
|
"""
|
|
|
|
Get a copy of the currently selected text
|
|
|
|
The string returned must be freed by the user when it's done with it.
|
|
|
|
:return: A newly allocated string, or **None** if nothing is selected or an
|
|
error occurred
|
|
|
|
"""
|
|
def __get__(self):
|
|
return _ctouni(elm_web_selection_get(self.obj))
|
|
|
|
def popup_selected_set(self, int index):
|
|
"""
|
|
|
|
Tells the web object which index in the currently open popup was selected
|
|
|
|
When the user handles the popup creation from the "popup,created" signal,
|
|
it needs to tell the web object which item was selected by calling this
|
|
function with the index corresponding to the item.
|
|
|
|
:param index: The index selected
|
|
|
|
:see: elm_web_popup_destroy()
|
|
|
|
"""
|
|
elm_web_popup_selected_set(self.obj, index)
|
|
|
|
def popup_destroy(self):
|
|
"""
|
|
|
|
Dismisses an open dropdown popup
|
|
|
|
When the popup from a dropdown widget is to be dismissed, either after
|
|
selecting an option or to cancel it, this function must be called, which
|
|
will later emit an "popup,willdelete" signal to notify the user that
|
|
any memory and objects related to this popup can be freed.
|
|
|
|
:return: **True** if the menu was successfully destroyed, or **False**
|
|
if there was no menu to destroy
|
|
|
|
"""
|
|
return bool(elm_web_popup_destroy(self.obj))
|
|
|
|
def text_search(self, string, bint case_sensitive, bint forward, bint wrap):
|
|
"""
|
|
|
|
Searches the given string in a document.
|
|
|
|
:param string: String to search
|
|
:param case_sensitive: If search should be case sensitive or not
|
|
:param forward: If search is from cursor and on or backwards
|
|
:param wrap: If search should wrap at the end
|
|
|
|
:return: **True** if the given string was found, **False** if not
|
|
or failure
|
|
|
|
"""
|
|
if isinstance(string, unicode): string = PyUnicode_AsUTF8String(string)
|
|
return bool(elm_web_text_search(self.obj,
|
|
string, case_sensitive, forward, wrap))
|
|
|
|
def text_matches_mark(self, string, bint case_sensitive, bint highlight,
|
|
unsigned int limit):
|
|
"""
|
|
|
|
Marks matches of the given string in a document.
|
|
|
|
:param string: String to match
|
|
:param case_sensitive: If match should be case sensitive or not
|
|
:param highlight: If matches should be highlighted
|
|
:param limit: Maximum amount of matches, or zero to unlimited
|
|
|
|
:return: number of matched @a string
|
|
|
|
"""
|
|
if isinstance(string, unicode): string = PyUnicode_AsUTF8String(string)
|
|
return elm_web_text_matches_mark(self.obj, string, case_sensitive, highlight, limit)
|
|
|
|
def text_matches_unmark_all(self):
|
|
"""
|
|
|
|
Clears all marked matches in the document
|
|
|
|
:return: **True** on success, **False** otherwise
|
|
|
|
"""
|
|
if not elm_web_text_matches_unmark_all(self.obj):
|
|
raise RuntimeWarning("Cannot clear marked matches")
|
|
|
|
property text_matches_highlight:
|
|
"""
|
|
|
|
Whether to highlight the matched marks
|
|
|
|
If enabled, marks set with elm_web_text_matches_mark() will be
|
|
highlighted.
|
|
|
|
:type: bool
|
|
|
|
"""
|
|
def __set__(self, bint highlight):
|
|
if not elm_web_text_matches_highlight_set(self.obj, highlight):
|
|
raise RuntimeWarning("Cannot set matched marks highlighting")
|
|
|
|
def __get__(self):
|
|
return bool(elm_web_text_matches_highlight_get(self.obj))
|
|
|
|
property load_progress:
|
|
"""
|
|
|
|
Get the overall loading progress of the page
|
|
|
|
Returns the estimated loading progress of the page, with a value
|
|
between 0.0 and 1.0. This is an estimated progress accounting for all
|
|
the frames included in the page.
|
|
|
|
:return: A value between 0.0 and 1.0 indicating the progress, or -1.0
|
|
on failure
|
|
|
|
"""
|
|
def __get__(self):
|
|
return elm_web_load_progress_get(self.obj)
|
|
|
|
def stop(self):
|
|
"""
|
|
|
|
Stops loading the current page
|
|
|
|
Cancels the loading of the current page in the web object. This will
|
|
cause a "load,error" signal to be emitted, with the is_cancellation
|
|
flag set to **True**.
|
|
|
|
:return: **True** if the cancel was successful, **False** otherwise
|
|
|
|
"""
|
|
if not elm_web_stop(self.obj):
|
|
raise RuntimeWarning("Cannot stop")
|
|
|
|
def reload(self):
|
|
"""
|
|
|
|
Requests a reload of the current document in the object
|
|
|
|
:return: **True** on success, **False** otherwise
|
|
|
|
"""
|
|
if not elm_web_reload(self.obj):
|
|
raise RuntimeWarning("Cannot reload")
|
|
|
|
def reload_full(self):
|
|
"""
|
|
|
|
Requests a reload of the current document, avoiding any existing caches
|
|
|
|
:return: **True** on success, **False** otherwise
|
|
|
|
"""
|
|
if not elm_web_reload_full(self.obj):
|
|
raise RuntimeWarning("Cannot reload without caches")
|
|
|
|
def back(self):
|
|
"""
|
|
|
|
Goes back one step in the browsing history
|
|
|
|
This is equivalent to calling elm_web_object_navigate(obj, -1);
|
|
|
|
:return: **True** on success, **False** otherwise
|
|
|
|
:see: elm_web_history_enabled_set()
|
|
:see: elm_web_back_possible()
|
|
:see: elm_web_forward()
|
|
:see: elm_web_navigate()
|
|
|
|
"""
|
|
if not elm_web_back(self.obj):
|
|
raise RuntimeWarning("Cannot go back")
|
|
|
|
def forward(self):
|
|
"""
|
|
|
|
Goes forward one step in the browsing history
|
|
|
|
This is equivalent to calling elm_web_object_navigate(obj, 1);
|
|
|
|
:return: **True** on success, **False** otherwise
|
|
|
|
:see: elm_web_history_enabled_set()
|
|
:see: elm_web_forward_possible_get()
|
|
:see: elm_web_back()
|
|
:see: elm_web_navigate()
|
|
|
|
"""
|
|
if not elm_web_forward(self.obj):
|
|
raise RuntimeWarning("Cannot go forward")
|
|
|
|
def navigate(self, int steps):
|
|
"""
|
|
|
|
Jumps the given number of steps in the browsing history
|
|
|
|
The @p steps value can be a negative integer to back in history, or a
|
|
positive to move forward.
|
|
|
|
:param steps: The number of steps to jump
|
|
|
|
:return: **True** on success, **False** on error or if not enough
|
|
history exists to jump the given number of steps
|
|
|
|
:see: elm_web_history_enabled_set()
|
|
:see: elm_web_back()
|
|
:see: elm_web_forward()
|
|
|
|
"""
|
|
return bool(elm_web_navigate(self.obj, steps))
|
|
|
|
property back_possible:
|
|
"""
|
|
|
|
Queries whether it's possible to go back in history
|
|
|
|
:return: **True** if it's possible to back in history, **False**
|
|
otherwise
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(elm_web_back_possible_get(self.obj))
|
|
|
|
property forward_possible:
|
|
"""
|
|
|
|
Queries whether it's possible to go forward in history
|
|
|
|
:return: **True** if it's possible to forward in history, **False**
|
|
otherwise
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(elm_web_forward_possible_get(self.obj))
|
|
|
|
def navigate_possible_get(self, int steps):
|
|
"""
|
|
|
|
Queries whether it's possible to jump the given number of steps
|
|
|
|
The @p steps value can be a negative integer to back in history, or a
|
|
positive to move forward.
|
|
:param steps: The number of steps to check for
|
|
|
|
:return: **True** if enough history exists to perform the given jump,
|
|
**False** otherwise
|
|
|
|
"""
|
|
return bool(elm_web_navigate_possible_get(self.obj, steps))
|
|
|
|
property history_enabled:
|
|
"""
|
|
|
|
Whether browsing history is enabled for the given object
|
|
|
|
:type: bool
|
|
|
|
"""
|
|
def __get__(self):
|
|
return bool(elm_web_history_enabled_get(self.obj))
|
|
|
|
def __set__(self, bint enabled):
|
|
elm_web_history_enabled_set(self.obj, enabled)
|
|
|
|
def history_enabled_get(self):
|
|
return bool(elm_web_history_enabled_get(self.obj))
|
|
|
|
def history_enabled_set(self, bint enabled):
|
|
elm_web_history_enabled_set(self.obj, enabled)
|
|
|
|
property zoom:
|
|
"""
|
|
|
|
Sets the zoom level of the web object
|
|
|
|
Zoom level matches the Webkit API, so 1.0 means normal zoom, with higher
|
|
values meaning zoom in and lower meaning zoom out. This function will
|
|
only affect the zoom level if the mode set with elm_web_zoom_mode_set()
|
|
is ::ELM_WEB_ZOOM_MODE_MANUAL.
|
|
|
|
Note that this is the zoom level set on the web object and not that
|
|
of the underlying Webkit one. In the ::ELM_WEB_ZOOM_MODE_MANUAL mode,
|
|
the two zoom levels should match, but for the other two modes the
|
|
Webkit zoom is calculated internally to match the chosen mode without
|
|
changing the zoom level set for the web object.
|
|
|
|
:type: float
|
|
|
|
"""
|
|
def __set__(self, double zoom):
|
|
elm_web_zoom_set(self.obj, zoom)
|
|
|
|
def __get__(self):
|
|
return elm_web_zoom_get(self.obj)
|
|
|
|
def zoom_set(self, double zoom):
|
|
elm_web_zoom_set(self.obj, zoom)
|
|
|
|
def zoom_get(self):
|
|
return elm_web_zoom_get(self.obj)
|
|
|
|
def region_show(self, int x, int y, int w, int h):
|
|
"""
|
|
|
|
Shows the given region in the web object
|
|
|
|
:param x: The x coordinate of the region to show
|
|
:param y: The y coordinate of the region to show
|
|
:param w: The width of the region to show
|
|
:param h: The height of the region to show
|
|
|
|
"""
|
|
elm_web_region_show(self.obj, x, y, w, h)
|
|
|
|
def region_bring_in(self, int x, int y, int w, int h):
|
|
"""
|
|
|
|
Brings in the region to the visible area
|
|
|
|
Like elm_web_region_show(), but it animates the scrolling of the object
|
|
to show the area
|
|
|
|
:param x: The x coordinate of the region to show
|
|
:param y: The y coordinate of the region to show
|
|
:param w: The width of the region to show
|
|
:param h: The height of the region to show
|
|
|
|
"""
|
|
elm_web_region_bring_in(self.obj, x, y, w, h)
|
|
|
|
property inwin_mode:
|
|
"""
|
|
|
|
Whether the default dialogs use an Inwin instead of a normal window
|
|
|
|
If set, then the default implementation for the JavaScript dialogs and
|
|
file selector will be opened in an Inwin. Otherwise they will use a
|
|
normal separated window.
|
|
|
|
:type: bool
|
|
|
|
"""
|
|
def __set__(self, bint value):
|
|
elm_web_inwin_mode_set(self.obj, value)
|
|
|
|
def __get__(self):
|
|
return bool(elm_web_inwin_mode_get(self.obj))
|
|
|
|
|
|
# TODO:
|
|
# def callback_download_request_add(self, func, *args, **kwargs):
|
|
# """A file download has been requested. Event info is a pointer to a
|
|
# Elm_Web_Download."""
|
|
# self._callback_add_full("download,request", _web_download_conv, func,
|
|
# *args, **kwargs)
|
|
|
|
# def callback_download_request_del(self, func):
|
|
# self._callback_del_full("download,request", _web_download_conv, func)
|
|
|
|
def callback_editorclient_contents_changed_add(self, func, *args, **kwargs):
|
|
"""Editor client's contents changed."""
|
|
self._callback_add("editorclient,contents,changed", func, *args, **kwargs)
|
|
|
|
def callback_editorclient_contents_changed_del(self, func):
|
|
self._callback_del("editorclient,contents,changed", func)
|
|
|
|
def callback_editorclient_selection_changed_add(self, func, *args, **kwargs):
|
|
"""Editor client's selection changed."""
|
|
self._callback_add("editorclient,selection,changed", func, *args, **kwargs)
|
|
|
|
def callback_editorclient_selection_changed_del(self, func):
|
|
self._callback_del("editorclient,selection,changed", func)
|
|
|
|
# TODO:
|
|
# def callback_frame_created_add(self, func, *args, **kwargs):
|
|
# """A new frame was created. Event info is an
|
|
# Evas_Object which can be handled with WebKit's ewk_frame API."""
|
|
# self._callback_add("frame,created", func, *args, **kwargs)
|
|
|
|
# def callback_frame_created_del(self, func):
|
|
# self._callback_del("frame,created", func)
|
|
|
|
def callback_icon_received_add(self, func, *args, **kwargs):
|
|
"""An icon was received by the main frame."""
|
|
self._callback_add("icon,received", func, *args, **kwargs)
|
|
|
|
def callback_icon_received_del(self, func):
|
|
self._callback_del("icon,received", func)
|
|
|
|
def callback_inputmethod_changed_add(self, func, *args, **kwargs):
|
|
"""Input method changed. Event info is an Eina_Bool indicating whether
|
|
it's enabled or not."""
|
|
self._callback_add_full("inputmethod,changed", _cb_bool_conv, func,
|
|
*args, **kwargs)
|
|
|
|
def callback_inputmethod_changed_del(self, func):
|
|
self._callback_del_full("inputmethod,changed", _cb_bool_conv, func)
|
|
|
|
def callback_js_windowobject_clear_add(self, func, *args, **kwargs):
|
|
"""JS window object has been cleared."""
|
|
self._callback_add("js,windowobject,clear", func, *args, **kwargs)
|
|
|
|
def callback_js_windowobject_clear_del(self, func):
|
|
self._callback_del("js,windowobject,clear", func)
|
|
|
|
def callback_link_hover_in_add(self, func, *args, **kwargs):
|
|
"""Mouse cursor is hovering over a link. Event info
|
|
is a tuple, where the first string contains the URL the link
|
|
points to, and the second one the title of the link."""
|
|
self._callback_add_full("link,hover,in", _web_link_hover_in_conv, func,
|
|
*args, **kwargs)
|
|
|
|
def callback_link_hover_in_del(self, func):
|
|
self._callback_del_full("link,hover,in", _web_link_hover_in_conv, func)
|
|
|
|
def callback_link_hover_out_add(self, func, *args, **kwargs):
|
|
"""Mouse cursor left the link."""
|
|
self._callback_add("link,hover,out", func, *args, **kwargs)
|
|
|
|
def callback_link_hover_out_del(self, func):
|
|
self._callback_del("link,hover,out", func)
|
|
|
|
# TODO:
|
|
# def callback_load_document_finished_add(self, func, *args, **kwargs):
|
|
# """Loading of a document finished. Event info
|
|
# is the frame that finished loading."""
|
|
# self._callback_add("load,document,finished", func, *args, **kwargs)
|
|
|
|
# def callback_load_document_finished_del(self, func):
|
|
# self._callback_del("load,document,finished", func)
|
|
|
|
def callback_load_error_add(self, func, *args, **kwargs):
|
|
"""Load failed. Event info is a WebFrameLoadError instance."""
|
|
self._callback_add_full("load,error", _web_load_frame_error_conv, func,
|
|
*args, **kwargs)
|
|
|
|
def callback_load_error_del(self, func):
|
|
self._callback_del_full("load,error", _web_load_frame_error_conv, func)
|
|
|
|
def callback_load_finished_add(self, func, *args, **kwargs):
|
|
"""Load finished. Event info is None on success, on error it's
|
|
a pointer to Elm_Web_Frame_Load_Error."""
|
|
self._callback_add_full("load,finished", _web_load_frame_error_conv, func, *args, **kwargs)
|
|
|
|
def callback_load_finished_del(self, func):
|
|
self._callback_del_full("load,finished", _web_load_frame_error_conv, func)
|
|
|
|
def callback_load_newwindow_show_add(self, func, *args, **kwargs):
|
|
"""A new window was created and is ready to be shown."""
|
|
self._callback_add("load,newwindow,show", func, *args, **kwargs)
|
|
|
|
def callback_load_newwindow_show_del(self, func):
|
|
self._callback_del("load,newwindow,show", func)
|
|
|
|
def callback_load_progress_add(self, func, *args, **kwargs):
|
|
"""Overall load progress. Event info is a double containing
|
|
a value between 0.0 and 1.0."""
|
|
self._callback_add_full("load,progress", _web_double_conv, func,
|
|
*args, **kwargs)
|
|
|
|
def callback_load_progress_del(self, func):
|
|
self._callback_del_full("load,progress", _web_double_conv, func)
|
|
|
|
def callback_load_provisional_add(self, func, *args, **kwargs):
|
|
"""Started provisional load."""
|
|
self._callback_add("load,provisional", func, *args, **kwargs)
|
|
|
|
def callback_load_provisional_del(self, func):
|
|
self._callback_del("load,provisional", func)
|
|
|
|
def callback_load_started_add(self, func, *args, **kwargs):
|
|
"""Loading of a document started."""
|
|
self._callback_add("load,started", func, *args, **kwargs)
|
|
|
|
def callback_load_started_del(self, func):
|
|
self._callback_del("load,started", func)
|
|
|
|
# def callback_menubar_visible_get_add(self, func, *args, **kwargs):
|
|
# """Queries if the menubar is visible. Event info
|
|
# is a bool where the callback should set True if
|
|
# the menubar is visible, or False in case it's not."""
|
|
# # XXX: the cb for this should use the return value, not the bool passed.
|
|
# self._callback_add_full("menubar,visible,get", _cb_bool_conv, func,
|
|
# *args, **kwargs)
|
|
|
|
# def callback_menubar_visible_get_del(self, func):
|
|
# self._callback_del_full("menubar,visible,get", _cb_bool_conv, func)
|
|
|
|
def callback_menubar_visible_set_add(self, func, *args, **kwargs):
|
|
"""Informs menubar visibility. Event info is
|
|
a bool indicating the visibility."""
|
|
self._callback_add_full("menubar,visible,set", _cb_bool_conv, func,
|
|
*args, **kwargs)
|
|
|
|
def callback_menubar_visible_set_del(self, func):
|
|
self._callback_del_full("menubar,visible,set", _cb_bool_conv, func)
|
|
|
|
# TODO:
|
|
# def callback_popup_created_add(self, func, *args, **kwargs):
|
|
# """A dropdown widget was activated, requesting its
|
|
# popup menu to be created. Event info is a pointer to Elm_Web_Menu."""
|
|
# self._callback_add("popup,created", func, *args, **kwargs)
|
|
|
|
# def callback_popup_created_del(self, func):
|
|
# self._callback_del("popup,created", func)
|
|
|
|
# def callback_popup_willdelete_add(self, func, *args, **kwargs):
|
|
# """The web object is ready to destroy the popup
|
|
# object created. Event info is a pointer to Elm_Web_Menu."""
|
|
# self._callback_add("popup,willdelete", func, *args, **kwargs)
|
|
|
|
# def callback_popup_willdelete_del(self, func):
|
|
# self._callback_del("popup,willdelete", func)
|
|
|
|
def callback_ready_add(self, func, *args, **kwargs):
|
|
"""Page is fully loaded."""
|
|
self._callback_add("ready", func, *args, **kwargs)
|
|
|
|
def callback_ready_del(self, func):
|
|
self._callback_del("ready", func)
|
|
|
|
# def callback_scrollbars_visible_get_add(self, func, *args, **kwargs):
|
|
# """Queries visibility of scrollbars. Event info is a bool where the
|
|
# visibility state should be set."""
|
|
# self._callback_add_full("scrollbars,visible,get", _cb_bool_conv, func,
|
|
# *args, **kwargs)
|
|
|
|
# def callback_scrollbars_visible_get_del(self, func):
|
|
# self._callback_del_full("scrollbars,visible,get", _cb_bool_conv, func)
|
|
|
|
def callback_scrollbars_visible_set_add(self, func, *args, **kwargs):
|
|
"""Informs scrollbars visibility. Event info
|
|
is a bool with the visibility state set."""
|
|
self._callback_add_full("scrollbars,visible,set", _cb_bool_conv, func,
|
|
*args, **kwargs)
|
|
|
|
def callback_scrollbars_visible_set_del(self, func):
|
|
self._callback_del_full("scrollbars,visible,set", _cb_bool_conv, func)
|
|
|
|
def callback_statusbar_text_set_add(self, func, *args, **kwargs):
|
|
"""Text of the statusbar changed. Event info is
|
|
a string with the new text."""
|
|
self._callback_add_full("statusbar,text,set", _cb_string_conv, func,
|
|
*args, **kwargs)
|
|
|
|
def callback_statusbar_text_set_del(self, func):
|
|
self._callback_del_full("statusbar,text,set", _cb_string_conv, func)
|
|
|
|
# def callback_statusbar_visible_get_add(self, func, *args, **kwargs):
|
|
# """Queries visibility of the status bar.
|
|
# Event info is a bool where the visibility state should
|
|
# be set."""
|
|
# self._callback_add_full("statusbar,visible,get", _cb_bool_conv, func,
|
|
# *args, **kwargs)
|
|
|
|
# def callback_statusbar_visible_get_del(self, func):
|
|
# self._callback_del_full("statusbar,visible,get", _cb_bool_conv, func)
|
|
|
|
def callback_statusbar_visible_set_add(self, func, *args, **kwargs):
|
|
"""Informs statusbar visibility. Event info is
|
|
a bool with the visibility value."""
|
|
self._callback_add_full("statusbar,visible,set", _cb_bool_conv, func,
|
|
*args, **kwargs)
|
|
|
|
def callback_statusbar_visible_set_del(self, func):
|
|
self._callback_del_full("statusbar,visible,set", _cb_bool_conv, func)
|
|
|
|
def callback_title_changed_add(self, func, *args, **kwargs):
|
|
"""Title of the main frame changed. Event info is a
|
|
string with the new title."""
|
|
self._callback_add_full("title,changed", _cb_string_conv, func, *args, **kwargs)
|
|
|
|
def callback_title_changed_del(self, func):
|
|
self._callback_del_full("title,changed", _cb_string_conv, func)
|
|
|
|
# def callback_toolbars_visible_get_add(self, func, *args, **kwargs):
|
|
# """Queries visibility of toolbars. Event info
|
|
# is a bool where the visibility state should be set."""
|
|
# self._callback_add_full("toolbars,visible,get", _cb_bool_conv, func,
|
|
# *args, **kwargs)
|
|
|
|
# def callback_toolbars_visible_get_del(self, func):
|
|
# self._callback_del_full("toolbars,visible,get", _cb_bool_conv, func)
|
|
|
|
def callback_toolbars_visible_set_add(self, func, *args, **kwargs):
|
|
"""Informs the visibility of toolbars. Event
|
|
info is a bool with the visibility state."""
|
|
self._callback_add_full("toolbars,visible,set", _cb_bool_conv, func,
|
|
*args, **kwargs)
|
|
|
|
def callback_toolbars_visible_set_del(self, func):
|
|
self._callback_del_full("toolbars,visible,set", func)
|
|
|
|
def callback_tooltip_text_set_add(self, func, *args, **kwargs):
|
|
"""Show and set text of a tooltip. Event info is
|
|
a string with the text to show."""
|
|
self._callback_add_full("tooltip,text,set", _cb_string_conv, func,
|
|
*args, **kwargs)
|
|
|
|
def callback_tooltip_text_set_del(self, func):
|
|
self._callback_del_full("tooltip,text,set", _cb_string_conv, func)
|
|
|
|
def callback_uri_changed_add(self, func, *args, **kwargs):
|
|
"""URI of the main frame changed. Event info is a string.
|
|
(deprecated. use "url,changed" instead)"""
|
|
self._callback_add_full("uri,changed", _cb_string_conv, func,
|
|
*args, **kwargs)
|
|
|
|
def callback_uri_changed_del(self, func):
|
|
self._callback_del_full("uri,changed", _cb_string_conv, func)
|
|
|
|
def callback_url_changed_add(self, func, *args, **kwargs):
|
|
"""URL of the main frame changed. Event info is a string
|
|
with the new URI."""
|
|
self._callback_add_full("url,changed", _cb_string_conv, func,
|
|
*args, **kwargs)
|
|
|
|
def callback_url_changed_del(self, func):
|
|
self._callback_del_full("url,changed", _cb_string_conv, func)
|
|
|
|
def callback_view_resized_add(self, func, *args, **kwargs):
|
|
"""The web object internal's view changed sized."""
|
|
self._callback_add("view,resized", func, *args, **kwargs)
|
|
|
|
def callback_view_resized_del(self, func):
|
|
self._callback_del("view,resized", func)
|
|
|
|
def callback_windows_close_request_add(self, func, *args, **kwargs):
|
|
"""A JavaScript request to close the current
|
|
window was requested."""
|
|
self._callback_add("windows,close,request", func, *args, **kwargs)
|
|
|
|
def callback_windows_close_request_del(self, func):
|
|
self._callback_del("windows,close,request", func)
|
|
|
|
def callback_zoom_animated_end_add(self, func, *args, **kwargs):
|
|
"""Animated zoom finished."""
|
|
self._callback_add("zoom,animated,end", func, *args, **kwargs)
|
|
|
|
def callback_zoom_animated_end_del(self, func):
|
|
self._callback_del("zoom,animated,end", func)
|
|
|
|
def callback_focused_add(self, func, *args, **kwargs):
|
|
"""When the web has received focus.
|
|
|
|
.. versionadded:: 1.8
|
|
|
|
"""
|
|
self._callback_add("focused", func, *args, **kwargs)
|
|
|
|
def callback_focused_del(self, func):
|
|
self._callback_del("focused", func)
|
|
|
|
def callback_unfocused_add(self, func, *args, **kwargs):
|
|
"""When the web has lost focus.
|
|
|
|
.. versionadded:: 1.8
|
|
|
|
"""
|
|
self._callback_add("unfocused", func, *args, **kwargs)
|
|
|
|
def callback_unfocused_del(self, func):
|
|
self._callback_del("unfocused", func)
|
|
|
|
|
|
_object_mapping_register("Elm_Web", Web)
|