summaryrefslogtreecommitdiff
path: root/efl/elementary/web.pyx
blob: c25b517a4bf5523f9832b14980c726f1f20fce12 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
# 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/>.
#

"""

:mod:`web` Module
#################


Widget description
==================

A web widget is used for displaying web pages (HTML/CSS/JS)
using WebKit-EFL. You must have compiled Elementary with
ewebkit support.


Emitted signals
===============

- ``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)


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.


Inheritance diagram
===================

.. inheritance-diagram:: efl.elementary.web
    :parts: 2

"""

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


cdef _cb_string_conv(void *addr):
    return _ctouni(<const char *>addr) if addr is not NULL else None


cdef _cb_bool_conv(void *addr):
    if addr == NULL:
        return None
    cdef Eina_Bool *ret = <Eina_Bool *>addr
    return <bint>ret[0]


cdef _web_double_conv(void *addr):
    if addr == NULL:
        return None
    cdef double *ret = <double *>addr
    return ret[0]


cdef _web_load_frame_error_conv(void *addr):
    cdef Elm_Web_Frame_Load_Error *err
    if addr == NULL:
        return None
    err = <Elm_Web_Frame_Load_Error *>addr
    return {"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}


cdef _web_link_hover_in_conv(void *addr):
    cdef char **info
    if addr == NULL:
        url = title = None
    else:
        info = <char **>addr
        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", _cb_bool_conv, 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)