summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--.qmake.conf2
-rw-r--r--examples/examples.pro2
-rw-r--r--examples/webengine/quicknanobrowser/ApplicationRoot.qml2
-rw-r--r--examples/webengine/quicknanobrowser/BrowserDialog.qml2
-rw-r--r--examples/webengine/quicknanobrowser/BrowserWindow.qml119
-rw-r--r--examples/webengine/quicknanobrowser/DownloadView.qml2
-rw-r--r--examples/webengine/quicknanobrowser/FullScreenNotification.qml99
-rw-r--r--examples/webengine/quicknanobrowser/doc/src/quicknanobrowser.qdoc2
-rw-r--r--examples/webengine/quicknanobrowser/quicknanobrowser.pro3
-rw-r--r--examples/webengine/quicknanobrowser/resources.qrc1
-rw-r--r--examples/webenginewidgets/browser/browser.rc1
-rw-r--r--examples/webenginewidgets/browser/networkaccessmanager.cpp160
-rw-r--r--examples/webenginewidgets/browser/networkaccessmanager.h75
-rw-r--r--examples/webenginewidgets/demobrowser/Info_mac.plist (renamed from examples/webenginewidgets/browser/Info_mac.plist)0
-rw-r--r--examples/webenginewidgets/demobrowser/addbookmarkdialog.ui (renamed from examples/webenginewidgets/browser/addbookmarkdialog.ui)0
-rw-r--r--examples/webenginewidgets/demobrowser/autosaver.cpp (renamed from examples/webenginewidgets/browser/autosaver.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/autosaver.h (renamed from examples/webenginewidgets/browser/autosaver.h)0
-rw-r--r--examples/webenginewidgets/demobrowser/bookmarks.cpp (renamed from examples/webenginewidgets/browser/bookmarks.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/bookmarks.h (renamed from examples/webenginewidgets/browser/bookmarks.h)0
-rw-r--r--examples/webenginewidgets/demobrowser/bookmarks.ui (renamed from examples/webenginewidgets/browser/bookmarks.ui)0
-rw-r--r--examples/webenginewidgets/demobrowser/browserapplication.cpp (renamed from examples/webenginewidgets/browser/browserapplication.cpp)110
-rw-r--r--examples/webenginewidgets/demobrowser/browserapplication.h (renamed from examples/webenginewidgets/browser/browserapplication.h)19
-rw-r--r--examples/webenginewidgets/demobrowser/browsermainwindow.cpp (renamed from examples/webenginewidgets/browser/browsermainwindow.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/browsermainwindow.h (renamed from examples/webenginewidgets/browser/browsermainwindow.h)0
-rw-r--r--examples/webenginewidgets/demobrowser/chasewidget.cpp (renamed from examples/webenginewidgets/browser/chasewidget.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/chasewidget.h (renamed from examples/webenginewidgets/browser/chasewidget.h)0
-rw-r--r--examples/webenginewidgets/demobrowser/cookiejar.cpp (renamed from examples/webenginewidgets/browser/cookiejar.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/cookiejar.h (renamed from examples/webenginewidgets/browser/cookiejar.h)0
-rw-r--r--examples/webenginewidgets/demobrowser/cookies.ui (renamed from examples/webenginewidgets/browser/cookies.ui)0
-rw-r--r--examples/webenginewidgets/demobrowser/cookiesexceptions.ui (renamed from examples/webenginewidgets/browser/cookiesexceptions.ui)0
-rw-r--r--examples/webenginewidgets/demobrowser/data/addtab.png (renamed from examples/webenginewidgets/browser/data/addtab.png)bin469 -> 469 bytes
-rw-r--r--examples/webenginewidgets/demobrowser/data/closetab.png (renamed from examples/webenginewidgets/browser/data/closetab.png)bin516 -> 516 bytes
-rw-r--r--examples/webenginewidgets/demobrowser/data/data.qrc (renamed from examples/webenginewidgets/browser/data/data.qrc)2
-rw-r--r--examples/webenginewidgets/demobrowser/data/defaultbookmarks.xbel (renamed from examples/webenginewidgets/browser/data/defaultbookmarks.xbel)0
-rw-r--r--examples/webenginewidgets/demobrowser/data/defaulticon.png (renamed from examples/webenginewidgets/browser/data/defaulticon.png)bin1473 -> 1473 bytes
-rw-r--r--examples/webenginewidgets/demobrowser/data/demobrowser.svg (renamed from examples/webenginewidgets/browser/data/browser.svg)3
-rw-r--r--examples/webenginewidgets/demobrowser/data/history.png (renamed from examples/webenginewidgets/browser/data/history.png)bin1527 -> 1527 bytes
-rw-r--r--examples/webenginewidgets/demobrowser/data/loading.gif (renamed from examples/webenginewidgets/browser/data/loading.gif)bin847 -> 847 bytes
-rw-r--r--examples/webenginewidgets/demobrowser/demobrowser.icns (renamed from examples/webenginewidgets/browser/browser.icns)bin50218 -> 50218 bytes
-rw-r--r--examples/webenginewidgets/demobrowser/demobrowser.ico (renamed from examples/webenginewidgets/browser/browser.ico)bin15374 -> 15374 bytes
-rw-r--r--examples/webenginewidgets/demobrowser/demobrowser.pro (renamed from examples/webenginewidgets/browser/browser.pro)18
-rw-r--r--examples/webenginewidgets/demobrowser/demobrowser.rc1
-rw-r--r--examples/webenginewidgets/demobrowser/doc/images/browser-demo.png (renamed from examples/webenginewidgets/browser/doc/images/browser-demo.png)bin156342 -> 156342 bytes
-rw-r--r--examples/webenginewidgets/demobrowser/doc/src/demobrowser.qdoc (renamed from examples/webenginewidgets/browser/doc/src/browser.qdoc)10
-rw-r--r--examples/webenginewidgets/demobrowser/downloaditem.ui (renamed from examples/webenginewidgets/browser/downloaditem.ui)0
-rw-r--r--examples/webenginewidgets/demobrowser/downloadmanager.cpp (renamed from examples/webenginewidgets/browser/downloadmanager.cpp)1
-rw-r--r--examples/webenginewidgets/demobrowser/downloadmanager.h (renamed from examples/webenginewidgets/browser/downloadmanager.h)0
-rw-r--r--examples/webenginewidgets/demobrowser/downloads.ui (renamed from examples/webenginewidgets/browser/downloads.ui)0
-rw-r--r--examples/webenginewidgets/demobrowser/edittableview.cpp (renamed from examples/webenginewidgets/browser/edittableview.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/edittableview.h (renamed from examples/webenginewidgets/browser/edittableview.h)0
-rw-r--r--examples/webenginewidgets/demobrowser/edittreeview.cpp (renamed from examples/webenginewidgets/browser/edittreeview.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/edittreeview.h (renamed from examples/webenginewidgets/browser/edittreeview.h)0
-rw-r--r--examples/webenginewidgets/demobrowser/featurepermissionbar.cpp (renamed from examples/webenginewidgets/browser/featurepermissionbar.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/featurepermissionbar.h (renamed from examples/webenginewidgets/browser/featurepermissionbar.h)0
-rw-r--r--examples/webenginewidgets/demobrowser/history.cpp (renamed from examples/webenginewidgets/browser/history.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/history.h (renamed from examples/webenginewidgets/browser/history.h)0
-rw-r--r--examples/webenginewidgets/demobrowser/history.ui (renamed from examples/webenginewidgets/browser/history.ui)0
-rw-r--r--examples/webenginewidgets/demobrowser/htmls/htmls.qrc (renamed from examples/webenginewidgets/browser/htmls/htmls.qrc)0
-rw-r--r--examples/webenginewidgets/demobrowser/htmls/notfound.html (renamed from examples/webenginewidgets/browser/htmls/notfound.html)0
-rw-r--r--examples/webenginewidgets/demobrowser/main.cpp (renamed from examples/webenginewidgets/browser/main.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/modelmenu.cpp (renamed from examples/webenginewidgets/browser/modelmenu.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/modelmenu.h (renamed from examples/webenginewidgets/browser/modelmenu.h)0
-rw-r--r--examples/webenginewidgets/demobrowser/passworddialog.ui (renamed from examples/webenginewidgets/browser/passworddialog.ui)0
-rw-r--r--examples/webenginewidgets/demobrowser/proxy.ui (renamed from examples/webenginewidgets/browser/proxy.ui)0
-rw-r--r--examples/webenginewidgets/demobrowser/searchlineedit.cpp (renamed from examples/webenginewidgets/browser/searchlineedit.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/searchlineedit.h (renamed from examples/webenginewidgets/browser/searchlineedit.h)0
-rw-r--r--examples/webenginewidgets/demobrowser/settings.cpp (renamed from examples/webenginewidgets/browser/settings.cpp)33
-rw-r--r--examples/webenginewidgets/demobrowser/settings.h (renamed from examples/webenginewidgets/browser/settings.h)3
-rw-r--r--examples/webenginewidgets/demobrowser/settings.ui (renamed from examples/webenginewidgets/browser/settings.ui)27
-rw-r--r--examples/webenginewidgets/demobrowser/squeezelabel.cpp (renamed from examples/webenginewidgets/browser/squeezelabel.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/squeezelabel.h (renamed from examples/webenginewidgets/browser/squeezelabel.h)0
-rw-r--r--examples/webenginewidgets/demobrowser/tabwidget.cpp (renamed from examples/webenginewidgets/browser/tabwidget.cpp)76
-rw-r--r--examples/webenginewidgets/demobrowser/tabwidget.h (renamed from examples/webenginewidgets/browser/tabwidget.h)7
-rw-r--r--examples/webenginewidgets/demobrowser/toolbarsearch.cpp (renamed from examples/webenginewidgets/browser/toolbarsearch.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/toolbarsearch.h (renamed from examples/webenginewidgets/browser/toolbarsearch.h)0
-rw-r--r--examples/webenginewidgets/demobrowser/urllineedit.cpp (renamed from examples/webenginewidgets/browser/urllineedit.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/urllineedit.h (renamed from examples/webenginewidgets/browser/urllineedit.h)0
-rw-r--r--examples/webenginewidgets/demobrowser/webview.cpp (renamed from examples/webenginewidgets/browser/webview.cpp)91
-rw-r--r--examples/webenginewidgets/demobrowser/webview.h (renamed from examples/webenginewidgets/browser/webview.h)2
-rw-r--r--examples/webenginewidgets/demobrowser/xbel.cpp (renamed from examples/webenginewidgets/browser/xbel.cpp)0
-rw-r--r--examples/webenginewidgets/demobrowser/xbel.h (renamed from examples/webenginewidgets/browser/xbel.h)0
-rw-r--r--examples/webenginewidgets/fancybrowser/doc/src/fancybrowser.qdoc22
m---------src/3rdparty0
-rw-r--r--src/core/api/core_api.pro56
-rw-r--r--src/core/api/qtwebenginecoreglobal.h50
-rw-r--r--src/core/api/qtwebenginecoreglobal_p.h (renamed from src/core/qtwebenginecoreglobal.h)31
-rw-r--r--src/core/api/qwebenginecallback.h92
-rw-r--r--src/core/api/qwebenginecallback_p.h232
-rw-r--r--src/core/api/qwebenginecookiestoreclient.cpp403
-rw-r--r--src/core/api/qwebenginecookiestoreclient.h104
-rw-r--r--src/core/api/qwebenginecookiestoreclient_p.h107
-rw-r--r--src/core/api/qwebengineurlrequestinfo.cpp277
-rw-r--r--src/core/api/qwebengineurlrequestinfo.h108
-rw-r--r--src/core/api/qwebengineurlrequestinfo_p.h78
-rw-r--r--src/core/api/qwebengineurlrequestinterceptor.h68
-rw-r--r--src/core/api/qwebengineurlrequestjob.cpp (renamed from src/webenginewidgets/api/qwebengineurlrequestjob.cpp)63
-rw-r--r--src/core/api/qwebengineurlrequestjob.h (renamed from src/webenginewidgets/api/qwebengineurlrequestjob_p.h)33
-rw-r--r--src/core/api/qwebengineurlschemehandler.cpp92
-rw-r--r--src/core/api/qwebengineurlschemehandler.h (renamed from src/webenginewidgets/api/qwebengineurlschemehandler_p.h)37
-rw-r--r--src/core/authentication_dialog_controller.cpp96
-rw-r--r--src/core/authentication_dialog_controller.h71
-rw-r--r--src/core/authentication_dialog_controller_p.h (renamed from src/core/custom_url_scheme_handler.cpp)37
-rw-r--r--src/core/browser_accessibility_qt.cpp80
-rw-r--r--src/core/browser_accessibility_qt.h12
-rw-r--r--src/core/browser_context_adapter.cpp82
-rw-r--r--src/core/browser_context_adapter.h34
-rw-r--r--src/core/browser_context_qt.cpp17
-rw-r--r--src/core/browser_context_qt.h7
-rw-r--r--src/core/chrome_qt.gyp2
-rw-r--r--src/core/chromium_gpu_helper.cpp8
-rw-r--r--src/core/chromium_gpu_helper.h9
-rw-r--r--src/core/chromium_overrides.cpp53
-rw-r--r--src/core/clipboard_qt.cpp4
-rw-r--r--src/core/clipboard_qt.h2
-rw-r--r--src/core/common/qt_messages.h3
-rw-r--r--src/core/config/desktop_linux.pri21
-rw-r--r--src/core/config/embedded_linux.pri19
-rw-r--r--src/core/config/linux.pri45
-rw-r--r--src/core/config/mac_osx.pri3
-rw-r--r--src/core/config/windows.pri14
-rw-r--r--src/core/content_browser_client_qt.cpp63
-rw-r--r--src/core/content_browser_client_qt.h27
-rw-r--r--src/core/content_client_qt.cpp108
-rw-r--r--src/core/content_client_qt.h4
-rw-r--r--src/core/content_main_delegate_qt.cpp2
-rw-r--r--src/core/cookie_monster_delegate_qt.cpp176
-rw-r--r--src/core/cookie_monster_delegate_qt.h89
-rw-r--r--src/core/core.pro13
-rw-r--r--src/core/core_common.pri2
-rw-r--r--src/core/core_gyp_generator.pro28
-rw-r--r--src/core/core_module.pro54
-rw-r--r--src/core/custom_protocol_handler.cpp2
-rw-r--r--src/core/custom_protocol_handler.h6
-rw-r--r--src/core/delegated_frame_node.cpp50
-rw-r--r--src/core/dev_tools_http_handler_delegate_qt.cpp123
-rw-r--r--src/core/dev_tools_http_handler_delegate_qt.h38
-rw-r--r--src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc8
-rw-r--r--src/core/doc/src/qtwebenginecore-index.qdoc104
-rw-r--r--src/core/doc/src/qtwebenginecore-module.qdoc44
-rw-r--r--src/core/file_picker_controller.cpp129
-rw-r--r--src/core/file_picker_controller.h81
-rw-r--r--src/core/gl_surface_qt.cpp17
-rw-r--r--src/core/gl_surface_qt.h4
-rw-r--r--src/core/gyp_run.pro92
-rw-r--r--src/core/javascript_dialog_manager_qt.cpp6
-rw-r--r--src/core/javascript_dialog_manager_qt.h5
-rw-r--r--src/core/location_provider_qt.cpp17
-rw-r--r--src/core/media_capture_devices_dispatcher.cpp11
-rw-r--r--src/core/network_delegate_qt.cpp154
-rw-r--r--src/core/network_delegate_qt.h35
-rw-r--r--src/core/ozone_platform_eglfs.cpp18
-rw-r--r--src/core/ozone_platform_eglfs.h5
-rw-r--r--src/core/permission_manager_qt.cpp211
-rw-r--r--src/core/permission_manager_qt.h119
-rw-r--r--src/core/proxy_config_service_qt.cpp173
-rw-r--r--src/core/proxy_config_service_qt.h87
-rw-r--r--src/core/qtwebengine.gypi6
-rw-r--r--src/core/qtwebengine_extras.gypi2
-rw-r--r--src/core/render_widget_host_view_qt.cpp70
-rw-r--r--src/core/render_widget_host_view_qt.h7
-rw-r--r--src/core/render_widget_host_view_qt_delegate.h1
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp14
-rw-r--r--src/core/renderer/content_renderer_client_qt.h2
-rw-r--r--src/core/renderer/pepper/pepper_flash_browser_host_qt.cpp134
-rw-r--r--src/core/renderer/pepper/pepper_flash_browser_host_qt.h91
-rw-r--r--src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp349
-rw-r--r--src/core/renderer/pepper/pepper_flash_renderer_host_qt.h105
-rw-r--r--src/core/renderer/pepper/pepper_host_factory_qt.cpp82
-rw-r--r--src/core/renderer/pepper/pepper_host_factory_qt.h70
-rw-r--r--src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp79
-rw-r--r--src/core/renderer/pepper/pepper_renderer_host_factory_qt.h73
-rw-r--r--src/core/renderer/qt_render_frame_observer.cpp65
-rw-r--r--src/core/renderer/qt_render_frame_observer.h (renamed from src/core/custom_url_scheme_handler.h)39
-rw-r--r--src/core/renderer/qt_render_view_observer.cpp6
-rw-r--r--src/core/renderer/qt_render_view_observer.h1
-rw-r--r--src/core/resource_dispatcher_host_delegate_qt.cpp87
-rw-r--r--src/core/resource_dispatcher_host_delegate_qt.h20
-rw-r--r--src/core/resources/resources.gyp4
-rw-r--r--src/core/type_conversion.h26
-rw-r--r--src/core/url_request_context_getter_qt.cpp106
-rw-r--r--src/core/url_request_context_getter_qt.h8
-rw-r--r--src/core/url_request_custom_job.cpp8
-rw-r--r--src/core/url_request_custom_job.h6
-rw-r--r--src/core/url_request_custom_job_delegate.cpp5
-rw-r--r--src/core/url_request_custom_job_delegate.h1
-rw-r--r--src/core/user_script.cpp11
-rw-r--r--src/core/user_script.h4
-rw-r--r--src/core/user_script_controller_host.cpp50
-rw-r--r--src/core/user_script_controller_host.h6
-rw-r--r--src/core/web_contents_adapter.cpp153
-rw-r--r--src/core/web_contents_adapter.h21
-rw-r--r--src/core/web_contents_adapter_client.h77
-rw-r--r--src/core/web_contents_delegate_qt.cpp81
-rw-r--r--src/core/web_contents_delegate_qt.h22
-rw-r--r--src/core/web_contents_view_qt.cpp41
-rw-r--r--src/core/web_contents_view_qt.h5
-rw-r--r--src/core/web_engine_context.cpp42
-rw-r--r--src/core/web_engine_context.h5
-rw-r--r--src/core/web_engine_library_info.cpp4
-rw-r--r--src/core/web_engine_settings.cpp4
-rw-r--r--src/core/web_engine_settings.h2
-rw-r--r--src/core/yuv_video_node.cpp175
-rw-r--r--src/core/yuv_video_node.h24
-rw-r--r--src/process/process.pro18
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem.cpp2
-rw-r--r--src/webengine/api/qquickwebenginehistory.cpp102
-rw-r--r--src/webengine/api/qquickwebenginenewviewrequest.cpp7
-rw-r--r--src/webengine/api/qquickwebenginenewviewrequest_p.h2
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp39
-rw-r--r--src/webengine/api/qquickwebengineprofile_p.h8
-rw-r--r--src/webengine/api/qquickwebenginesettings.cpp53
-rw-r--r--src/webengine/api/qquickwebenginesettings_p.h10
-rw-r--r--src/webengine/api/qquickwebenginesingleton.cpp36
-rw-r--r--src/webengine/api/qquickwebenginetestsupport_p.h4
-rw-r--r--src/webengine/api/qquickwebengineview.cpp371
-rw-r--r--src/webengine/api/qquickwebengineview_p.h77
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h15
-rw-r--r--src/webengine/api/qtwebengineglobal.cpp28
-rw-r--r--src/webengine/doc/images/qtwebengine-architecture.pngbin0 -> 11325 bytes
-rw-r--r--src/webengine/doc/qtwebengine.qdocconf47
-rw-r--r--src/webengine/doc/src/external-resources.qdoc48
-rw-r--r--src/webengine/doc/src/qtwebengine-devtools.qdoc58
-rw-r--r--src/webengine/doc/src/qtwebengine-examples.qdoc (renamed from src/webengine/doc/src/qtwebengine.qdoc)19
-rw-r--r--src/webengine/doc/src/qtwebengine-index.qdoc90
-rw-r--r--src/webengine/doc/src/qtwebengine-modules.qdoc45
-rw-r--r--src/webengine/doc/src/qtwebengine-overview.qdoc185
-rw-r--r--src/webengine/doc/src/qtwebengine-platform-notes.qdoc52
-rw-r--r--src/webengine/doc/src/qtwebengine-qmlmodule.qdoc39
-rw-r--r--src/webengine/doc/src/webengineview.qdoc (renamed from src/webengine/doc/src/qquickwebengineview_lgpl.qdoc)413
-rw-r--r--src/webengine/plugin/experimental/experimental.pro2
-rw-r--r--src/webengine/plugin/experimental/plugin.cpp6
-rw-r--r--src/webengine/plugin/plugin.cpp24
-rw-r--r--src/webengine/plugin/plugin.pro4
-rw-r--r--src/webengine/plugin/plugins.qmltypes99
-rw-r--r--src/webengine/plugin/testsupport/plugin.cpp2
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.cpp23
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.h2
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.h1
-rw-r--r--src/webengine/ui/AuthenticationDialog.qml105
-rw-r--r--src/webengine/ui/ui.pro2
-rw-r--r--src/webengine/ui_delegates_manager.cpp124
-rw-r--r--src/webengine/ui_delegates_manager.h32
-rw-r--r--src/webengine/webengine.pro6
-rw-r--r--src/webenginewidgets/api/qwebenginecertificateerror.h6
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem.h4
-rw-r--r--src/webenginewidgets/api/qwebenginefullscreenrequest.cpp59
-rw-r--r--src/webenginewidgets/api/qwebenginefullscreenrequest.h (renamed from src/webenginewidgets/api/qwebengineurlschemehandler_p_p.h)53
-rw-r--r--src/webenginewidgets/api/qwebenginehistory.cpp5
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp541
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h74
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h64
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp203
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.h27
-rw-r--r--src/webenginewidgets/api/qwebengineprofile_p.h7
-rw-r--r--src/webenginewidgets/api/qwebenginescript.cpp91
-rw-r--r--src/webenginewidgets/api/qwebenginescript.h7
-rw-r--r--src/webenginewidgets/api/qwebenginescriptcollection.cpp59
-rw-r--r--src/webenginewidgets/api/qwebenginescriptcollection.h10
-rw-r--r--src/webenginewidgets/api/qwebenginesettings.cpp4
-rw-r--r--src/webenginewidgets/api/qwebenginesettings.h4
-rw-r--r--src/webenginewidgets/api/qwebengineurlschemehandler.cpp119
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp9
-rw-r--r--src/webenginewidgets/api/qwebengineview.h3
-rw-r--r--src/webenginewidgets/doc/qtwebenginewidgets.qdocconf39
-rw-r--r--src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc38
-rw-r--r--src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc (renamed from src/webenginewidgets/doc/src/qtwebenginewidgets.qdoc)84
-rw-r--r--src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc48
-rw-r--r--src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc6
-rw-r--r--src/webenginewidgets/doc/src/qwebenginehistory_lgpl.qdoc46
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc205
-rw-r--r--src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc4
-rw-r--r--src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc119
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp16
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h2
-rw-r--r--src/webenginewidgets/webenginewidgets.pro15
-rw-r--r--sync.profile2
-rw-r--r--tests/auto/auto.pro2
-rw-r--r--tests/auto/core/core.pro7
-rw-r--r--tests/auto/core/qwebenginecookiestoreclient/qwebenginecookiestoreclient.pro1
-rw-r--r--tests/auto/core/qwebenginecookiestoreclient/resources/content.html5
-rw-r--r--tests/auto/core/qwebenginecookiestoreclient/resources/index.html38
-rw-r--r--tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp208
-rw-r--r--tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.qrc6
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro1
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/content.html5
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/firstparty.html5
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/index.html16
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp277
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc7
-rw-r--r--tests/auto/core/tests.pri17
-rw-r--r--tests/auto/quick/inspectorserver/tst_inspectorserver.cpp2
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp211
-rw-r--r--tests/auto/quick/qmltests/data/TestWebEngineView.qml9
-rw-r--r--tests/auto/quick/qmltests/data/confirmclose.html5
-rw-r--r--tests/auto/quick/qmltests/data/directoryupload.html16
-rw-r--r--tests/auto/quick/qmltests/data/forms.html40
-rw-r--r--tests/auto/quick/qmltests/data/multifileupload.html17
-rw-r--r--tests/auto/quick/qmltests/data/singlefileupload.html17
-rw-r--r--tests/auto/quick/qmltests/data/titleupdate.js55
-rw-r--r--tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml82
-rw-r--r--tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_favIconLoad.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_filePicker.qml129
-rw-r--r--tests/auto/quick/qmltests/data/tst_findText.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_formValidation.qml124
-rw-r--r--tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml35
-rw-r--r--tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_linkHovered.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadFail.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadHtml.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadProgress.qml23
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadProgressSignal.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadUrl.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_navigationHistory.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_navigationRequested.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_properties.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_runJavaScript.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_titleChanged.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_userScripts.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_webchannel.qml2
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/FilePicker.qml60
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/qmldir1
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml49
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/TestParams/qmldir1
-rw-r--r--tests/auto/quick/qmltests/qmltests.pro11
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp34
-rw-r--r--tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp2
-rw-r--r--tests/auto/widgets/qwebengineaccessibility/qwebengineaccessibility.pro1
-rw-r--r--tests/auto/widgets/qwebengineframe/qwebengineframe.pro2
-rw-r--r--tests/auto/widgets/qwebengineframe/tst_qwebengineframe.cpp1654
-rw-r--r--tests/auto/widgets/qwebengineframe/tst_qwebengineframe.qrc10
-rw-r--r--tests/auto/widgets/qwebenginehistory/qwebenginehistory.pro1
-rw-r--r--tests/auto/widgets/qwebenginehistoryinterface/qwebenginehistoryinterface.pro1
-rw-r--r--tests/auto/widgets/qwebengineinspector/qwebengineinspector.pro1
-rw-r--r--tests/auto/widgets/qwebenginepage/qwebenginepage.pro1
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/fullscreen.html10
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/image.png (renamed from tests/auto/widgets/qwebengineframe/resources/image.png)bin14743 -> 14743 bytes
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/style.css (renamed from tests/auto/widgets/qwebengineframe/resources/style.css)0
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/test1.html (renamed from tests/auto/widgets/qwebengineframe/resources/test1.html)0
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/test2.html (renamed from tests/auto/widgets/qwebengineframe/resources/test2.html)0
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/testiframe.html (renamed from tests/auto/widgets/qwebengineframe/resources/testiframe.html)0
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/testiframe2.html (renamed from tests/auto/widgets/qwebengineframe/resources/testiframe2.html)0
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp1785
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc9
-rw-r--r--tests/auto/widgets/qwebenginescript/qwebenginescript.pro1
-rw-r--r--tests/auto/widgets/qwebengineview/qwebengineview.pro1
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp3
-rw-r--r--tests/auto/widgets/tests.pri2
-rw-r--r--tests/auto/widgets/util.h5
-rw-r--r--tests/auto/widgets/widgets.pro1
-rw-r--r--tests/quicktestbrowser/ApplicationRoot.qml2
-rw-r--r--tests/quicktestbrowser/BrowserWindow.qml28
-rw-r--r--tests/quicktestbrowser/FullScreenNotification.qml99
-rw-r--r--tests/quicktestbrowser/main.cpp27
-rw-r--r--tests/quicktestbrowser/quicktestbrowser.pro3
-rw-r--r--tests/quicktestbrowser/resources.qrc1
-rwxr-xr-xtools/buildscripts/gyp_qtwebengine12
-rw-r--r--tools/qmake/config.tests/khr/khr.cpp4
-rw-r--r--tools/qmake/config.tests/khr/khr.pro4
-rw-r--r--tools/qmake/config.tests/snappy/snappy.cpp44
-rw-r--r--tools/qmake/config.tests/snappy/snappy.pro3
-rw-r--r--tools/qmake/config.tests/srtp/srtp.cpp43
-rw-r--r--tools/qmake/config.tests/srtp/srtp.pro3
-rw-r--r--tools/qmake/mkspecs/features/configure.prf90
-rw-r--r--tools/qmake/mkspecs/features/default_post.prf3
-rw-r--r--tools/qmake/mkspecs/features/default_pre.prf4
-rw-r--r--tools/qmake/mkspecs/features/functions.prf31
-rwxr-xr-xtools/scripts/take_snapshot.py63
-rw-r--r--tools/scripts/version_resolver.py7
372 files changed, 12790 insertions, 4542 deletions
diff --git a/.gitignore b/.gitignore
index d3e523f3a..9f362ff0f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,8 @@ src/3rdparty_upstream/ninja
src/3rdparty_upstream/chromium
src/core/Debug
src/core/Release
+src/core/api/Release
+src/core/api/Debug
src/core/core_generated.gyp
src/core/gypfiles
examples/webengine/quicknanobrowser/quicknanobrowser
diff --git a/.qmake.conf b/.qmake.conf
index 513fe9a0e..fe1cde075 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -2,4 +2,4 @@ QMAKEPATH += $$PWD/tools/qmake
load(qt_build_config)
CONFIG += qt_example_installs
-MODULE_VERSION = 5.5.1
+MODULE_VERSION = 5.6.0
diff --git a/examples/examples.pro b/examples/examples.pro
index 3d6872d55..8345fded6 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -6,6 +6,6 @@ qtHaveModule(webengine) {
qtHaveModule(webenginewidgets) {
SUBDIRS += \
- webenginewidgets/browser \
+ webenginewidgets/demobrowser \
webenginewidgets/fancybrowser
}
diff --git a/examples/webengine/quicknanobrowser/ApplicationRoot.qml b/examples/webengine/quicknanobrowser/ApplicationRoot.qml
index b409696be..91d1551a7 100644
--- a/examples/webengine/quicknanobrowser/ApplicationRoot.qml
+++ b/examples/webengine/quicknanobrowser/ApplicationRoot.qml
@@ -39,7 +39,7 @@
****************************************************************************/
import QtQuick 2.1
-import QtWebEngine 1.1
+import QtWebEngine 1.2
QtObject {
id: root
diff --git a/examples/webengine/quicknanobrowser/BrowserDialog.qml b/examples/webengine/quicknanobrowser/BrowserDialog.qml
index 6202d02f7..0577bf642 100644
--- a/examples/webengine/quicknanobrowser/BrowserDialog.qml
+++ b/examples/webengine/quicknanobrowser/BrowserDialog.qml
@@ -40,7 +40,7 @@
import QtQuick 2.1
import QtQuick.Window 2.2
-import QtWebEngine 1.1
+import QtWebEngine 1.2
Window {
property alias currentWebView: webView
diff --git a/examples/webengine/quicknanobrowser/BrowserWindow.qml b/examples/webengine/quicknanobrowser/BrowserWindow.qml
index c4c0270a4..3a8e8affc 100644
--- a/examples/webengine/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webengine/quicknanobrowser/BrowserWindow.qml
@@ -38,8 +38,8 @@
**
****************************************************************************/
-import QtQuick 2.1
-import QtWebEngine 1.1
+import QtQuick 2.2
+import QtWebEngine 1.2
import QtQuick.Controls 1.0
import QtQuick.Controls.Styles 1.0
import QtQuick.Layouts 1.0
@@ -59,8 +59,10 @@ ApplicationWindow {
// This is for the case where the system forces us to leave fullscreen.
if (currentWebView && !isFullScreen) {
currentWebView.state = ""
- if (currentWebView.isFullScreen)
+ if (currentWebView.isFullScreen) {
currentWebView.fullScreenCancelled()
+ fullScreenNotification.hide()
+ }
}
}
@@ -82,6 +84,8 @@ ApplicationWindow {
property alias autoLoadImages: loadImages.checked;
property alias javaScriptEnabled: javaScriptEnabled.checked;
property alias errorPageEnabled: errorPageEnabled.checked;
+ property alias pluginsEnabled: pluginsEnabled.checked;
+ property alias fullScreenSupportEnabled: fullScreenSupportEnabled.checked;
}
Action {
@@ -99,14 +103,14 @@ ApplicationWindow {
}
}
Action {
- shortcut: "Ctrl+R"
+ shortcut: StandardKey.Refresh
onTriggered: {
if (currentWebView)
currentWebView.reload()
}
}
Action {
- shortcut: "Ctrl+T"
+ shortcut: StandardKey.AddTab
onTriggered: {
tabs.createEmptyTab(currentWebView.profile)
tabs.currentIndex = tabs.count - 1
@@ -115,12 +119,9 @@ ApplicationWindow {
}
}
Action {
- shortcut: "Ctrl+W"
+ shortcut: StandardKey.Close
onTriggered: {
- if (tabs.count == 1)
- browserWindow.close()
- else
- tabs.removeTab(tabs.currentIndex)
+ currentWebView.triggerWebAction(WebEngineView.RequestClose);
}
}
Action {
@@ -135,14 +136,51 @@ ApplicationWindow {
onTriggered: currentWebView.zoomFactor = 1.0;
}
Action {
- shortcut: "Ctrl+-"
+ shortcut: StandardKey.ZoomOut
onTriggered: currentWebView.zoomFactor -= 0.1;
}
Action {
- shortcut: "Ctrl+="
+ shortcut: StandardKey.ZoomIn
onTriggered: currentWebView.zoomFactor += 0.1;
}
+ Action {
+ shortcut: StandardKey.Copy
+ onTriggered: currentWebView.triggerWebAction(WebEngineView.Copy)
+ }
+ Action {
+ shortcut: StandardKey.Cut
+ onTriggered: currentWebView.triggerWebAction(WebEngineView.Cut)
+ }
+ Action {
+ shortcut: StandardKey.Paste
+ onTriggered: currentWebView.triggerWebAction(WebEngineView.Paste)
+ }
+ Action {
+ shortcut: "Shift+"+StandardKey.Paste
+ onTriggered: currentWebView.triggerWebAction(WebEngineView.PasteAndMatchStyle)
+ }
+ Action {
+ shortcut: StandardKey.SelectAll
+ onTriggered: currentWebView.triggerWebAction(WebEngineView.SelectAll)
+ }
+ Action {
+ shortcut: StandardKey.Undo
+ onTriggered: currentWebView.triggerWebAction(WebEngineView.Undo)
+ }
+ Action {
+ shortcut: StandardKey.Redo
+ onTriggered: currentWebView.triggerWebAction(WebEngineView.Redo)
+ }
+ Action {
+ shortcut: StandardKey.Back
+ onTriggered: currentWebView.triggerWebAction(WebEngineView.Back)
+ }
+ Action {
+ shortcut: StandardKey.Forward
+ onTriggered: currentWebView.triggerWebAction(WebEngineView.Forward)
+ }
+
toolBar: ToolBar {
id: navigationBar
RowLayout {
@@ -230,6 +268,18 @@ ApplicationWindow {
checked: WebEngine.settings.errorPageEnabled
}
MenuItem {
+ id: pluginsEnabled
+ text: "Plugins On"
+ checkable: true
+ checked: WebEngine.settings.pluginsEnabled
+ }
+ MenuItem {
+ id: fullScreenSupportEnabled
+ text: "FullScreen On"
+ checkable: true
+ checked: WebEngine.settings.fullScreenSupportEnabled
+ }
+ MenuItem {
id: offTheRecordEnabled
text: "Off The Record"
checkable: true
@@ -312,6 +362,8 @@ ApplicationWindow {
settings.autoLoadImages: appSettings.autoLoadImages
settings.javascriptEnabled: appSettings.javaScriptEnabled
settings.errorPageEnabled: appSettings.errorPageEnabled
+ settings.pluginsEnabled: appSettings.pluginsEnabled
+ settings.fullScreenSupportEnabled: appSettings.fullScreenSupportEanbled
onCertificateError: {
error.defer()
@@ -342,12 +394,50 @@ ApplicationWindow {
webEngineView.state = "FullScreen"
browserWindow.previousVisibility = browserWindow.visibility
browserWindow.showFullScreen()
+ fullScreenNotification.show()
} else {
webEngineView.state = ""
browserWindow.visibility = browserWindow.previousVisibility
+ fullScreenNotification.hide()
}
request.accept()
}
+
+ onRenderProcessTerminated: {
+ var status = ""
+ switch (terminationStatus) {
+ case WebEngineView.NormalTerminationStatus:
+ status = "(normal exit)"
+ break;
+ case WebEngineView.AbnormalTerminationStatus:
+ status = "(abnormal exit)"
+ break;
+ case WebEngineView.CrashedTerminationStatus:
+ status = "(crashed)"
+ break;
+ case WebEngineView.KilledTerminationStatus:
+ status = "(killed)"
+ break;
+ }
+
+ print("Render process exited with code " + exitCode + " " + status)
+ reloadTimer.running = true
+ }
+
+ onWindowCloseRequested: {
+ if (tabs.count == 1)
+ browserWindow.close()
+ else
+ tabs.removeTab(tabs.currentIndex)
+ }
+
+ Timer {
+ id: reloadTimer
+ interval: 0
+ running: false
+ repeat: false
+ onTriggered: currentWebView.reload()
+ }
}
}
}
@@ -382,6 +472,11 @@ ApplicationWindow {
visible = certErrors.length > 0
}
}
+
+ FullScreenNotification {
+ id: fullScreenNotification
+ }
+
DownloadView {
id: downloadView
visible: false
diff --git a/examples/webengine/quicknanobrowser/DownloadView.qml b/examples/webengine/quicknanobrowser/DownloadView.qml
index 9a5cdd28f..c17a8bd60 100644
--- a/examples/webengine/quicknanobrowser/DownloadView.qml
+++ b/examples/webengine/quicknanobrowser/DownloadView.qml
@@ -41,7 +41,7 @@
import QtQuick 2.1
import QtQuick.Controls 1.0
import QtQuick.Controls.Styles 1.0
-import QtWebEngine 1.0
+import QtWebEngine 1.2
import QtQuick.Layouts 1.0
Rectangle {
diff --git a/examples/webengine/quicknanobrowser/FullScreenNotification.qml b/examples/webengine/quicknanobrowser/FullScreenNotification.qml
new file mode 100644
index 000000000..80a63d479
--- /dev/null
+++ b/examples/webengine/quicknanobrowser/FullScreenNotification.qml
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+
+Rectangle {
+ id: fullScreenNotification
+ width: 500
+ height: 40
+ color: "white"
+ radius: 7
+
+ visible: false
+ opacity: 0
+
+ function show() {
+ visible = true
+ opacity = 1
+ reset.start()
+ }
+
+ function hide() {
+ reset.stop()
+ opacity = 0
+ }
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: 750
+ onStopped: {
+ if (opacity == 0)
+ visible = false
+ }
+ }
+ }
+
+ Timer {
+ id: reset
+ interval: 5000
+ onTriggered: hide()
+ }
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: 125
+
+ Text {
+ id: message
+ width: parent.width
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ wrapMode: Text.WordWrap
+ elide: Text.ElideNone
+ clip: true
+
+ text: qsTr("You are now in fullscreen mode. Press ESC to quit!")
+ }
+}
diff --git a/examples/webengine/quicknanobrowser/doc/src/quicknanobrowser.qdoc b/examples/webengine/quicknanobrowser/doc/src/quicknanobrowser.qdoc
index 4fac9fe09..211951929 100644
--- a/examples/webengine/quicknanobrowser/doc/src/quicknanobrowser.qdoc
+++ b/examples/webengine/quicknanobrowser/doc/src/quicknanobrowser.qdoc
@@ -26,7 +26,7 @@
****************************************************************************/
/*!
- \example quicknanobrowser
+ \example webengine/quicknanobrowser
\title WebEngine Quick Nano Browser
\ingroup webengine-examples
\brief A web browser implemented using the WebEngineView QML type.
diff --git a/examples/webengine/quicknanobrowser/quicknanobrowser.pro b/examples/webengine/quicknanobrowser/quicknanobrowser.pro
index 1447af927..6cf556984 100644
--- a/examples/webengine/quicknanobrowser/quicknanobrowser.pro
+++ b/examples/webengine/quicknanobrowser/quicknanobrowser.pro
@@ -9,7 +9,8 @@ SOURCES = main.cpp
OTHER_FILES += ApplicationRoot.qml \
BrowserDialog.qml \
BrowserWindow.qml \
- DownloadView.qml
+ DownloadView.qml \
+ FullScreenNotification.qml
RESOURCES += resources.qrc
diff --git a/examples/webengine/quicknanobrowser/resources.qrc b/examples/webengine/quicknanobrowser/resources.qrc
index 28fd7b7dc..694f8d19b 100644
--- a/examples/webengine/quicknanobrowser/resources.qrc
+++ b/examples/webengine/quicknanobrowser/resources.qrc
@@ -4,6 +4,7 @@
<file>BrowserDialog.qml</file>
<file>BrowserWindow.qml</file>
<file>DownloadView.qml</file>
+ <file>FullScreenNotification.qml</file>
</qresource>
<qresource prefix="icons">
<file alias="go-next.png">icons/go-next.png</file>
diff --git a/examples/webenginewidgets/browser/browser.rc b/examples/webenginewidgets/browser/browser.rc
deleted file mode 100644
index 39e17e973..000000000
--- a/examples/webenginewidgets/browser/browser.rc
+++ /dev/null
@@ -1 +0,0 @@
-IDI_ICON1 ICON DISCARDABLE "browser.ico"
diff --git a/examples/webenginewidgets/browser/networkaccessmanager.cpp b/examples/webenginewidgets/browser/networkaccessmanager.cpp
deleted file mode 100644
index d2b4f827f..000000000
--- a/examples/webenginewidgets/browser/networkaccessmanager.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the demonstration applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "networkaccessmanager.h"
-
-#include "browserapplication.h"
-#include "browsermainwindow.h"
-
-#include <QtCore/QSettings>
-
-#include <QtGui/QDesktopServices>
-#include <QtWidgets/QDialog>
-#include <QtWidgets/QMessageBox>
-#include <QtWidgets/QStyle>
-#include <QtGui/QTextDocument>
-
-#include <QtNetwork/QAuthenticator>
-#include <QtNetwork/QNetworkDiskCache>
-#include <QtNetwork/QNetworkProxy>
-#include <QtNetwork/QNetworkRequest>
-#include <QtNetwork/QNetworkReply>
-#include <QtNetwork/QSslError>
-
-NetworkAccessManager::NetworkAccessManager(QObject *parent)
- : QNetworkAccessManager(parent),
- requestFinishedCount(0), requestFinishedFromCacheCount(0), requestFinishedPipelinedCount(0),
- requestFinishedSecureCount(0), requestFinishedDownloadBufferCount(0)
-{
- connect(this, SIGNAL(finished(QNetworkReply*)),
- SLOT(requestFinished(QNetworkReply*)));
-#ifndef QT_NO_OPENSSL
- connect(this, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
- SLOT(sslErrors(QNetworkReply*,QList<QSslError>)));
-#endif
- loadSettings();
-
- QNetworkDiskCache *diskCache = new QNetworkDiskCache(this);
- QString location = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
- diskCache->setCacheDirectory(location);
- setCache(diskCache);
-}
-
-QNetworkReply* NetworkAccessManager::createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData)
-{
- QNetworkRequest request = req; // copy so we can modify
- // this is a temporary hack until we properly use the pipelining flags from QtWebkit
- // pipeline everything! :)
- request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
- return QNetworkAccessManager::createRequest(op, request, outgoingData);
-}
-
-void NetworkAccessManager::requestFinished(QNetworkReply *reply)
-{
- requestFinishedCount++;
-
- if (reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool() == true)
- requestFinishedFromCacheCount++;
-
- if (reply->attribute(QNetworkRequest::HttpPipeliningWasUsedAttribute).toBool() == true)
- requestFinishedPipelinedCount++;
-
- if (reply->attribute(QNetworkRequest::ConnectionEncryptedAttribute).toBool() == true)
- requestFinishedSecureCount++;
-
- if (reply->attribute(QNetworkRequest::DownloadBufferAttribute).isValid() == true)
- requestFinishedDownloadBufferCount++;
-
- if (requestFinishedCount % 10)
- return;
-
-#ifdef QT_DEBUG
- double pctCached = (double(requestFinishedFromCacheCount) * 100.0/ double(requestFinishedCount));
- double pctPipelined = (double(requestFinishedPipelinedCount) * 100.0/ double(requestFinishedCount));
- double pctSecure = (double(requestFinishedSecureCount) * 100.0/ double(requestFinishedCount));
- double pctDownloadBuffer = (double(requestFinishedDownloadBufferCount) * 100.0/ double(requestFinishedCount));
-
- qDebug("STATS [%lli requests total] [%3.2f%% from cache] [%3.2f%% pipelined] [%3.2f%% SSL/TLS] [%3.2f%% Zerocopy]", requestFinishedCount, pctCached, pctPipelined, pctSecure, pctDownloadBuffer);
-#endif
-}
-
-void NetworkAccessManager::loadSettings()
-{
- QSettings settings;
- settings.beginGroup(QLatin1String("proxy"));
- QNetworkProxy proxy;
- if (settings.value(QLatin1String("enabled"), false).toBool()) {
- if (settings.value(QLatin1String("type"), 0).toInt() == 0)
- proxy = QNetworkProxy::Socks5Proxy;
- else
- proxy = QNetworkProxy::HttpProxy;
- proxy.setHostName(settings.value(QLatin1String("hostName")).toString());
- proxy.setPort(settings.value(QLatin1String("port"), 1080).toInt());
- proxy.setUser(settings.value(QLatin1String("userName")).toString());
- proxy.setPassword(settings.value(QLatin1String("password")).toString());
- }
- setProxy(proxy);
-}
-
-#ifndef QT_NO_OPENSSL
-void NetworkAccessManager::sslErrors(QNetworkReply *reply, const QList<QSslError> &error)
-{
- // check if SSL certificate has been trusted already
- QString replyHost = reply->url().host() + QString(":%1").arg(reply->url().port());
- if (! sslTrustedHostList.contains(replyHost)) {
- BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow();
-
- QStringList errorStrings;
- for (int i = 0; i < error.count(); ++i)
- errorStrings += error.at(i).errorString();
- QString errors = errorStrings.join(QLatin1String("\n"));
- int ret = QMessageBox::warning(mainWindow, QCoreApplication::applicationName(),
- tr("SSL Errors:\n\n%1\n\n%2\n\n"
- "Do you want to ignore these errors for this host?").arg(reply->url().toString()).arg(errors),
- QMessageBox::Yes | QMessageBox::No,
- QMessageBox::No);
- if (ret == QMessageBox::Yes) {
- reply->ignoreSslErrors();
- sslTrustedHostList.append(replyHost);
- }
- }
-}
-#endif
diff --git a/examples/webenginewidgets/browser/networkaccessmanager.h b/examples/webenginewidgets/browser/networkaccessmanager.h
deleted file mode 100644
index f3ee2d338..000000000
--- a/examples/webenginewidgets/browser/networkaccessmanager.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the demonstration applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef NETWORKACCESSMANAGER_H
-#define NETWORKACCESSMANAGER_H
-
-#include <QtNetwork/QNetworkAccessManager>
-#include <QtNetwork/QNetworkRequest>
-
-class NetworkAccessManager : public QNetworkAccessManager
-{
- Q_OBJECT
-
-public:
- NetworkAccessManager(QObject *parent = 0);
-
- virtual QNetworkReply* createRequest ( Operation op, const QNetworkRequest & req, QIODevice * outgoingData = 0 );
-
-private:
- QList<QString> sslTrustedHostList;
- qint64 requestFinishedCount;
- qint64 requestFinishedFromCacheCount;
- qint64 requestFinishedPipelinedCount;
- qint64 requestFinishedSecureCount;
- qint64 requestFinishedDownloadBufferCount;
-
-public slots:
- void loadSettings();
- void requestFinished(QNetworkReply *reply);
-
-private slots:
-#ifndef QT_NO_OPENSSL
- void sslErrors(QNetworkReply *reply, const QList<QSslError> &error);
-#endif
-};
-
-#endif // NETWORKACCESSMANAGER_H
diff --git a/examples/webenginewidgets/browser/Info_mac.plist b/examples/webenginewidgets/demobrowser/Info_mac.plist
index ccd4b3f28..ccd4b3f28 100644
--- a/examples/webenginewidgets/browser/Info_mac.plist
+++ b/examples/webenginewidgets/demobrowser/Info_mac.plist
diff --git a/examples/webenginewidgets/browser/addbookmarkdialog.ui b/examples/webenginewidgets/demobrowser/addbookmarkdialog.ui
index 3460d7bb8..3460d7bb8 100644
--- a/examples/webenginewidgets/browser/addbookmarkdialog.ui
+++ b/examples/webenginewidgets/demobrowser/addbookmarkdialog.ui
diff --git a/examples/webenginewidgets/browser/autosaver.cpp b/examples/webenginewidgets/demobrowser/autosaver.cpp
index dc72090dd..dc72090dd 100644
--- a/examples/webenginewidgets/browser/autosaver.cpp
+++ b/examples/webenginewidgets/demobrowser/autosaver.cpp
diff --git a/examples/webenginewidgets/browser/autosaver.h b/examples/webenginewidgets/demobrowser/autosaver.h
index b0c73846f..b0c73846f 100644
--- a/examples/webenginewidgets/browser/autosaver.h
+++ b/examples/webenginewidgets/demobrowser/autosaver.h
diff --git a/examples/webenginewidgets/browser/bookmarks.cpp b/examples/webenginewidgets/demobrowser/bookmarks.cpp
index 15078caa3..15078caa3 100644
--- a/examples/webenginewidgets/browser/bookmarks.cpp
+++ b/examples/webenginewidgets/demobrowser/bookmarks.cpp
diff --git a/examples/webenginewidgets/browser/bookmarks.h b/examples/webenginewidgets/demobrowser/bookmarks.h
index 244f003c6..244f003c6 100644
--- a/examples/webenginewidgets/browser/bookmarks.h
+++ b/examples/webenginewidgets/demobrowser/bookmarks.h
diff --git a/examples/webenginewidgets/browser/bookmarks.ui b/examples/webenginewidgets/demobrowser/bookmarks.ui
index c893e941d..c893e941d 100644
--- a/examples/webenginewidgets/browser/bookmarks.ui
+++ b/examples/webenginewidgets/demobrowser/bookmarks.ui
diff --git a/examples/webenginewidgets/browser/browserapplication.cpp b/examples/webenginewidgets/demobrowser/browserapplication.cpp
index ca28b2d0b..a85bce2c3 100644
--- a/examples/webenginewidgets/browser/browserapplication.cpp
+++ b/examples/webenginewidgets/demobrowser/browserapplication.cpp
@@ -46,7 +46,6 @@
#include "cookiejar.h"
#include "downloadmanager.h"
#include "history.h"
-#include "networkaccessmanager.h"
#include "tabwidget.h"
#include "webview.h"
@@ -64,6 +63,7 @@
#include <QtNetwork/QLocalServer>
#include <QtNetwork/QLocalSocket>
#include <QtNetwork/QNetworkProxy>
+#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QSslSocket>
#include <QWebEngineProfile>
@@ -191,25 +191,24 @@ BrowserApplication::~BrowserApplication()
delete s_bookmarksManager;
}
-#if defined(Q_OS_OSX)
void BrowserApplication::lastWindowClosed()
{
+#if defined(Q_OS_OSX)
clean();
BrowserMainWindow *mw = new BrowserMainWindow;
mw->slotHome();
m_mainWindows.prepend(mw);
-}
#endif
+}
BrowserApplication *BrowserApplication::instance()
{
return (static_cast<BrowserApplication *>(QCoreApplication::instance()));
}
-#if defined(Q_OS_OSX)
-#include <QtWidgets/QMessageBox>
void BrowserApplication::quitBrowser()
{
+#if defined(Q_OS_OSX)
clean();
int tabCount = 0;
for (int i = 0; i < m_mainWindows.count(); ++i) {
@@ -227,8 +226,8 @@ void BrowserApplication::quitBrowser()
}
exit(0);
-}
#endif
+}
/*!
Any actions that can be delayed until the window is visible
@@ -243,7 +242,7 @@ void BrowserApplication::postLaunch()
QWebEngineSettings::setOfflineStoragePath(directory);
#endif
- setWindowIcon(QIcon(QLatin1String(":browser.svg")));
+ setWindowIcon(QIcon(QLatin1String(":demobrowser.svg")));
loadSettings();
@@ -283,14 +282,15 @@ void BrowserApplication::loadSettings()
defaultSettings->setAttribute(QWebEngineSettings::JavascriptEnabled, settings.value(QLatin1String("enableJavascript"), true).toBool());
defaultSettings->setAttribute(QWebEngineSettings::ScrollAnimatorEnabled, settings.value(QLatin1String("enableScrollAnimator"), true).toBool());
-#if defined(QTWEBENGINE_PLUGINS)
defaultSettings->setAttribute(QWebEngineSettings::PluginsEnabled, settings.value(QLatin1String("enablePlugins"), true).toBool());
-#endif
+
+ defaultSettings->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true);
QString css = settings.value(QLatin1String("userStyleSheet")).toString();
setUserStyleSheet(defaultProfile, css, mainWindow());
defaultProfile->setHttpUserAgent(settings.value(QLatin1String("httpUserAgent")).toString());
+ defaultProfile->setHttpAcceptLanguage(settings.value(QLatin1String("httpAcceptLanguage")).toString());
settings.endGroup();
settings.beginGroup(QLatin1String("cookies"));
@@ -300,6 +300,21 @@ void BrowserApplication::loadSettings()
defaultProfile->setPersistentStoragePath(pdataPath);
settings.endGroup();
+
+ settings.beginGroup(QLatin1String("proxy"));
+ QNetworkProxy proxy;
+ if (settings.value(QLatin1String("enabled"), false).toBool()) {
+ if (settings.value(QLatin1String("type"), 0).toInt() == 0)
+ proxy = QNetworkProxy::Socks5Proxy;
+ else
+ proxy = QNetworkProxy::HttpProxy;
+ proxy.setHostName(settings.value(QLatin1String("hostName")).toString());
+ proxy.setPort(settings.value(QLatin1String("port"), 1080).toInt());
+ proxy.setUser(settings.value(QLatin1String("userName")).toString());
+ proxy.setPassword(settings.value(QLatin1String("password")).toString());
+ }
+ QNetworkProxy::setApplicationProxy(proxy);
+ settings.endGroup();
}
QList<BrowserMainWindow*> BrowserApplication::mainWindows()
@@ -475,18 +490,14 @@ DownloadManager *BrowserApplication::downloadManager()
QNetworkAccessManager *BrowserApplication::networkAccessManager()
{
-#if defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- if (!s_networkAccessManager) {
- s_networkAccessManager = new NetworkAccessManager();
- s_networkAccessManager->setCookieJar(new CookieJar);
- }
- return s_networkAccessManager;
-#else
if (!s_networkAccessManager) {
s_networkAccessManager = new QNetworkAccessManager();
+ connect(s_networkAccessManager, &QNetworkAccessManager::authenticationRequired,
+ BrowserApplication::instance(), &BrowserApplication::authenticationRequired);
+ connect(s_networkAccessManager, &QNetworkAccessManager::proxyAuthenticationRequired,
+ BrowserApplication::instance(), &BrowserApplication::proxyAuthenticationRequired);
}
return s_networkAccessManager;
-#endif
}
HistoryManager *BrowserApplication::historyManager()
@@ -543,3 +554,68 @@ void BrowserApplication::setPrivateBrowsing(bool privateBrowsing)
}
emit privateBrowsingChanged(privateBrowsing);
}
+
+void BrowserApplication::setLastAuthenticator(QAuthenticator *authenticator)
+{
+ m_lastAuthenticator = QAuthenticator(*authenticator);
+}
+
+void BrowserApplication::setLastProxyAuthenticator(QAuthenticator *authenticator)
+{
+ m_lastProxyAuthenticator = QAuthenticator(*authenticator);
+}
+
+void BrowserApplication::authenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator)
+{
+ if (m_lastAuthenticator.isNull())
+ return;
+
+
+ Q_ASSERT(m_lastAuthenticator.option("key").isValid());
+ QByteArray lastKey = m_lastAuthenticator.option("key").toByteArray();
+ QByteArray key = BrowserApplication::authenticationKey(reply->url(), authenticator->realm());
+
+ if (lastKey == key)
+ *authenticator = m_lastAuthenticator;
+}
+
+void BrowserApplication::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
+{
+ if (m_lastProxyAuthenticator.isNull())
+ return;
+
+ QNetworkProxy::ProxyType proxyType = proxy.type();
+ if (proxyType != QNetworkProxy::HttpProxy || proxyType != QNetworkProxy::HttpCachingProxy)
+ return;
+
+ Q_ASSERT(m_lastProxyAuthenticator.option("host").isValid());
+ QByteArray lastKey = m_lastProxyAuthenticator.option("key").toByteArray();
+ QByteArray key = BrowserApplication::proxyAuthenticationKey(proxy, authenticator->realm());
+
+ if (lastKey == key)
+ *authenticator = m_lastAuthenticator;
+}
+
+// TODO: Remove these functions (QTBUG-47967)
+QByteArray BrowserApplication::authenticationKey(const QUrl &url, const QString &realm)
+{
+ QUrl copy = url;
+ copy.setFragment(realm);
+ return "auth:" + copy.toEncoded(QUrl::RemovePassword | QUrl::RemovePath | QUrl::RemoveQuery);
+}
+
+QByteArray BrowserApplication::proxyAuthenticationKey(const QNetworkProxy &proxy, const QString &realm)
+{
+ QString host = QString("%1:%2").arg(proxy.hostName()).arg(proxy.port());
+ return BrowserApplication::proxyAuthenticationKey(proxy.user(), host, realm);
+}
+
+QByteArray BrowserApplication::proxyAuthenticationKey(const QString &user, const QString &host, const QString &realm)
+{
+ QUrl key;
+ key.setScheme(QLatin1String("proxy-http"));
+ key.setUserName(user);
+ key.setHost(host);
+ key.setFragment(realm);
+ return "auth:" + key.toEncoded();
+}
diff --git a/examples/webenginewidgets/browser/browserapplication.h b/examples/webenginewidgets/demobrowser/browserapplication.h
index 26557b8f9..75ae57c64 100644
--- a/examples/webenginewidgets/browser/browserapplication.h
+++ b/examples/webenginewidgets/demobrowser/browserapplication.h
@@ -49,9 +49,13 @@
#include <QtGui/QIcon>
+#include <QtNetwork/QAuthenticator>
+
QT_BEGIN_NAMESPACE
class QLocalServer;
class QNetworkAccessManager;
+class QNetworkProxy;
+class QNetworkReply;
class QWebEngineProfile;
QT_END_NAMESPACE
@@ -80,6 +84,14 @@ public:
bool canRestoreSession() const;
bool privateBrowsing() const { return m_privateBrowsing; }
+ void setLastAuthenticator(QAuthenticator *);
+ void setLastProxyAuthenticator(QAuthenticator *);
+
+ // TODO: Remove these functions (QTBUG-47967)
+ static QByteArray authenticationKey(const QUrl &, const QString &);
+ static QByteArray proxyAuthenticationKey(const QNetworkProxy &, const QString &);
+ static QByteArray proxyAuthenticationKey(const QString &, const QString &, const QString &);
+
static HistoryManager *historyManager();
static CookieJar *cookieJar();
static DownloadManager *downloadManager();
@@ -93,11 +105,11 @@ public:
public slots:
BrowserMainWindow *newMainWindow();
void restoreLastSession();
-#if defined(Q_OS_OSX)
void lastWindowClosed();
void quitBrowser();
-#endif
void setPrivateBrowsing(bool);
+ void authenticationRequired(QNetworkReply *, QAuthenticator *);
+ void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *);
signals:
void privateBrowsingChanged(bool);
@@ -122,6 +134,9 @@ private:
QWebEngineProfile *m_privateProfile;
bool m_privateBrowsing;
mutable QIcon m_defaultIcon;
+
+ QAuthenticator m_lastAuthenticator;
+ QAuthenticator m_lastProxyAuthenticator;
};
#endif // BROWSERAPPLICATION_H
diff --git a/examples/webenginewidgets/browser/browsermainwindow.cpp b/examples/webenginewidgets/demobrowser/browsermainwindow.cpp
index 9595ca7ba..9595ca7ba 100644
--- a/examples/webenginewidgets/browser/browsermainwindow.cpp
+++ b/examples/webenginewidgets/demobrowser/browsermainwindow.cpp
diff --git a/examples/webenginewidgets/browser/browsermainwindow.h b/examples/webenginewidgets/demobrowser/browsermainwindow.h
index a2bbc443f..a2bbc443f 100644
--- a/examples/webenginewidgets/browser/browsermainwindow.h
+++ b/examples/webenginewidgets/demobrowser/browsermainwindow.h
diff --git a/examples/webenginewidgets/browser/chasewidget.cpp b/examples/webenginewidgets/demobrowser/chasewidget.cpp
index fb0e9ce76..fb0e9ce76 100644
--- a/examples/webenginewidgets/browser/chasewidget.cpp
+++ b/examples/webenginewidgets/demobrowser/chasewidget.cpp
diff --git a/examples/webenginewidgets/browser/chasewidget.h b/examples/webenginewidgets/demobrowser/chasewidget.h
index a90389034..a90389034 100644
--- a/examples/webenginewidgets/browser/chasewidget.h
+++ b/examples/webenginewidgets/demobrowser/chasewidget.h
diff --git a/examples/webenginewidgets/browser/cookiejar.cpp b/examples/webenginewidgets/demobrowser/cookiejar.cpp
index d9a7465ca..d9a7465ca 100644
--- a/examples/webenginewidgets/browser/cookiejar.cpp
+++ b/examples/webenginewidgets/demobrowser/cookiejar.cpp
diff --git a/examples/webenginewidgets/browser/cookiejar.h b/examples/webenginewidgets/demobrowser/cookiejar.h
index 374156e89..374156e89 100644
--- a/examples/webenginewidgets/browser/cookiejar.h
+++ b/examples/webenginewidgets/demobrowser/cookiejar.h
diff --git a/examples/webenginewidgets/browser/cookies.ui b/examples/webenginewidgets/demobrowser/cookies.ui
index c4bccc548..c4bccc548 100644
--- a/examples/webenginewidgets/browser/cookies.ui
+++ b/examples/webenginewidgets/demobrowser/cookies.ui
diff --git a/examples/webenginewidgets/browser/cookiesexceptions.ui b/examples/webenginewidgets/demobrowser/cookiesexceptions.ui
index 3d9ef6241..3d9ef6241 100644
--- a/examples/webenginewidgets/browser/cookiesexceptions.ui
+++ b/examples/webenginewidgets/demobrowser/cookiesexceptions.ui
diff --git a/examples/webenginewidgets/browser/data/addtab.png b/examples/webenginewidgets/demobrowser/data/addtab.png
index 20928fb40..20928fb40 100644
--- a/examples/webenginewidgets/browser/data/addtab.png
+++ b/examples/webenginewidgets/demobrowser/data/addtab.png
Binary files differ
diff --git a/examples/webenginewidgets/browser/data/closetab.png b/examples/webenginewidgets/demobrowser/data/closetab.png
index ab9d669ee..ab9d669ee 100644
--- a/examples/webenginewidgets/browser/data/closetab.png
+++ b/examples/webenginewidgets/demobrowser/data/closetab.png
Binary files differ
diff --git a/examples/webenginewidgets/browser/data/data.qrc b/examples/webenginewidgets/demobrowser/data/data.qrc
index c7d0294c1..5cb8a97c0 100644
--- a/examples/webenginewidgets/browser/data/data.qrc
+++ b/examples/webenginewidgets/demobrowser/data/data.qrc
@@ -3,7 +3,7 @@
<file>addtab.png</file>
<file>closetab.png</file>
<file>history.png</file>
- <file>browser.svg</file>
+ <file>demobrowser.svg</file>
<file>defaultbookmarks.xbel</file>
<file>loading.gif</file>
<file>defaulticon.png</file>
diff --git a/examples/webenginewidgets/browser/data/defaultbookmarks.xbel b/examples/webenginewidgets/demobrowser/data/defaultbookmarks.xbel
index fef7f5514..fef7f5514 100644
--- a/examples/webenginewidgets/browser/data/defaultbookmarks.xbel
+++ b/examples/webenginewidgets/demobrowser/data/defaultbookmarks.xbel
diff --git a/examples/webenginewidgets/browser/data/defaulticon.png b/examples/webenginewidgets/demobrowser/data/defaulticon.png
index 01a0920c9..01a0920c9 100644
--- a/examples/webenginewidgets/browser/data/defaulticon.png
+++ b/examples/webenginewidgets/demobrowser/data/defaulticon.png
Binary files differ
diff --git a/examples/webenginewidgets/browser/data/browser.svg b/examples/webenginewidgets/demobrowser/data/demobrowser.svg
index 2127a0a6e..f61a54c67 100644
--- a/examples/webenginewidgets/browser/data/browser.svg
+++ b/examples/webenginewidgets/demobrowser/data/demobrowser.svg
@@ -14,11 +14,10 @@
id="svg2160"
sodipodi:version="0.32"
inkscape:version="0.46"
- inkscape:export-filename="c:\icons\qtbrowser48.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
sodipodi:docbase="C:\icons"
- sodipodi:docname="browser.svg"
+ sodipodi:docname="demobrowser.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2162"><linearGradient
diff --git a/examples/webenginewidgets/browser/data/history.png b/examples/webenginewidgets/demobrowser/data/history.png
index 552a1cbd8..552a1cbd8 100644
--- a/examples/webenginewidgets/browser/data/history.png
+++ b/examples/webenginewidgets/demobrowser/data/history.png
Binary files differ
diff --git a/examples/webenginewidgets/browser/data/loading.gif b/examples/webenginewidgets/demobrowser/data/loading.gif
index c1545eb0e..c1545eb0e 100644
--- a/examples/webenginewidgets/browser/data/loading.gif
+++ b/examples/webenginewidgets/demobrowser/data/loading.gif
Binary files differ
diff --git a/examples/webenginewidgets/browser/browser.icns b/examples/webenginewidgets/demobrowser/demobrowser.icns
index f591ae48a..f591ae48a 100644
--- a/examples/webenginewidgets/browser/browser.icns
+++ b/examples/webenginewidgets/demobrowser/demobrowser.icns
Binary files differ
diff --git a/examples/webenginewidgets/browser/browser.ico b/examples/webenginewidgets/demobrowser/demobrowser.ico
index 7f9be934d..7f9be934d 100644
--- a/examples/webenginewidgets/browser/browser.ico
+++ b/examples/webenginewidgets/demobrowser/demobrowser.ico
Binary files differ
diff --git a/examples/webenginewidgets/browser/browser.pro b/examples/webenginewidgets/demobrowser/demobrowser.pro
index f54186856..14347de71 100644
--- a/examples/webenginewidgets/browser/browser.pro
+++ b/examples/webenginewidgets/demobrowser/demobrowser.pro
@@ -1,6 +1,7 @@
TEMPLATE = app
-TARGET = browser
+TARGET = demobrowser
QT += webenginewidgets network widgets printsupport
+CONFIG += c++11
qtHaveModule(uitools):!embedded: QT += uitools
else: DEFINES += QT_NO_UITOOLS
@@ -62,28 +63,23 @@ SOURCES += \
RESOURCES += data/data.qrc htmls/htmls.qrc
-contains(DEFINES, QWEBENGINEPAGE_SETNETWORKACCESSMANAGER) {
- HEADERS += cookiejar.h networkaccessmanager.h
- SOURCES += cookiejar.cpp networkaccessmanager.cpp
-}
-
build_all:!build_pass {
CONFIG -= build_all
CONFIG += release
}
win32 {
- RC_FILE = browser.rc
+ RC_FILE = demobrowser.rc
}
mac {
- ICON = browser.icns
+ ICON = demobrowser.icns
QMAKE_INFO_PLIST = Info_mac.plist
- TARGET = Browser
+ TARGET = Demobrowser
}
-EXAMPLE_FILES = Info_mac.plist browser.icns browser.ico browser.rc
+EXAMPLE_FILES = Info_mac.plist demobrowser.icns demobrowser.ico demobrowser.rc
# install
-target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/browser
+target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/demobrowser
INSTALLS += target
diff --git a/examples/webenginewidgets/demobrowser/demobrowser.rc b/examples/webenginewidgets/demobrowser/demobrowser.rc
new file mode 100644
index 000000000..70cd8bb1c
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/demobrowser.rc
@@ -0,0 +1 @@
+IDI_ICON1 ICON DISCARDABLE "demobrowser.ico"
diff --git a/examples/webenginewidgets/browser/doc/images/browser-demo.png b/examples/webenginewidgets/demobrowser/doc/images/browser-demo.png
index 09d065095..09d065095 100644
--- a/examples/webenginewidgets/browser/doc/images/browser-demo.png
+++ b/examples/webenginewidgets/demobrowser/doc/images/browser-demo.png
Binary files differ
diff --git a/examples/webenginewidgets/browser/doc/src/browser.qdoc b/examples/webenginewidgets/demobrowser/doc/src/demobrowser.qdoc
index 99581d8a9..ba61dd79d 100644
--- a/examples/webenginewidgets/browser/doc/src/browser.qdoc
+++ b/examples/webenginewidgets/demobrowser/doc/src/demobrowser.qdoc
@@ -26,13 +26,13 @@
****************************************************************************/
/*!
- \example browser
- \title WebEngine Tab Browser Example
+ \example webenginewidgets/demobrowser
+ \title WebEngine Demo Browser Example
\ingroup webengine-widgetexamples
- \brief The QtWebKit browser example ported to use QtWebEngine
+ \brief A demo browser based on Qt WebEngine Widgets
- The Tab Browser example shows the \l{Qt WebEngine Widgets} module in action,
- providing a little Web browser application with support for tabs.
+ \e {Demo Browser} demonstrates how to use the \l{Qt WebEngine Widgets C++ Classes}
+ {Qt WebEngine C++ classes} to develop a small Web browser application with support for tabs.
\image browser-demo.png
diff --git a/examples/webenginewidgets/browser/downloaditem.ui b/examples/webenginewidgets/demobrowser/downloaditem.ui
index b7f7deb72..b7f7deb72 100644
--- a/examples/webenginewidgets/browser/downloaditem.ui
+++ b/examples/webenginewidgets/demobrowser/downloaditem.ui
diff --git a/examples/webenginewidgets/browser/downloadmanager.cpp b/examples/webenginewidgets/demobrowser/downloadmanager.cpp
index 90b0cec9d..eab28942e 100644
--- a/examples/webenginewidgets/browser/downloadmanager.cpp
+++ b/examples/webenginewidgets/demobrowser/downloadmanager.cpp
@@ -43,7 +43,6 @@
#include "autosaver.h"
#include "browserapplication.h"
-#include "networkaccessmanager.h"
#include <math.h>
diff --git a/examples/webenginewidgets/browser/downloadmanager.h b/examples/webenginewidgets/demobrowser/downloadmanager.h
index 877682d77..877682d77 100644
--- a/examples/webenginewidgets/browser/downloadmanager.h
+++ b/examples/webenginewidgets/demobrowser/downloadmanager.h
diff --git a/examples/webenginewidgets/browser/downloads.ui b/examples/webenginewidgets/demobrowser/downloads.ui
index a2e256935..a2e256935 100644
--- a/examples/webenginewidgets/browser/downloads.ui
+++ b/examples/webenginewidgets/demobrowser/downloads.ui
diff --git a/examples/webenginewidgets/browser/edittableview.cpp b/examples/webenginewidgets/demobrowser/edittableview.cpp
index 866ee6f1f..866ee6f1f 100644
--- a/examples/webenginewidgets/browser/edittableview.cpp
+++ b/examples/webenginewidgets/demobrowser/edittableview.cpp
diff --git a/examples/webenginewidgets/browser/edittableview.h b/examples/webenginewidgets/demobrowser/edittableview.h
index 315427eac..315427eac 100644
--- a/examples/webenginewidgets/browser/edittableview.h
+++ b/examples/webenginewidgets/demobrowser/edittableview.h
diff --git a/examples/webenginewidgets/browser/edittreeview.cpp b/examples/webenginewidgets/demobrowser/edittreeview.cpp
index d515ea058..d515ea058 100644
--- a/examples/webenginewidgets/browser/edittreeview.cpp
+++ b/examples/webenginewidgets/demobrowser/edittreeview.cpp
diff --git a/examples/webenginewidgets/browser/edittreeview.h b/examples/webenginewidgets/demobrowser/edittreeview.h
index 1cf87d54f..1cf87d54f 100644
--- a/examples/webenginewidgets/browser/edittreeview.h
+++ b/examples/webenginewidgets/demobrowser/edittreeview.h
diff --git a/examples/webenginewidgets/browser/featurepermissionbar.cpp b/examples/webenginewidgets/demobrowser/featurepermissionbar.cpp
index b7275dfc2..b7275dfc2 100644
--- a/examples/webenginewidgets/browser/featurepermissionbar.cpp
+++ b/examples/webenginewidgets/demobrowser/featurepermissionbar.cpp
diff --git a/examples/webenginewidgets/browser/featurepermissionbar.h b/examples/webenginewidgets/demobrowser/featurepermissionbar.h
index 1bfe1b483..1bfe1b483 100644
--- a/examples/webenginewidgets/browser/featurepermissionbar.h
+++ b/examples/webenginewidgets/demobrowser/featurepermissionbar.h
diff --git a/examples/webenginewidgets/browser/history.cpp b/examples/webenginewidgets/demobrowser/history.cpp
index ce104e982..ce104e982 100644
--- a/examples/webenginewidgets/browser/history.cpp
+++ b/examples/webenginewidgets/demobrowser/history.cpp
diff --git a/examples/webenginewidgets/browser/history.h b/examples/webenginewidgets/demobrowser/history.h
index bcb9c9b28..bcb9c9b28 100644
--- a/examples/webenginewidgets/browser/history.h
+++ b/examples/webenginewidgets/demobrowser/history.h
diff --git a/examples/webenginewidgets/browser/history.ui b/examples/webenginewidgets/demobrowser/history.ui
index 0944940e7..0944940e7 100644
--- a/examples/webenginewidgets/browser/history.ui
+++ b/examples/webenginewidgets/demobrowser/history.ui
diff --git a/examples/webenginewidgets/browser/htmls/htmls.qrc b/examples/webenginewidgets/demobrowser/htmls/htmls.qrc
index 03b256ccb..03b256ccb 100644
--- a/examples/webenginewidgets/browser/htmls/htmls.qrc
+++ b/examples/webenginewidgets/demobrowser/htmls/htmls.qrc
diff --git a/examples/webenginewidgets/browser/htmls/notfound.html b/examples/webenginewidgets/demobrowser/htmls/notfound.html
index e89845aa6..e89845aa6 100644
--- a/examples/webenginewidgets/browser/htmls/notfound.html
+++ b/examples/webenginewidgets/demobrowser/htmls/notfound.html
diff --git a/examples/webenginewidgets/browser/main.cpp b/examples/webenginewidgets/demobrowser/main.cpp
index 86859f741..86859f741 100644
--- a/examples/webenginewidgets/browser/main.cpp
+++ b/examples/webenginewidgets/demobrowser/main.cpp
diff --git a/examples/webenginewidgets/browser/modelmenu.cpp b/examples/webenginewidgets/demobrowser/modelmenu.cpp
index ec0eaffab..ec0eaffab 100644
--- a/examples/webenginewidgets/browser/modelmenu.cpp
+++ b/examples/webenginewidgets/demobrowser/modelmenu.cpp
diff --git a/examples/webenginewidgets/browser/modelmenu.h b/examples/webenginewidgets/demobrowser/modelmenu.h
index c0a7d56b8..c0a7d56b8 100644
--- a/examples/webenginewidgets/browser/modelmenu.h
+++ b/examples/webenginewidgets/demobrowser/modelmenu.h
diff --git a/examples/webenginewidgets/browser/passworddialog.ui b/examples/webenginewidgets/demobrowser/passworddialog.ui
index 7c1665867..7c1665867 100644
--- a/examples/webenginewidgets/browser/passworddialog.ui
+++ b/examples/webenginewidgets/demobrowser/passworddialog.ui
diff --git a/examples/webenginewidgets/browser/proxy.ui b/examples/webenginewidgets/demobrowser/proxy.ui
index 62a8be627..62a8be627 100644
--- a/examples/webenginewidgets/browser/proxy.ui
+++ b/examples/webenginewidgets/demobrowser/proxy.ui
diff --git a/examples/webenginewidgets/browser/searchlineedit.cpp b/examples/webenginewidgets/demobrowser/searchlineedit.cpp
index 5152ac1c0..5152ac1c0 100644
--- a/examples/webenginewidgets/browser/searchlineedit.cpp
+++ b/examples/webenginewidgets/demobrowser/searchlineedit.cpp
diff --git a/examples/webenginewidgets/browser/searchlineedit.h b/examples/webenginewidgets/demobrowser/searchlineedit.h
index b8b8337fd..b8b8337fd 100644
--- a/examples/webenginewidgets/browser/searchlineedit.h
+++ b/examples/webenginewidgets/demobrowser/searchlineedit.h
diff --git a/examples/webenginewidgets/browser/settings.cpp b/examples/webenginewidgets/demobrowser/settings.cpp
index 7ed5f707b..35e5e26c9 100644
--- a/examples/webenginewidgets/browser/settings.cpp
+++ b/examples/webenginewidgets/demobrowser/settings.cpp
@@ -47,9 +47,9 @@
#include "cookiejar.h"
#endif
#include "history.h"
-#include "networkaccessmanager.h"
#include "webview.h"
+#include <QtCore/QLocale>
#include <QtCore/QSettings>
#include <QtWidgets/QtWidgets>
#include <QtWebEngineWidgets/QtWebEngineWidgets>
@@ -66,6 +66,21 @@ SettingsDialog::SettingsDialog(QWidget *parent)
loadFromSettings();
}
+static QString defaultAcceptLanguage()
+{
+ const QStringList langs = QLocale().uiLanguages();
+ if (langs.isEmpty())
+ return QString();
+ QString str = langs.first();
+ const float qstep = 1.0f / float(langs.count());
+ float q = 1.0f - qstep;
+ for (int i = 1; i < langs.count(); ++i) {
+ str += QStringLiteral(", ") + langs.at(i) + QStringLiteral(";q=") + QString::number(q, 'f', 2);
+ q -= qstep;
+ }
+ return str;
+}
+
void SettingsDialog::loadDefaults()
{
QWebEngineSettings *defaultSettings = QWebEngineSettings::globalSettings();
@@ -82,15 +97,14 @@ void SettingsDialog::loadDefaults()
downloadsLocation->setText(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation));
enableJavascript->setChecked(defaultSettings->testAttribute(QWebEngineSettings::JavascriptEnabled));
-#if defined(QTWEBENGINE_PLUGINS)
enablePlugins->setChecked(defaultSettings->testAttribute(QWebEngineSettings::PluginsEnabled));
-#endif
enableScrollAnimator->setChecked(defaultSettings->testAttribute(QWebEngineSettings::ScrollAnimatorEnabled));
persistentDataPath->setText(QWebEngineProfile::defaultProfile()->persistentStoragePath());
sessionCookiesCombo->setCurrentIndex(QWebEngineProfile::defaultProfile()->persistentCookiesPolicy());
httpUserAgent->setText(QWebEngineProfile::defaultProfile()->httpUserAgent());
+ httpAcceptLanguage->setText(defaultAcceptLanguage());
}
void SettingsDialog::loadFromSettings()
@@ -140,6 +154,7 @@ void SettingsDialog::loadFromSettings()
userStyleSheet->setPlainText(settings.value(QLatin1String("userStyleSheet")).toString());
enableScrollAnimator->setChecked(settings.value(QLatin1String("enableScrollAnimator"), enableScrollAnimator->isChecked()).toBool());
httpUserAgent->setText(settings.value(QLatin1String("httpUserAgent"), httpUserAgent->text()).toString());
+ httpAcceptLanguage->setText(settings.value(QLatin1String("httpAcceptLanguage"), httpAcceptLanguage->text()).toString());
settings.endGroup();
// Privacy
@@ -198,6 +213,7 @@ void SettingsDialog::saveToSettings()
settings.setValue(QLatin1String("enableScrollAnimator"), enableScrollAnimator->isChecked());
settings.setValue(QLatin1String("userStyleSheet"), userStyleSheet->toPlainText());
settings.setValue(QLatin1String("httpUserAgent"), httpUserAgent->text());
+ settings.setValue(QLatin1String("httpAcceptLanguage"), httpAcceptLanguage->text());
settings.endGroup();
//Privacy
@@ -223,7 +239,6 @@ void SettingsDialog::saveToSettings()
BrowserApplication::instance()->loadSettings();
#if defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- BrowserApplication::networkAccessManager()->loadSettings();
BrowserApplication::cookieJar()->loadSettings();
#endif
BrowserApplication::historyManager()->loadSettings();
@@ -271,6 +286,16 @@ void SettingsDialog::chooseFixedFont()
}
}
+void SettingsDialog::on_httpUserAgent_editingFinished()
+{
+ QWebEngineProfile::defaultProfile()->setHttpUserAgent(httpUserAgent->text());
+}
+
+void SettingsDialog::on_httpAcceptLanguage_editingFinished()
+{
+ QWebEngineProfile::defaultProfile()->setHttpAcceptLanguage(httpAcceptLanguage->text());
+}
+
void SettingsDialog::setHomeToCurrentPage()
{
BrowserMainWindow *mw = static_cast<BrowserMainWindow*>(parent());
diff --git a/examples/webenginewidgets/browser/settings.h b/examples/webenginewidgets/demobrowser/settings.h
index 6def66928..3a50dd29f 100644
--- a/examples/webenginewidgets/browser/settings.h
+++ b/examples/webenginewidgets/demobrowser/settings.h
@@ -65,6 +65,9 @@ private slots:
void chooseFont();
void chooseFixedFont();
+ void on_httpUserAgent_editingFinished();
+ void on_httpAcceptLanguage_editingFinished();
+
private:
QFont standardFont;
QFont fixedFont;
diff --git a/examples/webenginewidgets/browser/settings.ui b/examples/webenginewidgets/demobrowser/settings.ui
index 11bdee4d3..38a7af344 100644
--- a/examples/webenginewidgets/browser/settings.ui
+++ b/examples/webenginewidgets/demobrowser/settings.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>657</width>
- <height>322</height>
+ <height>336</height>
</rect>
</property>
<property name="windowTitle">
@@ -499,19 +499,29 @@
<string>Advanced</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
- <item row="2" column="1">
- <widget class="QTextEdit" name="userStyleSheet"/>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_15">
+ <property name="text">
+ <string>HTTP User-Agent:</string>
+ </property>
+ </widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="httpUserAgent"/>
</item>
- <item row="0" column="0">
- <widget class="QLabel" name="label_15">
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_16">
<property name="text">
- <string>HTTP User-Agent:</string>
+ <string>HTTP Accept-&amp;Language:</string>
+ </property>
+ <property name="buddy">
+ <cstring>httpAcceptLanguage</cstring>
</property>
</widget>
</item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="httpAcceptLanguage"/>
+ </item>
<item row="2" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
@@ -519,7 +529,10 @@
</property>
</widget>
</item>
- <item row="4" column="1">
+ <item row="2" column="1">
+ <widget class="QTextEdit" name="userStyleSheet"/>
+ </item>
+ <item row="3" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
diff --git a/examples/webenginewidgets/browser/squeezelabel.cpp b/examples/webenginewidgets/demobrowser/squeezelabel.cpp
index 78198c3f0..78198c3f0 100644
--- a/examples/webenginewidgets/browser/squeezelabel.cpp
+++ b/examples/webenginewidgets/demobrowser/squeezelabel.cpp
diff --git a/examples/webenginewidgets/browser/squeezelabel.h b/examples/webenginewidgets/demobrowser/squeezelabel.h
index 628b7350a..628b7350a 100644
--- a/examples/webenginewidgets/browser/squeezelabel.h
+++ b/examples/webenginewidgets/demobrowser/squeezelabel.h
diff --git a/examples/webenginewidgets/browser/tabwidget.cpp b/examples/webenginewidgets/demobrowser/tabwidget.cpp
index c093b804a..4e2073b11 100644
--- a/examples/webenginewidgets/browser/tabwidget.cpp
+++ b/examples/webenginewidgets/demobrowser/tabwidget.cpp
@@ -48,10 +48,11 @@
#include "urllineedit.h"
#include "webview.h"
+#include <QWebEngineDownloadItem>
+#include <QWebEngineProfile>
+#include <QWebEngineFullScreenRequest>
#include <QtCore/QMimeData>
#include <QtGui/QClipboard>
-#include <QtWebEngineWidgets/QWebEngineDownloadItem>
-#include <QtWebEngineWidgets/QWebEngineProfile>
#include <QtWidgets/QCompleter>
#include <QtWidgets/QListView>
#include <QtWidgets/QMenu>
@@ -85,6 +86,11 @@ TabBar::TabBar(QWidget *parent)
setMovable(true);
}
+TabWidget::~TabWidget()
+{
+ delete m_fullScreenView;
+}
+
void TabBar::selectTabAction()
{
if (QShortcut *shortCut = qobject_cast<QShortcut*>(sender())) {
@@ -213,11 +219,12 @@ TabWidget::TabWidget(QWidget *parent)
, m_lineEdits(0)
, m_tabBar(new TabBar(this))
, m_profile(QWebEngineProfile::defaultProfile())
+ , m_fullScreenView(0)
{
setElideMode(Qt::ElideRight);
connect(m_tabBar, SIGNAL(newTab()), this, SLOT(newTab()));
- connect(m_tabBar, SIGNAL(closeTab(int)), this, SLOT(closeTab(int)));
+ connect(m_tabBar, SIGNAL(closeTab(int)), this, SLOT(requestCloseTab(int)));
connect(m_tabBar, SIGNAL(cloneTab(int)), this, SLOT(cloneTab(int)));
connect(m_tabBar, SIGNAL(closeOtherTabs(int)), this, SLOT(closeOtherTabs(int)));
connect(m_tabBar, SIGNAL(reloadTab(int)), this, SLOT(reloadTab(int)));
@@ -235,7 +242,7 @@ TabWidget::TabWidget(QWidget *parent)
m_closeTabAction = new QAction(QIcon(QLatin1String(":closetab.png")), tr("&Close Tab"), this);
m_closeTabAction->setShortcuts(QKeySequence::Close);
m_closeTabAction->setIconVisibleInMenu(false);
- connect(m_closeTabAction, SIGNAL(triggered()), this, SLOT(closeTab()));
+ connect(m_closeTabAction, SIGNAL(triggered()), this, SLOT(requestCloseTab()));
m_nextTabAction = new QAction(tr("Show Next Tab"), this);
QList<QKeySequence> shortcuts;
@@ -315,6 +322,8 @@ void TabWidget::currentChanged(int index)
this, SIGNAL(loadProgress(int)));
disconnect(oldWebView->page()->profile(), SIGNAL(downloadRequested(QWebEngineDownloadItem*)),
this, SLOT(downloadRequested(QWebEngineDownloadItem*)));
+ disconnect(oldWebView->page(), SIGNAL(fullScreenRequested(const QWebEngineFullScreenRequest&)),
+ this, SLOT(fullScreenRequested(const QWebEngineFullScreenRequest&)));
}
#if defined(QWEBENGINEVIEW_STATUSBARMESSAGE)
@@ -327,6 +336,8 @@ void TabWidget::currentChanged(int index)
this, SIGNAL(loadProgress(int)));
connect(webView->page()->profile(), SIGNAL(downloadRequested(QWebEngineDownloadItem*)),
this, SLOT(downloadRequested(QWebEngineDownloadItem*)));
+ connect(webView->page(), SIGNAL(fullScreenRequested(const QWebEngineFullScreenRequest&)),
+ this, SLOT(fullScreenRequested(const QWebEngineFullScreenRequest&)));
for (int i = 0; i < m_actions.count(); ++i) {
WebActionMapper *mapper = m_actions[i];
@@ -342,6 +353,28 @@ void TabWidget::currentChanged(int index)
webView->setFocus();
}
+void TabWidget::fullScreenRequested(const QWebEngineFullScreenRequest &request)
+{
+ if (request.toggleOn()) {
+ if (!m_fullScreenView)
+ m_fullScreenView = new QWebEngineView();
+ WebPage *webPage = qobject_cast<WebPage*>(sender());
+ webPage->setView(m_fullScreenView);
+ request.accept();
+ m_fullScreenView->showFullScreen();
+ m_fullScreenView->raise();
+ } else {
+ if (!m_fullScreenView)
+ return;
+ WebPage *webPage = qobject_cast<WebPage*>(sender());
+ WebView *oldWebView = this->webView(m_lineEdits->currentIndex());
+ webPage->setView(oldWebView);
+ request.accept();
+ raise();
+ m_fullScreenView->hide();
+ }
+}
+
QAction *TabWidget::newTabAction() const
{
return m_newTabAction;
@@ -522,12 +555,8 @@ void TabWidget::windowCloseRequested()
WebPage *webPage = qobject_cast<WebPage*>(sender());
WebView *webView = qobject_cast<WebView*>(webPage->view());
int index = webViewIndex(webView);
- if (index >= 0) {
- if (count() == 1)
- webView->webPage()->mainWindow()->close();
- else
- closeTab(index);
- }
+ if (index >= 0)
+ closeTab(index);
}
void TabWidget::closeOtherTabs(int index)
@@ -552,30 +581,25 @@ void TabWidget::cloneTab(int index)
}
// When index is -1 index chooses the current tab
-void TabWidget::closeTab(int index)
+void TabWidget::requestCloseTab(int index)
{
if (index < 0)
index = currentIndex();
if (index < 0 || index >= count())
return;
+ WebView *tab = webView(index);
+ if (!tab)
+ return;
+ tab->page()->triggerAction(QWebEnginePage::RequestClose);
+}
+
+void TabWidget::closeTab(int index)
+{
+ if (index < 0 || index >= count())
+ return;
bool hasFocus = false;
if (WebView *tab = webView(index)) {
-#if defined(QWEBENGINEPAGE_ISMODIFIED)
- if (tab->isModified()) {
- QMessageBox closeConfirmation(tab);
- closeConfirmation.setWindowFlags(Qt::Sheet);
- closeConfirmation.setWindowTitle(tr("Do you really want to close this page?"));
- closeConfirmation.setInformativeText(tr("You have modified this page and when closing it you would lose the modification.\n"
- "Do you really want to close this page?\n"));
- closeConfirmation.setIcon(QMessageBox::Question);
- closeConfirmation.addButton(QMessageBox::Yes);
- closeConfirmation.addButton(QMessageBox::No);
- closeConfirmation.setEscapeButton(QMessageBox::No);
- if (closeConfirmation.exec() == QMessageBox::No)
- return;
- }
-#endif
hasFocus = tab->hasFocus();
if (m_profile == QWebEngineProfile::defaultProfile()) {
diff --git a/examples/webenginewidgets/browser/tabwidget.h b/examples/webenginewidgets/demobrowser/tabwidget.h
index 5d7f1e2c5..3a1fe7171 100644
--- a/examples/webenginewidgets/browser/tabwidget.h
+++ b/examples/webenginewidgets/demobrowser/tabwidget.h
@@ -49,6 +49,7 @@
QT_BEGIN_NAMESPACE
class QWebEngineDownloadItem;
class QWebEngineProfile;
+class QWebEngineView;
QT_END_NAMESPACE
/*
@@ -164,6 +165,7 @@ signals:
public:
TabWidget(QWidget *parent = 0);
+ ~TabWidget();
void clear();
void addWebAction(QAction *action, QWebEnginePage::WebAction webAction);
@@ -194,7 +196,8 @@ public slots:
void loadUrlInCurrentTab(const QUrl &url);
WebView *newTab(bool makeCurrent = true);
void cloneTab(int index = -1);
- void closeTab(int index = -1);
+ void requestCloseTab(int index = -1);
+ void closeTab(int index);
void closeOtherTabs(int index);
void reloadTab(int index = -1);
void reloadAllTabs();
@@ -213,6 +216,7 @@ private slots:
void lineEditReturnPressed();
void windowCloseRequested();
void moveTab(int fromIndex, int toIndex);
+ void fullScreenRequested(const QWebEngineFullScreenRequest& request);
private:
QAction *m_recentlyClosedTabsAction;
@@ -230,6 +234,7 @@ private:
QStackedWidget *m_lineEdits;
TabBar *m_tabBar;
QWebEngineProfile *m_profile;
+ QWebEngineView *m_fullScreenView;
};
#endif // TABWIDGET_H
diff --git a/examples/webenginewidgets/browser/toolbarsearch.cpp b/examples/webenginewidgets/demobrowser/toolbarsearch.cpp
index 42cdaec18..42cdaec18 100644
--- a/examples/webenginewidgets/browser/toolbarsearch.cpp
+++ b/examples/webenginewidgets/demobrowser/toolbarsearch.cpp
diff --git a/examples/webenginewidgets/browser/toolbarsearch.h b/examples/webenginewidgets/demobrowser/toolbarsearch.h
index cbe00366c..cbe00366c 100644
--- a/examples/webenginewidgets/browser/toolbarsearch.h
+++ b/examples/webenginewidgets/demobrowser/toolbarsearch.h
diff --git a/examples/webenginewidgets/browser/urllineedit.cpp b/examples/webenginewidgets/demobrowser/urllineedit.cpp
index 685277d9c..685277d9c 100644
--- a/examples/webenginewidgets/browser/urllineedit.cpp
+++ b/examples/webenginewidgets/demobrowser/urllineedit.cpp
diff --git a/examples/webenginewidgets/browser/urllineedit.h b/examples/webenginewidgets/demobrowser/urllineedit.h
index 775aa7d18..775aa7d18 100644
--- a/examples/webenginewidgets/browser/urllineedit.h
+++ b/examples/webenginewidgets/demobrowser/urllineedit.h
diff --git a/examples/webenginewidgets/browser/webview.cpp b/examples/webenginewidgets/demobrowser/webview.cpp
index 99986642e..c12f3db36 100644
--- a/examples/webenginewidgets/browser/webview.cpp
+++ b/examples/webenginewidgets/demobrowser/webview.cpp
@@ -44,7 +44,6 @@
#include "cookiejar.h"
#include "downloadmanager.h"
#include "featurepermissionbar.h"
-#include "networkaccessmanager.h"
#include "ui_passworddialog.h"
#include "ui_proxy.h"
#include "tabwidget.h"
@@ -67,12 +66,12 @@
#include <QtCore/QDebug>
#include <QtCore/QBuffer>
+#include <QtCore/QTimer>
WebPage::WebPage(QWebEngineProfile *profile, QObject *parent)
: QWebEnginePage(profile, parent)
, m_keyboardModifiers(Qt::NoModifier)
, m_pressedButtons(Qt::NoButton)
- , m_openInNewTab(false)
{
#if defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
setNetworkAccessManager(BrowserApplication::networkAccessManager());
@@ -175,8 +174,7 @@ private:
QWebEnginePage *WebPage::createWindow(QWebEnginePage::WebWindowType type)
{
- if (m_openInNewTab || type == QWebEnginePage::WebBrowserTab) {
- m_openInNewTab = false;
+ if (type == QWebEnginePage::WebBrowserTab) {
return mainWindow()->tabWidget()->newTab()->page();
} else if (type == QWebEnginePage::WebBrowserWindow) {
BrowserApplication::instance()->newMainWindow();
@@ -274,8 +272,14 @@ void WebPage::authenticationRequired(const QUrl &requestUrl, QAuthenticator *aut
passwordDialog.introLabel->setWordWrap(true);
if (dialog.exec() == QDialog::Accepted) {
+ QByteArray key = BrowserApplication::authenticationKey(requestUrl, auth->realm());
auth->setUser(passwordDialog.userNameLineEdit->text());
auth->setPassword(passwordDialog.passwordLineEdit->text());
+ auth->setOption("key", key);
+ BrowserApplication::instance()->setLastAuthenticator(auth);
+ } else {
+ // Set authenticator null if dialog is cancelled
+ *auth = QAuthenticator();
}
}
@@ -299,8 +303,32 @@ void WebPage::proxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator
proxyDialog.introLabel->setWordWrap(true);
if (dialog.exec() == QDialog::Accepted) {
- auth->setUser(proxyDialog.userNameLineEdit->text());
+ QString user = proxyDialog.userNameLineEdit->text();
+ QByteArray key = BrowserApplication::proxyAuthenticationKey(user, proxyHost, auth->realm());
+ auth->setUser(user);
auth->setPassword(proxyDialog.passwordLineEdit->text());
+ auth->setOption("key", key);
+ BrowserApplication::instance()->setLastProxyAuthenticator(auth);
+ } else {
+ // Set authenticator null if dialog is cancelled
+ *auth = QAuthenticator();
+ }
+}
+
+void WebPage::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int /*lineNumber*/, const QString& sourceID)
+{
+ QUrl url;
+ url.setUrl(sourceID);
+ switch (level) {
+ case InfoMessageLevel:
+ // Ignore these, they can still be found in the inspector.
+ break;
+ case WarningMessageLevel:
+ qInfo() << "JavaScript WARNING:" << url.host() << message;
+ break;
+ case ErrorMessageLevel:
+ qInfo() << "JavaScript ERROR:" << url.host() << message;
+ break;
}
}
@@ -314,6 +342,27 @@ WebView::WebView(QWidget* parent)
this, SLOT(setProgress(int)));
connect(this, SIGNAL(loadFinished(bool)),
this, SLOT(loadFinished(bool)));
+ connect(this, &QWebEngineView::renderProcessTerminated,
+ [=](QWebEnginePage::RenderProcessTerminationStatus termStatus, int statusCode) {
+ const char *status = "";
+ switch (termStatus) {
+ case QWebEnginePage::NormalTerminationStatus:
+ status = "(normal exit)";
+ break;
+ case QWebEnginePage::AbnormalTerminationStatus:
+ status = "(abnormal exit)";
+ break;
+ case QWebEnginePage::CrashedTerminationStatus:
+ status = "(crashed)";
+ break;
+ case QWebEnginePage::KilledTerminationStatus:
+ status = "(killed)";
+ break;
+ }
+
+ qInfo() << "Render process exited with code" << statusCode << status;
+ QTimer::singleShot(0, [this] { reload(); });
+ });
}
void WebView::setPage(WebPage *_page)
@@ -338,24 +387,17 @@ void WebView::setPage(WebPage *_page)
void WebView::contextMenuEvent(QContextMenuEvent *event)
{
-#if defined(QWEBENGINEPAGE_HITTESTCONTENT)
- QWebEngineHitTestResult r = page()->hitTestContent(event->pos());
- if (!r.linkUrl().isEmpty()) {
- QMenu menu(this);
- menu.addAction(pageAction(QWebEnginePage::OpenLinkInNewWindow));
- menu.addAction(tr("Open in New Tab"), this, SLOT(openLinkInNewTab()));
- menu.addSeparator();
- menu.addAction(pageAction(QWebEnginePage::DownloadLinkToDisk));
- // Add link to bookmarks...
- menu.addSeparator();
- menu.addAction(pageAction(QWebEnginePage::CopyLinkToClipboard));
- if (page()->settings()->testAttribute(QWebEngineSettings::DeveloperExtrasEnabled))
- menu.addAction(pageAction(QWebEnginePage::InspectElement));
- menu.exec(mapToGlobal(event->pos()));
- return;
+ QMenu *menu = page()->createStandardContextMenu();
+ const QList<QAction*> actions = menu->actions();
+ QList<QAction*>::const_iterator it = qFind(actions.cbegin(), actions.cend(), page()->action(QWebEnginePage::OpenLinkInThisWindow));
+ if (it != actions.cend()) {
+ (*it)->setText(tr("Open Link in This Window"));
+ ++it;
+ menu->insertAction(*it, page()->action(QWebEnginePage::OpenLinkInNewWindow));
+ menu->insertAction(*it, page()->action(QWebEnginePage::OpenLinkInNewTab));
}
-#endif
- QWebEngineView::contextMenuEvent(event);
+
+ menu->popup(event->globalPos());
}
void WebView::wheelEvent(QWheelEvent *event)
@@ -374,10 +416,7 @@ void WebView::wheelEvent(QWheelEvent *event)
void WebView::openLinkInNewTab()
{
-#if defined(QWEBENGINEPAGE_WEBACTION_OPENLINKINNEWWINDOW)
- m_page->m_openInNewTab = true;
- pageAction(QWebEnginePage::OpenLinkInNewWindow)->trigger();
-#endif
+ pageAction(QWebEnginePage::OpenLinkInNewTab)->trigger();
}
void WebView::onFeaturePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature)
diff --git a/examples/webenginewidgets/browser/webview.h b/examples/webenginewidgets/demobrowser/webview.h
index a147d780a..cb78fdd8a 100644
--- a/examples/webenginewidgets/browser/webview.h
+++ b/examples/webenginewidgets/demobrowser/webview.h
@@ -71,6 +71,7 @@ protected:
QObject *createPlugin(const QString &classId, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues);
#endif
virtual bool certificateError(const QWebEngineCertificateError &error) Q_DECL_OVERRIDE;
+ virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
private slots:
#if defined(QWEBENGINEPAGE_UNSUPPORTEDCONTENT)
@@ -85,7 +86,6 @@ private:
// set the webview mousepressedevent
Qt::KeyboardModifiers m_keyboardModifiers;
Qt::MouseButtons m_pressedButtons;
- bool m_openInNewTab;
QUrl m_loadingUrl;
};
diff --git a/examples/webenginewidgets/browser/xbel.cpp b/examples/webenginewidgets/demobrowser/xbel.cpp
index 6b4f53d2e..6b4f53d2e 100644
--- a/examples/webenginewidgets/browser/xbel.cpp
+++ b/examples/webenginewidgets/demobrowser/xbel.cpp
diff --git a/examples/webenginewidgets/browser/xbel.h b/examples/webenginewidgets/demobrowser/xbel.h
index d95549dd8..d95549dd8 100644
--- a/examples/webenginewidgets/browser/xbel.h
+++ b/examples/webenginewidgets/demobrowser/xbel.h
diff --git a/examples/webenginewidgets/fancybrowser/doc/src/fancybrowser.qdoc b/examples/webenginewidgets/fancybrowser/doc/src/fancybrowser.qdoc
index e6c6ada34..b798e4832 100644
--- a/examples/webenginewidgets/fancybrowser/doc/src/fancybrowser.qdoc
+++ b/examples/webenginewidgets/fancybrowser/doc/src/fancybrowser.qdoc
@@ -26,7 +26,7 @@
****************************************************************************/
/*!
- \example fancybrowser
+ \example webenginewidgets/fancybrowser
\title WebEngine Fancy Browser Example
\ingroup webengine-widgetexamples
\brief Demonstrates how to use browse web and manipulate content
@@ -48,7 +48,7 @@
The \c MainWindow class inherits QMainWindow. It implements a number of
slots to perform actions on both the application and on the web content.
- \snippet fancybrowser/mainwindow.h 1
+ \snippet webenginewidgets/fancybrowser/mainwindow.h 1
We also declare a QString that contains the jQuery, a QWebView
that displays the web content, and a QLineEdit that acts as the
@@ -58,7 +58,7 @@
We start by implementing the constructor.
- \snippet fancybrowser/mainwindow.cpp 1
+ \snippet webenginewidgets/fancybrowser/mainwindow.cpp 1
The first part of the constructor sets the value of \c progress to
0. This value will be used later in the code to visualize the
@@ -68,7 +68,7 @@
content. The jQuery library is a JavaScript library that provides different
functions for manipulating HTML.
- \snippet fancybrowser/mainwindow.cpp 2
+ \snippet webenginewidgets/fancybrowser/mainwindow.cpp 2
The second part of the constructor creates a QWebView and connects
slots to the views signals. Furthermore, we create a QLineEdit as
@@ -77,13 +77,13 @@
QLineEdit to a QToolbar together with a set of navigation actions
from QWebView::pageAction.
- \snippet fancybrowser/mainwindow.cpp 3
+ \snippet webenginewidgets/fancybrowser/mainwindow.cpp 3
The third and last part of the constructor implements two QMenus and assigns
a set of actions to them. The last line sets the QWebView as the central
widget in the QMainWindow.
- \snippet fancybrowser/mainwindow.cpp 4
+ \snippet webenginewidgets/fancybrowser/mainwindow.cpp 4
When the page is loaded, \c adjustLocation() updates the address
bar; \c adjustLocation() is triggered by the \c loadFinished()
@@ -92,13 +92,13 @@
the new web page has finished loading, \c adjustLocation() will be
run once more to update the address bar.
- \snippet fancybrowser/mainwindow.cpp 5
+ \snippet webenginewidgets/fancybrowser/mainwindow.cpp 5
\c adjustTitle() sets the window title and displays the loading
progress. This slot is triggered by the \c titleChanged() signal
in QWebView.
- \snippet fancybrowser/mainwindow.cpp 6
+ \snippet webenginewidgets/fancybrowser/mainwindow.cpp 6
When a web page has loaded, \c finishLoading() is triggered by the
\c loadFinished() signal in QWebView. \c finishLoading() then updates the
@@ -113,7 +113,7 @@
that the images of the newly loaded page respect the state of the toggle
action.
- \snippet fancybrowser/mainwindow.cpp 7
+ \snippet webenginewidgets/fancybrowser/mainwindow.cpp 7
The first jQuery-based function, \c highlightAllLinks(), is designed to
highlight all links in the current webpage. The JavaScript code looks
@@ -121,14 +121,14 @@
For each such element, the background color is set to be yellow by
using CSS.
- \snippet fancybrowser/mainwindow.cpp 8
+ \snippet webenginewidgets/fancybrowser/mainwindow.cpp 8
The \c rotateImages() function rotates the images on the current
web page. This JavaScript code relies on CSS transforms and
looks up all \e {img} elements and rotates the images 180 degrees
and then back again.
- \snippet fancybrowser/mainwindow.cpp 9
+ \snippet webenginewidgets/fancybrowser/mainwindow.cpp 9
The remaining four methods remove different elements from the current web
page. \c removeGifImages() removes all GIF images on the page by looking up
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 2ccb9f03c534c28b1c3d2f2d09d131a70cdfe9f
+Subproject ae431a6bc66d30847024c5cbfa2b10bc931ef0d
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro
new file mode 100644
index 000000000..e4cdf43cb
--- /dev/null
+++ b/src/core/api/core_api.pro
@@ -0,0 +1,56 @@
+TARGET = qtwebenginecoreapi$$qtPlatformTargetSuffix()
+DESTDIR = $$OUT_PWD/$$getConfigDir()
+
+TEMPLATE = lib
+
+CONFIG += staticlib c++11
+QT += network
+
+# Don't create .prl file for this intermediate library because
+# their contents get used when linking against them, breaking
+# "-Wl,-whole-archive -lqtwebenginecoreapi --Wl,-no-whole-archive"
+CONFIG -= create_prl
+
+# Copy this logic from qt_module.prf so that the intermediate library can be
+# created to the same rules as the final module linking in core_module.pro.
+!host_build:if(win32|mac):!macx-xcode {
+ contains(QT_CONFIG, debug_and_release):CONFIG += debug_and_release
+ contains(QT_CONFIG, build_all):CONFIG += build_all
+}
+
+DEFINES += \
+ BUILDING_CHROMIUM \
+ NOMINMAX
+
+CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$$getChromiumSrcDir()
+INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core \
+ $$CHROMIUM_SRC_DIR
+
+linux-g++*: QMAKE_CXXFLAGS += -Wno-unused-parameter
+
+HEADERS = \
+ qwebenginecallback.h \
+ qwebenginecallback_p.h \
+ qtwebenginecoreglobal.h \
+ qtwebenginecoreglobal_p.h \
+ qwebenginecookiestoreclient.h \
+ qwebenginecookiestoreclient_p.h \
+ qwebengineurlrequestinterceptor.h \
+ qwebengineurlrequestinfo.h \
+ qwebengineurlrequestinfo_p.h \
+ qwebengineurlrequestjob.h \
+ qwebengineurlschemehandler.h
+
+SOURCES = \
+ qwebenginecookiestoreclient.cpp \
+ qwebengineurlrequestinfo.cpp \
+ qwebengineurlrequestjob.cpp \
+ qwebengineurlschemehandler.cpp
+
+msvc {
+ # Create a list of object files that can be used as response file for the linker.
+ # This is done to simulate -whole-archive on MSVC.
+ QMAKE_POST_LINK = \
+ "if exist $(DESTDIR_TARGET).objects del $(DESTDIR_TARGET).objects$$escape_expand(\\n\\t)" \
+ "for %%a in ($(OBJECTS)) do echo $$shell_quote($$shell_path($$OUT_PWD))\\%%a >> $(DESTDIR_TARGET).objects"
+}
diff --git a/src/core/api/qtwebenginecoreglobal.h b/src/core/api/qtwebenginecoreglobal.h
new file mode 100644
index 000000000..16daaab7d
--- /dev/null
+++ b/src/core/api/qtwebenginecoreglobal.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTWEBENGINECOREGLOBAL_H
+#define QTWEBENGINECOREGLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#if defined(BUILDING_CHROMIUM)
+# define QWEBENGINE_EXPORT Q_DECL_EXPORT
+#else
+# define QWEBENGINE_EXPORT Q_DECL_IMPORT
+#endif
+
+#define ASSERT_ENUMS_MATCH(A, B) Q_STATIC_ASSERT_X(static_cast<int>(A) == static_cast<int>(B), "The enum values must match");
+
+#endif // QTWEBENGINECOREGLOBAL_H
diff --git a/src/core/qtwebenginecoreglobal.h b/src/core/api/qtwebenginecoreglobal_p.h
index d09497ce8..e93ca9c2c 100644
--- a/src/core/qtwebenginecoreglobal.h
+++ b/src/core/api/qtwebenginecoreglobal_p.h
@@ -34,10 +34,21 @@
**
****************************************************************************/
-#ifndef QTWEBENGINECOREGLOBAL_H
-#define QTWEBENGINECOREGLOBAL_H
+#ifndef QTWEBENGINECOREGLOBAL_P_H
+#define QTWEBENGINECOREGLOBAL_P_H
-#include <QtCore/qglobal.h>
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qtwebenginecoreglobal.h"
#ifdef QT_WEBENGINE_LOGGING
#define QT_NOT_YET_IMPLEMENTED fprintf(stderr, "function %s not implemented! - %s:%d\n", __func__, __FILE__, __LINE__);
@@ -47,16 +58,6 @@
#define QT_NOT_USED Q_UNREACHABLE(); // This will assert in debug.
#endif
-#ifndef QT_STATIC
-# if defined(BUILDING_CHROMIUM)
-# define QWEBENGINE_EXPORT Q_DECL_EXPORT
-# else
-# define QWEBENGINE_EXPORT Q_DECL_IMPORT
-# endif
-#else
-# define QWEBENGINE_EXPORT
-#endif
-
-#define ASSERT_ENUMS_MATCH(A, B) Q_STATIC_ASSERT_X(static_cast<int>(A) == static_cast<int>(B), "The enum values must match");
+#define QWEBENGINE_PRIVATE_EXPORT QWEBENGINE_EXPORT
-#endif // QTWEBENGINECOREGLOBAL_H
+#endif // QTWEBENGINECOREGLOBAL_P_H
diff --git a/src/core/api/qwebenginecallback.h b/src/core/api/qwebenginecallback.h
new file mode 100644
index 000000000..ddee20d06
--- /dev/null
+++ b/src/core/api/qwebenginecallback.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINECALLBACK_H
+#define QWEBENGINECALLBACK_H
+
+#include "qtwebenginecoreglobal.h"
+
+#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE
+#include <QtCore/qshareddata.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qvariant.h>
+
+namespace QtWebEngineCore {
+class CallbackDirectory;
+}
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWebEnginePrivate {
+
+template <typename T>
+class QWebEngineCallbackPrivateBase : public QSharedData {
+public:
+ QWebEngineCallbackPrivateBase() {}
+ virtual ~QWebEngineCallbackPrivateBase() {}
+ virtual void operator()(T) = 0;
+};
+
+template <typename T, typename F>
+class QWebEngineCallbackPrivate : public QWebEngineCallbackPrivateBase<T> {
+public:
+ QWebEngineCallbackPrivate(F callable)
+ : m_callable(callable)
+ {}
+ virtual void operator()(T value) Q_DECL_OVERRIDE { m_callable(value); }
+private:
+ F m_callable;
+};
+
+} // namespace QtWebEnginePrivate
+
+template <typename T>
+class QWebEngineCallback {
+public:
+ template <typename F>
+ QWebEngineCallback(F f)
+ : d(new QtWebEnginePrivate::QWebEngineCallbackPrivate<T, F>(f))
+ { }
+ QWebEngineCallback() { }
+ operator bool() const { return d; }
+private:
+ friend class QtWebEngineCore::CallbackDirectory;
+ QExplicitlySharedDataPointer<QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> > d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINECALLBACK_H
diff --git a/src/core/api/qwebenginecallback_p.h b/src/core/api/qwebenginecallback_p.h
new file mode 100644
index 000000000..f0c25fe9e
--- /dev/null
+++ b/src/core/api/qwebenginecallback_p.h
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINECALLBACK_P_H
+#define QWEBENGINECALLBACK_P_H
+
+#include "qtwebenginecoreglobal_p.h"
+#include "qwebenginecallback.h"
+
+#include <QByteArray>
+#include <QHash>
+#include <QSharedData>
+#include <QString>
+#include <QVariant>
+#include <type_traits>
+
+#define FOR_EACH_TYPE(F) \
+ F(bool) \
+ F(int) \
+ F(const QString &) \
+ F(const QByteArray &) \
+ F(const QVariant &)
+
+namespace QtWebEngineCore {
+
+class CallbackDirectory {
+ template<typename T>
+ void invokeInternal(quint64 callbackId, T result);
+ template<typename T>
+ void invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *callback);
+
+public:
+ ~CallbackDirectory()
+ {
+ // "Cancel" pending callbacks by calling them with an invalid value.
+ // This guarantees that each callback is called exactly once.
+ for (CallbackSharedDataPointerBase * const sharedPtrBase: m_callbackMap) {
+ Q_ASSERT(sharedPtrBase);
+ sharedPtrBase->invokeEmpty();
+ delete sharedPtrBase;
+ }
+ }
+
+ enum ReservedCallbackIds {
+ NoCallbackId = 0,
+ DeleteCookieCallbackId,
+ DeleteSessionCookiesCallbackId,
+ DeleteAllCookiesCallbackId,
+ GetAllCookiesCallbackId,
+
+ // Place reserved id's before this.
+ ReservedCallbackIdsEnd
+ };
+
+ template<typename T>
+ void registerCallback(quint64 callbackId, const QWebEngineCallback<T> &callback);
+
+ template<typename T>
+ void invokeEmpty(const QWebEngineCallback<T> &callback);
+
+#define DEFINE_INVOKE_FOR_TYPE(Type) \
+ void invoke(quint64 callbackId, Type result) { \
+ invokeInternal<Type>(callbackId, std::forward<Type>(result)); \
+ }
+ FOR_EACH_TYPE(DEFINE_INVOKE_FOR_TYPE)
+#undef DEFINE_INVOKE_FOR_TYPE
+
+ template <typename A>
+ void invokeDirectly(const QWebEngineCallback<A> &callback, const A &argument)
+ {
+ return callback.d.data()->operator()(std::forward<const A&>(argument));
+ }
+
+private:
+ struct CallbackSharedDataPointerBase {
+ virtual ~CallbackSharedDataPointerBase() { }
+ virtual void invokeEmpty() = 0;
+ virtual void doRef() = 0;
+ virtual void doDeref() = 0;
+ virtual operator bool () const = 0;
+ };
+
+ template <typename T>
+ struct CallbackSharedDataPointer : public CallbackSharedDataPointerBase {
+ CallbackDirectory* parent;
+ QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *callback;
+
+ ~CallbackSharedDataPointer() { doDeref(); }
+ CallbackSharedDataPointer() : parent(0), callback(0) { }
+ CallbackSharedDataPointer(const CallbackSharedDataPointer<T> &other)
+ : parent(other.parent), callback(other.callback) { doRef(); }
+ CallbackSharedDataPointer(CallbackDirectory *p, QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *c)
+ : parent(p), callback(c) { Q_ASSERT(callback); doRef(); }
+
+ void invokeEmpty() override;
+ operator bool () const override { return callback; }
+
+ private:
+ void doRef() override;
+ void doDeref() override;
+ };
+
+ QHash<quint64, CallbackSharedDataPointerBase*> m_callbackMap;
+};
+
+template<typename T>
+inline
+void CallbackDirectory::registerCallback(quint64 callbackId, const QWebEngineCallback<T> &callback)
+{
+ if (!callback.d)
+ return;
+ m_callbackMap.insert(callbackId, new CallbackSharedDataPointer<T>(this, callback.d.data()));
+}
+
+template<typename T>
+inline
+void CallbackDirectory::invokeInternal(quint64 callbackId, T result)
+{
+ CallbackSharedDataPointerBase * const sharedPtrBase = m_callbackMap.take(callbackId);
+ if (!sharedPtrBase)
+ return;
+
+ auto ptr = static_cast<CallbackSharedDataPointer<T> *>(sharedPtrBase);
+ Q_ASSERT(ptr);
+ (*ptr->callback)(std::forward<T>(result));
+ delete ptr;
+}
+
+template<typename T>
+inline
+void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *callback)
+{
+ Q_ASSERT(callback);
+ using NoRefT = typename std::remove_reference<T>::type;
+ using NoConstNoRefT = typename std::remove_const<NoRefT>::type;
+ NoConstNoRefT t;
+ (*callback)(t);
+}
+
+template<>
+inline
+void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<bool> *callback)
+{
+ Q_ASSERT(callback);
+ (*callback)(false);
+}
+
+template<>
+inline
+void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<int> *callback)
+{
+ Q_ASSERT(callback);
+ (*callback)(0);
+}
+
+template<typename T>
+inline
+void CallbackDirectory::invokeEmpty(const QWebEngineCallback<T> &callback)
+{
+ if (!callback.d)
+ return;
+
+ invokeEmptyInternal(callback.d.data());
+}
+
+template <typename T>
+inline
+void CallbackDirectory::CallbackSharedDataPointer<T>::doRef()
+{
+ if (!callback)
+ return;
+
+ callback->ref.ref();
+}
+
+template <typename T>
+inline
+void CallbackDirectory::CallbackSharedDataPointer<T>::doDeref()
+{
+ if (!callback)
+ return;
+ if (!callback->ref.deref())
+ delete callback;
+}
+
+template <typename T>
+inline
+void CallbackDirectory::CallbackSharedDataPointer<T>::invokeEmpty()
+{
+ if (!callback)
+ return;
+
+ Q_ASSERT(parent);
+ parent->invokeEmptyInternal(callback);
+}
+
+} // namespace QtWebEngineCore
+
+#endif // QWEBENGINECALLBACK_P_H
diff --git a/src/core/api/qwebenginecookiestoreclient.cpp b/src/core/api/qwebenginecookiestoreclient.cpp
new file mode 100644
index 000000000..bd43b871d
--- /dev/null
+++ b/src/core/api/qwebenginecookiestoreclient.cpp
@@ -0,0 +1,403 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwebenginecookiestoreclient.h"
+#include "qwebenginecookiestoreclient_p.h"
+
+#include <cookie_monster_delegate_qt.h>
+
+#include <QByteArray>
+#include <QUrl>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QtWebEngineCore;
+
+QWebEngineCookieStoreClientPrivate::QWebEngineCookieStoreClientPrivate(QWebEngineCookieStoreClient* q)
+ : m_nextCallbackId(CallbackDirectory::ReservedCallbackIdsEnd)
+ , m_deleteSessionCookiesPending(false)
+ , m_deleteAllCookiesPending(false)
+ , m_getAllCookiesPending(false)
+ , delegate(0)
+ , q_ptr(q)
+{
+}
+
+QWebEngineCookieStoreClientPrivate::~QWebEngineCookieStoreClientPrivate()
+{
+
+}
+
+void QWebEngineCookieStoreClientPrivate::processPendingUserCookies()
+{
+ Q_ASSERT(delegate);
+ Q_ASSERT(delegate->hasCookieMonster());
+
+ if (m_getAllCookiesPending) {
+ m_getAllCookiesPending = false;
+ delegate->getAllCookies(CallbackDirectory::GetAllCookiesCallbackId);
+ }
+
+ if (m_deleteAllCookiesPending) {
+ m_deleteAllCookiesPending = false;
+ delegate->deleteAllCookies(CallbackDirectory::DeleteAllCookiesCallbackId);
+ }
+
+ if (m_deleteSessionCookiesPending) {
+ m_deleteSessionCookiesPending = false;
+ delegate->deleteSessionCookies(CallbackDirectory::DeleteSessionCookiesCallbackId);
+ }
+
+ if (m_pendingUserCookies.isEmpty())
+ return;
+
+ Q_FOREACH (const auto &cookieData, m_pendingUserCookies) {
+ if (cookieData.callbackId == CallbackDirectory::DeleteCookieCallbackId)
+ delegate->deleteCookie(cookieData.cookie, cookieData.origin);
+ else
+ delegate->setCookie(cookieData.callbackId, cookieData.cookie, cookieData.origin);
+ }
+
+ m_pendingUserCookies.clear();
+}
+
+void QWebEngineCookieStoreClientPrivate::setCookie(const QWebEngineCallback<bool> &callback, const QNetworkCookie &cookie, const QUrl &origin)
+{
+ const quint64 currentCallbackId = callback ? m_nextCallbackId++ : static_cast<quint64>(CallbackDirectory::NoCallbackId);
+
+ if (currentCallbackId != CallbackDirectory::NoCallbackId)
+ callbackDirectory.registerCallback(currentCallbackId, callback);
+
+ if (!delegate || !delegate->hasCookieMonster()) {
+ m_pendingUserCookies.append(CookieData{ currentCallbackId, cookie, origin });
+ return;
+ }
+
+ delegate->setCookie(currentCallbackId, cookie, origin);
+}
+
+void QWebEngineCookieStoreClientPrivate::deleteCookie(const QNetworkCookie &cookie, const QUrl &url)
+{
+ if (!delegate || !delegate->hasCookieMonster()) {
+ m_pendingUserCookies.append(CookieData{ CallbackDirectory::DeleteCookieCallbackId, cookie, url });
+ return;
+ }
+
+ delegate->deleteCookie(cookie, url);
+}
+
+void QWebEngineCookieStoreClientPrivate::deleteSessionCookies()
+{
+ if (!delegate || !delegate->hasCookieMonster()) {
+ m_deleteSessionCookiesPending = true;
+ return;
+ }
+
+ delegate->deleteSessionCookies(CallbackDirectory::DeleteSessionCookiesCallbackId);
+}
+
+void QWebEngineCookieStoreClientPrivate::deleteAllCookies()
+{
+ if (!delegate || !delegate->hasCookieMonster()) {
+ m_deleteAllCookiesPending = true;
+ m_deleteSessionCookiesPending = false;
+ return;
+ }
+
+ delegate->deleteAllCookies(CallbackDirectory::DeleteAllCookiesCallbackId);
+}
+
+void QWebEngineCookieStoreClientPrivate::getAllCookies()
+{
+ if (!delegate || !delegate->hasCookieMonster()) {
+ m_getAllCookiesPending = true;
+ return;
+ }
+
+ delegate->getAllCookies(CallbackDirectory::GetAllCookiesCallbackId);
+}
+
+void QWebEngineCookieStoreClientPrivate::onGetAllCallbackResult(qint64 callbackId, const QByteArray &cookieList)
+{
+ callbackDirectory.invoke(callbackId, cookieList);
+}
+void QWebEngineCookieStoreClientPrivate::onSetCallbackResult(qint64 callbackId, bool success)
+{
+ callbackDirectory.invoke(callbackId, success);
+}
+
+void QWebEngineCookieStoreClientPrivate::onDeleteCallbackResult(qint64 callbackId, int numCookies)
+{
+ callbackDirectory.invoke(callbackId, numCookies);
+}
+
+void QWebEngineCookieStoreClientPrivate::onCookieChanged(const QNetworkCookie &cookie, bool removed)
+{
+ Q_Q(QWebEngineCookieStoreClient);
+ if (removed)
+ Q_EMIT q->cookieRemoved(cookie);
+ else
+ Q_EMIT q->cookieAdded(cookie);
+}
+
+bool QWebEngineCookieStoreClientPrivate::canSetCookie(const QUrl &firstPartyUrl, const QByteArray &cookieLine, const QUrl &url)
+{
+ if (filterCallback) {
+ QWebEngineCookieStoreClient::FilterRequest request;
+ request.accepted = true;
+ request.firstPartyUrl = firstPartyUrl;
+ request.cookieLine = cookieLine;
+ request.cookieSource = url;
+ callbackDirectory.invokeDirectly<QWebEngineCookieStoreClient::FilterRequest&>(filterCallback, request);
+ return request.accepted;
+ }
+ return true;
+}
+
+/*!
+ \class QWebEngineCookieStoreClient
+ \inmodule QtWebEngineCore
+ \since 5.6
+ \brief The QWebEngineCookieStoreClient class provides access to Chromium's cookies.
+
+ The class allows to access HTTP cookies of Chromium for a specific profile.
+ It can be used to synchronize cookies of Chromium and the QNetworkAccessManager, as well as
+ to set, delete, and intercept cookies during navigation.
+ Because cookie operations are asynchronous, the user can choose to provide a callback function
+ to get notified about the success of the operation.
+ The signal handlers for removal and addition should not be used to execute heavy tasks,
+ because they might block the IO thread in case of a blocking connection.
+*/
+
+/*!
+ \class QWebEngineCookieStoreClient::FilterRequest
+ \inmodule QtWebEngineCore
+ \since 5.6
+
+ The structure specifies properties of a cookie, and whether it should accepted or not. It is
+ used as an argument to a filter installed via setCookieFilter().
+*/
+
+/*!
+ \variable QWebEngineCookieStoreClient::FilterRequest::accepted
+ Whether the cookie shall be accepted. The default is \c true.
+ \variable QWebEngineCookieStoreClient::FilterRequest::firstPartyUrl
+ URL of page that triggered the setting of the cookie.
+ \variable QWebEngineCookieStoreClient::FilterRequest::cookieLine
+ Content of the cookie.
+ \variable QWebEngineCookieStoreClient::FilterRequest::cookieSource
+ URL of site that sets the cookie.
+*/
+
+
+/*!
+ \fn void QWebEngineCookieStoreClient::cookieAdded(const QNetworkCookie &cookie)
+
+ This signal is emitted whenever a new \a cookie is added to the cookie store.
+*/
+
+/*!
+ \fn void QWebEngineCookieStoreClient::cookieRemoved(const QNetworkCookie &cookie)
+
+ This signal is emitted whenever a \a cookie is deleted from the cookie store.
+*/
+
+/*!
+ Creates a new QWebEngineCookieStoreClient object with \a parent.
+*/
+
+QWebEngineCookieStoreClient::QWebEngineCookieStoreClient(QObject *parent)
+ : QObject(parent)
+ , d_ptr(new QWebEngineCookieStoreClientPrivate(this))
+{
+
+}
+
+/*!
+ Destroys this QWebEngineCookieStoreClient object.
+*/
+
+QWebEngineCookieStoreClient::~QWebEngineCookieStoreClient()
+{
+
+}
+
+/*!
+ \fn void setCookieWithCallback(const QNetworkCookie &cookie, FunctorOrLambda resultCallback, const QUrl &origin = QUrl())
+
+ Adds \a cookie to the cookie store. When the operation finishes, \a resultCallback will be executed
+ on the caller thread.
+ It is possible to provide an optional \a origin URL argument to limit the scope of the cookie.
+ The provided URL should also include the scheme.
+
+ \sa setCookie()
+*/
+
+void QWebEngineCookieStoreClient::setCookieWithCallback(const QNetworkCookie &cookie, const QWebEngineCallback<bool> &resultCallback, const QUrl &origin)
+{
+ Q_D(QWebEngineCookieStoreClient);
+ d->setCookie(resultCallback, cookie, origin);
+}
+
+/*!
+ Adds \a cookie to the cookie store. This function is provided for convenience and is
+ equivalent to calling setCookieWithCallback() with an empty callback.
+ It is possible to provide an optional \a origin URL argument to limit the scope of the cookie.
+ The provided URL should also include the scheme.
+
+ \sa setCookieWithCallback()
+*/
+
+void QWebEngineCookieStoreClient::setCookie(const QNetworkCookie &cookie, const QUrl &origin)
+{
+ setCookieWithCallback(cookie, QWebEngineCallback<bool>(), origin);
+}
+
+/*!
+ Deletes \a cookie from the cookie store.
+ It is possible to provide an optional \a origin URL argument to limit the scope of the
+ cookie to be deleted.
+ The provided URL should also include the scheme.
+*/
+
+void QWebEngineCookieStoreClient::deleteCookie(const QNetworkCookie &cookie, const QUrl &origin)
+{
+ Q_D(QWebEngineCookieStoreClient);
+ d->deleteCookie(cookie, origin);
+}
+
+/*!
+ \fn void QWebEngineCookieStoreClient::getAllCookies(FunctorOrLambda resultCallback)
+
+ Requests all the cookies in the cookie store. When the asynchronous operation finishes,
+ \a resultCallback will be called with a QByteArray as the argument containing the cookies.
+ This QByteArray can be parsed using QNetworkCookie::parseCookies().
+
+ \sa deleteCookie()
+*/
+
+void QWebEngineCookieStoreClient::getAllCookies(const QWebEngineCallback<const QByteArray&> &resultCallback)
+{
+ Q_D(QWebEngineCookieStoreClient);
+ if (d->m_getAllCookiesPending) {
+ d->callbackDirectory.invokeEmpty(resultCallback);
+ return;
+ }
+ d->callbackDirectory.registerCallback(CallbackDirectory::GetAllCookiesCallbackId, resultCallback);
+ d->getAllCookies();
+}
+
+/*!
+ \fn void QWebEngineCookieStoreClient::deleteSessionCookiesWithCallback(FunctorOrLambda resultCallback)
+
+ Deletes all the session cookies in the cookie store. Session cookies do not have an
+ expiration date assigned to them.
+ When the asynchronous operation finishes, \a resultCallback will be called with the
+ number of cookies deleted as the argument.
+*/
+
+void QWebEngineCookieStoreClient::deleteSessionCookiesWithCallback(const QWebEngineCallback<int> &resultCallback)
+{
+ Q_D(QWebEngineCookieStoreClient);
+ if (d->m_deleteAllCookiesPending || d->m_deleteSessionCookiesPending) {
+ d->callbackDirectory.invokeEmpty(resultCallback);
+ return;
+ }
+ d->callbackDirectory.registerCallback(CallbackDirectory::DeleteSessionCookiesCallbackId, resultCallback);
+ d->deleteSessionCookies();
+}
+
+/*!
+ \fn void QWebEngineCookieStoreClient::deleteAllCookiesWithCallback(FunctorOrLambda resultCallback)
+
+ Deletes all the cookies in the cookie store. When the asynchronous operation finishes,
+ \a resultCallback will be called with the number of cookies deleted as the argument.
+
+ \sa deleteSessionCookiesWithCallback(), getAllCookies()
+*/
+
+void QWebEngineCookieStoreClient::deleteAllCookiesWithCallback(const QWebEngineCallback<int> &resultCallback)
+{
+ Q_D(QWebEngineCookieStoreClient);
+ if (d->m_deleteAllCookiesPending) {
+ d->callbackDirectory.invokeEmpty(resultCallback);
+ return;
+ }
+ d->callbackDirectory.registerCallback(CallbackDirectory::DeleteAllCookiesCallbackId, resultCallback);
+ d->deleteAllCookies();
+}
+
+/*!
+ Deletes all the session cookies in the cookie store.
+
+ \sa deleteSessionCookiesWithCallback()
+*/
+
+void QWebEngineCookieStoreClient::deleteSessionCookies()
+{
+ deleteSessionCookiesWithCallback(QWebEngineCallback<int>());
+}
+
+/*!
+ Deletes all the cookies in the cookie store.
+
+ \sa deleteAllCookiesWithCallback(), getAllCookies()
+*/
+
+void QWebEngineCookieStoreClient::deleteAllCookies()
+{
+ deleteAllCookiesWithCallback(QWebEngineCallback<int>());
+}
+
+/*!
+ \fn void QWebEngineCookieStoreClient::setCookieFilter(FunctorOrLambda filterCallback)
+
+ Installs a cookie filter that can reject cookies before they are added to the cookie store.
+ The \a filterCallback must be a lambda or functor taking FilterRequest structure. If the
+ cookie is to be rejected, the filter can set FilterRequest::accepted to \c false.
+
+ The callback should not be used to execute heavy tasks since it is running on the
+ IO thread and therefore blocks the Chromium networking.
+
+ \sa deleteAllCookiesWithCallback(), getAllCookies()
+*/
+void QWebEngineCookieStoreClient::setCookieFilter(const QWebEngineCallback<QWebEngineCookieStoreClient::FilterRequest&> &filter)
+{
+ Q_D(QWebEngineCookieStoreClient);
+ d->filterCallback = filter;
+}
+
+QT_END_NAMESPACE
diff --git a/src/core/api/qwebenginecookiestoreclient.h b/src/core/api/qwebenginecookiestoreclient.h
new file mode 100644
index 000000000..4664a8459
--- /dev/null
+++ b/src/core/api/qwebenginecookiestoreclient.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINECOOKIESTORECLIENT_H
+#define QWEBENGINECOOKIESTORECLIENT_H
+
+#include "qtwebenginecoreglobal.h"
+#include "qwebenginecallback.h"
+
+#include <QtCore/qobject.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qurl.h>
+#include <QtNetwork/qnetworkcookie.h>
+
+namespace QtWebEngineCore {
+class BrowserContextAdapter;
+class CookieMonsterDelegateQt;
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWebEngineCookieStoreClientPrivate;
+class QWEBENGINE_EXPORT QWebEngineCookieStoreClient : public QObject {
+ Q_OBJECT
+
+public:
+ struct FilterRequest {
+ bool accepted;
+
+ QUrl firstPartyUrl;
+ QByteArray cookieLine;
+ QUrl cookieSource;
+ };
+ virtual ~QWebEngineCookieStoreClient();
+
+#ifdef Q_QDOC
+ void setCookieWithCallback(const QNetworkCookie &cookie, FunctorOrLambda resultCallback, const QUrl &origin = QUrl());
+ void deleteSessionCookiesWithCallback(FunctorOrLambda resultCallback);
+ void deleteAllCookiesWithCallback(FunctorOrLambda resultCallback);
+ void getAllCookies(FunctorOrLambda resultCallback);
+ void setCookieFilter(FunctorOrLambda filterCallback);
+#else
+ void setCookieWithCallback(const QNetworkCookie &cookie, const QWebEngineCallback<bool> &resultCallback, const QUrl &origin = QUrl());
+ void deleteSessionCookiesWithCallback(const QWebEngineCallback<int> &resultCallback);
+ void deleteAllCookiesWithCallback(const QWebEngineCallback<int> &resultCallback);
+ void getAllCookies(const QWebEngineCallback<const QByteArray&> &resultCallback);
+ void setCookieFilter(const QWebEngineCallback<FilterRequest&> &filterCallback);
+#endif
+ void setCookie(const QNetworkCookie &cookie, const QUrl &origin = QUrl());
+ void deleteCookie(const QNetworkCookie &cookie, const QUrl &origin = QUrl());
+ void deleteSessionCookies();
+ void deleteAllCookies();
+
+Q_SIGNALS:
+ void cookieAdded(const QNetworkCookie &cookie);
+ void cookieRemoved(const QNetworkCookie &cookie);
+
+private:
+ explicit QWebEngineCookieStoreClient(QObject *parent = 0);
+ friend class QtWebEngineCore::BrowserContextAdapter;
+ friend class QtWebEngineCore::CookieMonsterDelegateQt;
+ Q_DISABLE_COPY(QWebEngineCookieStoreClient)
+ Q_DECLARE_PRIVATE(QWebEngineCookieStoreClient)
+ QScopedPointer<QWebEngineCookieStoreClientPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QWebEngineCookieStoreClient*)
+
+#endif // QWEBENGINECOOKIESTORECLIENT_H
diff --git a/src/core/api/qwebenginecookiestoreclient_p.h b/src/core/api/qwebenginecookiestoreclient_p.h
new file mode 100644
index 000000000..68ab6549f
--- /dev/null
+++ b/src/core/api/qwebenginecookiestoreclient_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINECOOKIESTORECLIENT_P_H
+#define QWEBENGINECOOKIESTORECLIENT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qtwebenginecoreglobal_p.h"
+
+#include "qwebenginecallback_p.h"
+#include "qwebenginecookiestoreclient.h"
+
+#include <QList>
+#include <QMap>
+#include <QNetworkCookie>
+#include <QUrl>
+
+namespace QtWebEngineCore {
+class CookieMonsterDelegateQt;
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWEBENGINE_PRIVATE_EXPORT QWebEngineCookieStoreClientPrivate {
+ struct CookieData {
+ quint64 callbackId;
+ QNetworkCookie cookie;
+ QUrl origin;
+ };
+
+public:
+ Q_DECLARE_PUBLIC(QWebEngineCookieStoreClient)
+ QtWebEngineCore::CallbackDirectory callbackDirectory;
+ QWebEngineCallback<QWebEngineCookieStoreClient::FilterRequest&> filterCallback;
+ QList<CookieData> m_pendingUserCookies;
+ quint64 m_nextCallbackId;
+ bool m_deleteSessionCookiesPending;
+ bool m_deleteAllCookiesPending;
+ bool m_getAllCookiesPending;
+
+ QtWebEngineCore::CookieMonsterDelegateQt *delegate;
+ QWebEngineCookieStoreClient *q_ptr;
+
+ QWebEngineCookieStoreClientPrivate(QWebEngineCookieStoreClient *q);
+ ~QWebEngineCookieStoreClientPrivate();
+
+ void processPendingUserCookies();
+ void setCookie(const QWebEngineCallback<bool> &callback, const QNetworkCookie &cookie, const QUrl &origin);
+ void deleteCookie(const QNetworkCookie &cookie, const QUrl &url);
+ void deleteSessionCookies();
+ void deleteAllCookies();
+ void getAllCookies();
+
+ bool canSetCookie(const QUrl &firstPartyUrl, const QByteArray &cookieLine, const QUrl &url);
+
+ void onGetAllCallbackResult(qint64 callbackId, const QByteArray &cookieList);
+ void onSetCallbackResult(qint64 callbackId, bool success);
+ void onDeleteCallbackResult(qint64 callbackId, int numCookies);
+ void onCookieChanged(const QNetworkCookie &cookie, bool removed);
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINECOOKIESTORECLIENT_P_H
diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
new file mode 100644
index 000000000..e8ce65be3
--- /dev/null
+++ b/src/core/api/qwebengineurlrequestinfo.cpp
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwebengineurlrequestinfo.h"
+#include "qwebengineurlrequestinfo_p.h"
+
+#include "content/public/common/resource_type.h"
+
+#include "web_contents_adapter_client.h"
+
+QT_BEGIN_NAMESPACE
+
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeMainFrame, content::RESOURCE_TYPE_MAIN_FRAME)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeSubFrame, content::RESOURCE_TYPE_SUB_FRAME)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeStylesheet, content::RESOURCE_TYPE_STYLESHEET)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeScript, content::RESOURCE_TYPE_SCRIPT)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeImage, content::RESOURCE_TYPE_IMAGE)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeFontResource, content::RESOURCE_TYPE_FONT_RESOURCE)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeSubResource, content::RESOURCE_TYPE_SUB_RESOURCE)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeObject, content::RESOURCE_TYPE_OBJECT)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeMedia, content::RESOURCE_TYPE_MEDIA)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeWorker, content::RESOURCE_TYPE_WORKER)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeSharedWorker, content::RESOURCE_TYPE_SHARED_WORKER)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePrefetch, content::RESOURCE_TYPE_PREFETCH)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeFavicon, content::RESOURCE_TYPE_FAVICON)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeXhr, content::RESOURCE_TYPE_XHR)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePing, content::RESOURCE_TYPE_PING)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeServiceWorker, content::RESOURCE_TYPE_SERVICE_WORKER)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeUnknown, content::RESOURCE_TYPE_LAST_TYPE)
+
+ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::LinkNavigation, QWebEngineUrlRequestInfo::NavigationTypeLink)
+ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::TypedNavigation, QWebEngineUrlRequestInfo::NavigationTypeTyped)
+ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::FormSubmittedNavigation, QWebEngineUrlRequestInfo::NavigationTypeFormSubmitted)
+ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::BackForwardNavigation, QWebEngineUrlRequestInfo::NavigationTypeBackForward)
+ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::ReloadNavigation, QWebEngineUrlRequestInfo::NavigationTypeReload)
+ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::OtherNavigation, QWebEngineUrlRequestInfo::NavigationTypeOther)
+
+/*!
+ \class QWebEngineUrlRequestInfo
+ \inmodule QtWebEngineCore
+ \since 5.6
+ \brief The QWebEngineUrlRequestInfo class provides information about URL requests.
+
+ The QWebEngineUrlRequestInfo is useful for setting extra header fields for requests
+ or for redirecting certain requests without payload data to another URL.
+ This class cannot be instantiated or copied by the user, instead it will
+ be created by Qt WebEngine and sent through the virtual function
+ QWebEngineUrlRequestInterceptor::interceptRequest() if an interceptor has been set.
+*/
+
+/*!
+ \class QWebEngineUrlRequestInterceptor
+ \inmodule QtWebEngineCore
+ \since 5.6
+ \brief The QWebEngineUrlRequestInterceptor class provides an abstract base class for URL interception.
+
+ Implementing the \l{QWebEngineUrlRequestInterceptor} interface and installing the
+ interceptor on the profile enables intercepting, blocking, and modifying URL requests
+ before they reach the networking stack of Chromium.
+
+ \sa QWebEngineUrlRequestInterceptor::interceptRequest, QWebEngineUrlRequestInfo
+*/
+
+/*!
+ \fn QWebEngineUrlRequestInterceptor::QWebEngineUrlRequestInterceptor(QObject * p = 0)
+
+ Creates a new QWebEngineUrlRequestInterceptor object with \a p as parent.
+*/
+
+/*!
+ \fn QWebEngineUrlRequestInterceptor::~QWebEngineUrlRequestInterceptor()
+
+ Destroys this QWebEngineUrlRequestInterceptor object.
+*/
+
+/*!
+ \fn bool QWebEngineUrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info)
+
+ Reimplementing this virtual function and setting the interceptor on a profile makes
+ it possible to intercept URL requests. This function is executed on the IO thread,
+ and therefore running long tasks here will block networking.
+ If this function is only used for inspection, it should return \c false, in which
+ case any modification to \a info will be ignored.
+
+ \sa QWebEngineProfile::setRequestInterceptor
+*/
+
+
+QWebEngineUrlRequestInfoPrivate::QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRequestInfo::ResourceType resource, QWebEngineUrlRequestInfo::NavigationType navigation, const QUrl &u, const QUrl &fpu, const QByteArray &m)
+ : resourceType(resource)
+ , navigationType(navigation)
+ , shouldBlockRequest(false)
+ , url(u)
+ , firstPartyUrl(fpu)
+ , method(m)
+{
+}
+
+/*!
+ \internal
+*/
+
+QWebEngineUrlRequestInfo::~QWebEngineUrlRequestInfo()
+{
+
+}
+
+/*!
+ \internal
+*/
+
+QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfoPrivate *p)
+ : d_ptr(p)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ \enum QWebEngineUrlRequestInfo::ResourceType
+
+ This enum type holds the type of the requested resource:
+
+ \value ResourceTypeMainFrame Top level page.
+ \value ResourceTypeSubFrame Frame or iframe.
+ \value ResourceTypeStylesheet A CSS stylesheet.
+ \value ResourceTypeScript An external script.
+ \value ResourceTypeImage An image (JPG, GIF, PNG, and so on).
+ \value ResourceTypeFontResource A font.
+ \value ResourceTypeSubResource An "other" subresource.
+ \value ResourceTypeObject An object (or embed) tag for a plugin or a resource that a plugin requested.
+ \value ResourceTypeMedia A media resource.
+ \value ResourceTypeWorker The main resource of a dedicated worker.
+ \value ResourceTypeSharedWorker The main resource of a shared worker.
+ \value ResourceTypePrefetch An explicitly requested prefetch.
+ \value ResourceTypeFavicon A favicon.
+ \value ResourceTypeXhr An XMLHttpRequest.
+ \value ResourceTypePing A ping request for <a ping>.
+ \value ResourceTypeServiceWorker The main resource of a service worker.
+ \value ResourceTypeUnknown Unknown request type.
+*/
+
+/*!
+ Returns the resource type of the request.
+
+ \sa QWebEngineUrlRequestInfo::ResourceType
+*/
+
+QWebEngineUrlRequestInfo::ResourceType QWebEngineUrlRequestInfo::resourceType() const
+{
+ Q_D(const QWebEngineUrlRequestInfo);
+ return d->resourceType;
+}
+
+/*!
+ \enum QWebEngineUrlRequestInfo::NavigationType
+
+ This enum type describes the navigation type of the request:
+
+ \value NavigationTypeLink Navigation initiated by clicking a link.
+ \value NavigationTypeTyped Navigation explicitly initiated by typing a URL.
+ \value NavigationTypeFormSubmitted Navigation submits a form.
+ \value NavigationTypeBackForward Navigation initiated by a history action.
+ \value NavigationTypeReload Navigation initiated by refreshing the page.
+ \value NavigationTypeOther None of the above.
+*/
+
+/*!
+ Returns the navigation type of the request.
+
+ \sa QWebEngineUrlRequestInfo::NavigationType
+*/
+
+QWebEngineUrlRequestInfo::NavigationType QWebEngineUrlRequestInfo::navigationType() const
+{
+ Q_D(const QWebEngineUrlRequestInfo);
+ return d->navigationType;
+}
+
+/*!
+ Returns the requested URL.
+*/
+
+QUrl QWebEngineUrlRequestInfo::requestUrl() const
+{
+ Q_D(const QWebEngineUrlRequestInfo);
+ return d->url;
+}
+
+/*!
+ Returns the first party URL of the request.
+ The first party URL is the URL of the page that issued the request.
+*/
+
+QUrl QWebEngineUrlRequestInfo::firstPartyUrl() const
+{
+ Q_D(const QWebEngineUrlRequestInfo);
+ return d->firstPartyUrl;
+}
+
+
+/*!
+ Returns the HTTP method of the request (for example, GET or POST).
+*/
+
+QByteArray QWebEngineUrlRequestInfo::requestMethod() const
+{
+ Q_D(const QWebEngineUrlRequestInfo);
+ return d->method;
+}
+
+/*!
+ Redirects this request to \a url.
+ It is only possible to redirect requests that do not have payload data, such as GET requests.
+*/
+
+void QWebEngineUrlRequestInfo::redirect(const QUrl &url)
+{
+ Q_D(QWebEngineUrlRequestInfo);
+ d->url = url;
+}
+
+/*!
+ Blocks this request if \a shouldBlock is true, so that it will not proceed.
+
+ This function can be used to prevent navigating away from a given domain, for example.
+*/
+
+void QWebEngineUrlRequestInfo::block(bool shouldBlock)
+{
+ Q_D(QWebEngineUrlRequestInfo);
+ d->shouldBlockRequest = shouldBlock;
+}
+
+/*!
+ Sets an extra request header for this request with \a name and \a value.
+*/
+
+void QWebEngineUrlRequestInfo::setExtraHeader(const QByteArray &name, const QByteArray &value)
+{
+ Q_D(QWebEngineUrlRequestInfo);
+ d->extraHeaders.insert(name, value);
+}
+
+QT_END_NAMESPACE
diff --git a/src/core/api/qwebengineurlrequestinfo.h b/src/core/api/qwebengineurlrequestinfo.h
new file mode 100644
index 000000000..e6e225051
--- /dev/null
+++ b/src/core/api/qwebengineurlrequestinfo.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINEURLREQUESTINFO_H
+#define QWEBENGINEURLREQUESTINFO_H
+
+#include "qtwebenginecoreglobal.h"
+
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qurl.h>
+
+namespace QtWebEngineCore {
+class NetworkDelegateQt;
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWebEngineUrlRequestInfoPrivate;
+
+class QWEBENGINE_EXPORT QWebEngineUrlRequestInfo {
+public:
+ enum ResourceType {
+ ResourceTypeMainFrame = 0, // top level page
+ ResourceTypeSubFrame, // frame or iframe
+ ResourceTypeStylesheet, // a CSS stylesheet
+ ResourceTypeScript, // an external script
+ ResourceTypeImage, // an image (jpg/gif/png/etc)
+ ResourceTypeFontResource, // a font
+ ResourceTypeSubResource, // an "other" subresource.
+ ResourceTypeObject, // an object (or embed) tag for a plugin,
+ // or a resource that a plugin requested.
+ ResourceTypeMedia, // a media resource.
+ ResourceTypeWorker, // the main resource of a dedicated worker.
+ ResourceTypeSharedWorker, // the main resource of a shared worker.
+ ResourceTypePrefetch, // an explicitly requested prefetch
+ ResourceTypeFavicon, // a favicon
+ ResourceTypeXhr, // a XMLHttpRequest
+ ResourceTypePing, // a ping request for <a ping>
+ ResourceTypeServiceWorker, // the main resource of a service worker.
+ ResourceTypeUnknown
+ };
+
+ enum NavigationType {
+ NavigationTypeLink,
+ NavigationTypeTyped,
+ NavigationTypeFormSubmitted,
+ NavigationTypeBackForward,
+ NavigationTypeReload,
+ NavigationTypeOther
+ };
+
+ ResourceType resourceType() const;
+ NavigationType navigationType() const;
+
+ QUrl requestUrl() const;
+ QUrl firstPartyUrl() const;
+ QByteArray requestMethod() const;
+
+ void block(bool shouldBlock);
+ void redirect(const QUrl &url);
+ void setExtraHeader(const QByteArray &name, const QByteArray &value);
+
+private:
+ friend class QtWebEngineCore::NetworkDelegateQt;
+ Q_DISABLE_COPY(QWebEngineUrlRequestInfo)
+ Q_DECLARE_PRIVATE(QWebEngineUrlRequestInfo)
+
+ QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfoPrivate *p);
+ ~QWebEngineUrlRequestInfo();
+ QScopedPointer<QWebEngineUrlRequestInfoPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINEURLREQUESTINFO_H
diff --git a/src/core/api/qwebengineurlrequestinfo_p.h b/src/core/api/qwebengineurlrequestinfo_p.h
new file mode 100644
index 000000000..1b1279d27
--- /dev/null
+++ b/src/core/api/qwebengineurlrequestinfo_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINEURLREQUESTINFO_P_H
+#define QWEBENGINEURLREQUESTINFO_P_H
+
+#include "qtwebenginecoreglobal_p.h"
+
+#include "qwebengineurlrequestinfo.h"
+
+#include <QByteArray>
+#include <QHash>
+#include <QUrl>
+
+namespace net {
+class URLRequest;
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWebEngineUrlRequestInfoPrivate
+{
+ Q_DECLARE_PUBLIC(QWebEngineUrlRequestInfo)
+public:
+ QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRequestInfo::ResourceType resource
+ , QWebEngineUrlRequestInfo::NavigationType navigation
+ , const QUrl &u
+ , const QUrl &fpu
+ , const QByteArray &m);
+
+ QWebEngineUrlRequestInfo::ResourceType resourceType;
+ QWebEngineUrlRequestInfo::NavigationType navigationType;
+ bool shouldBlockRequest;
+
+ QUrl url;
+ QUrl firstPartyUrl;
+ const QByteArray method;
+ QHash<QByteArray, QByteArray> extraHeaders;
+
+ QWebEngineUrlRequestInfo *q_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINEURLREQUESTINFO_P_H
diff --git a/src/core/api/qwebengineurlrequestinterceptor.h b/src/core/api/qwebengineurlrequestinterceptor.h
new file mode 100644
index 000000000..72f3452d0
--- /dev/null
+++ b/src/core/api/qwebengineurlrequestinterceptor.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENINGEURLREQUESTINTERCEPTOR_H
+#define QWEBENINGEURLREQUESTINTERCEPTOR_H
+
+#include "qtwebenginecoreglobal.h"
+#include "qwebengineurlrequestinfo.h"
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qhash.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qurl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWEBENGINE_EXPORT QWebEngineUrlRequestInterceptor : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWebEngineUrlRequestInterceptor)
+public:
+ explicit QWebEngineUrlRequestInterceptor(QObject *p = 0)
+ : QObject (p)
+ {
+ }
+ virtual ~QWebEngineUrlRequestInterceptor()
+ {
+ }
+
+ virtual bool interceptRequest(QWebEngineUrlRequestInfo &info) = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENINGEURLREQUESTINTERCEPTOR_H
diff --git a/src/webenginewidgets/api/qwebengineurlrequestjob.cpp b/src/core/api/qwebengineurlrequestjob.cpp
index 2bff57236..0e56ba5b3 100644
--- a/src/webenginewidgets/api/qwebengineurlrequestjob.cpp
+++ b/src/core/api/qwebengineurlrequestjob.cpp
@@ -34,9 +34,7 @@
**
****************************************************************************/
-#include "qwebengineurlrequestjob_p.h"
-
-#include "qwebengineprofile.h"
+#include "qwebengineurlrequestjob.h"
#include "url_request_custom_job_delegate.h"
@@ -47,19 +45,36 @@ QT_BEGIN_NAMESPACE
/*!
\class QWebEngineUrlRequestJob
\brief The QWebEngineUrlRequestJob class represents a custom URL request.
- \since 5.5
- \internal
+ \since 5.6
A QWebEngineUrlRequestJob is given to QWebEngineUrlSchemeHandler::requestStarted() and must
- be handled by the derived implementations of class.
+ be handled by the derived implementations of the class. The job can be handled by calling
+ either reply(), redirect(), or fail().
- A job can be handled by calling either setReply(), redirect() or setError().
+ The class is owned by the web engine and does not need to be deleted. However, the web engine
+ may delete the job when it is no longer needed, and therefore the signal QObject::destroyed()
+ must be monitored if a pointer to the object is stored.
- The class is owned by QtWebEngine and does not need to be deleted. Note QtWebEngine may delete
- the job when it is no longer needed, so the signal QObject::destroyed() must be monitored if
- a pointer to the object is stored.
+ \inmodule QtWebEngineCore
+*/
- \inmodule QtWebEngineWidgets
+/*!
+ \enum QWebEngineUrlRequestJob::Error
+
+ This enum type holds the type of the error that occurred:
+
+ \value NoError
+ The request was successful.
+ \value UrlNotFound
+ The requested URL was not found.
+ \value UrlInvalid
+ The requested URL is invalid.
+ \value RequestAborted
+ The request was canceled.
+ \value RequestDenied
+ The request was denied.
+ \value RequestFailed
+ The request failed.
*/
/*!
@@ -79,33 +94,43 @@ QWebEngineUrlRequestJob::~QWebEngineUrlRequestJob()
}
/*!
- Returns the url requested.
- */
+ Returns the requested URL.
+*/
QUrl QWebEngineUrlRequestJob::requestUrl() const
{
return d_ptr->url();
}
/*!
- Sets the reply for the request to \a device with the mime-type \a contentType.
+ Returns the HTTP method of the request (for example, GET or POST).
+*/
+QByteArray QWebEngineUrlRequestJob::requestMethod() const
+{
+ return d_ptr->method();
+}
+
+/*!
+ Replies to the request with \a device and the MIME type \a contentType.
*/
-void QWebEngineUrlRequestJob::setReply(const QByteArray &contentType, QIODevice *device)
+void QWebEngineUrlRequestJob::reply(const QByteArray &contentType, QIODevice *device)
{
d_ptr->setReply(contentType, device);
}
/*!
- Fails the request with error \a error.
+ Fails the request with the error \a r.
+
+ \sa Error
*/
-void QWebEngineUrlRequestJob::setError(Error r)
+void QWebEngineUrlRequestJob::fail(Error r)
{
d_ptr->fail((URLRequestCustomJobDelegate::Error)r);
}
/*!
- Tell the request is redirected to \a url.
+ Redirects the request to \a url.
*/
-void QWebEngineUrlRequestJob::setRedirect(const QUrl &url)
+void QWebEngineUrlRequestJob::redirect(const QUrl &url)
{
d_ptr->redirect(url);
}
diff --git a/src/webenginewidgets/api/qwebengineurlrequestjob_p.h b/src/core/api/qwebengineurlrequestjob.h
index 32e2498fa..fc9f4d911 100644
--- a/src/webenginewidgets/api/qwebengineurlrequestjob_p.h
+++ b/src/core/api/qwebengineurlrequestjob.h
@@ -37,24 +37,14 @@
#ifndef QWEBENGINEURLREQUESTJOB_H
#define QWEBENGINEURLREQUESTJOB_H
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
+#include "qtwebenginecoreglobal.h"
-#include "qtwebenginewidgetsglobal.h"
-
-#include <QtCore/QByteArray>
-#include <QtCore/QObject>
-#include <QtCore/QUrl>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qurl.h>
namespace QtWebEngineCore {
+class URLRequestCustomJob;
class URLRequestCustomJobDelegate;
} // namespace
@@ -62,7 +52,7 @@ QT_BEGIN_NAMESPACE
class QIODevice;
-class QWEBENGINEWIDGETS_EXPORT QWebEngineUrlRequestJob : public QObject {
+class QWEBENGINE_EXPORT QWebEngineUrlRequestJob : public QObject {
Q_OBJECT
public:
~QWebEngineUrlRequestJob();
@@ -75,15 +65,18 @@ public:
RequestDenied,
RequestFailed
};
+ Q_ENUM(Error)
QUrl requestUrl() const;
- void setReply(const QByteArray &contentType, QIODevice *device);
- void setError(Error error);
- void setRedirect(const QUrl &url);
+ QByteArray requestMethod() const;
+
+ void reply(const QByteArray &contentType, QIODevice *device);
+ void fail(Error error);
+ void redirect(const QUrl &url);
private:
QWebEngineUrlRequestJob(QtWebEngineCore::URLRequestCustomJobDelegate *);
- friend class QWebEngineUrlSchemeHandlerPrivate;
+ friend class QtWebEngineCore::URLRequestCustomJob;
QtWebEngineCore::URLRequestCustomJobDelegate* d_ptr;
};
diff --git a/src/core/api/qwebengineurlschemehandler.cpp b/src/core/api/qwebengineurlschemehandler.cpp
new file mode 100644
index 000000000..f887e4e98
--- /dev/null
+++ b/src/core/api/qwebengineurlschemehandler.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwebengineurlschemehandler.h"
+
+#include "qwebengineurlrequestjob.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWebEngineUrlSchemeHandler
+ \brief The QWebEngineUrlSchemeHandler is a base class for handling custom URL schemes.
+ \since 5.6
+
+ To implement a custom URL scheme for QtWebEngine, you must write a class derived from this class,
+ and reimplement requestStarted().
+
+ \inmodule QtWebEngineCore
+
+*/
+
+/*!
+ \fn QWebEngineUrlSchemeHandler::destroyed(QWebEngineUrlSchemeHandler *handler)
+
+ This signal is emitted when the custom URL scheme handler \a handler is deleted.
+*/
+
+/*!
+ Constructs a new URL scheme handler.
+
+ The handler is created with the parent \a parent.
+
+ */
+QWebEngineUrlSchemeHandler::QWebEngineUrlSchemeHandler(QObject *parent)
+ : QObject(parent)
+{
+}
+
+/*!
+ Deletes a custom URL scheme handler.
+*/
+QWebEngineUrlSchemeHandler::~QWebEngineUrlSchemeHandler()
+{
+ Q_EMIT destroyed(this);
+ delete d_ptr;
+}
+
+/*!
+ \fn void QWebEngineUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *request)
+
+ This method is called whenever a request \a request for the registered scheme is started.
+
+ This method must be reimplemented by all custom URL scheme handlers.
+ The request is asynchronous and does not need to be handled right away.
+
+ \sa QWebEngineUrlRequestJob
+*/
+
+QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebengineurlschemehandler_p.h b/src/core/api/qwebengineurlschemehandler.h
index 7de87dff2..8c1e52646 100644
--- a/src/webenginewidgets/api/qwebengineurlschemehandler_p.h
+++ b/src/core/api/qwebengineurlschemehandler.h
@@ -37,45 +37,34 @@
#ifndef QWEBENGINEURLSCHEMEHANDLER_H
#define QWEBENGINEURLSCHEMEHANDLER_H
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
+#include "qtwebenginecoreglobal.h"
-#include "qtwebenginewidgetsglobal.h"
+#include <QtCore/qobject.h>
-#include <QtCore/QByteArray>
-#include <QtCore/QIODevice>
-#include <QtCore/QObject>
-#include <QtCore/QScopedPointer>
-#include <QtCore/QUrl>
+namespace QtWebEngineCore {
+class URLRequestContextGetterQt;
+}
QT_BEGIN_NAMESPACE
-class QWebEngineProfile;
class QWebEngineUrlRequestJob;
class QWebEngineUrlSchemeHandlerPrivate;
-class QWEBENGINEWIDGETS_EXPORT QWebEngineUrlSchemeHandler : public QObject {
+class QWEBENGINE_EXPORT QWebEngineUrlSchemeHandler : public QObject {
Q_OBJECT
public:
- QWebEngineUrlSchemeHandler(const QByteArray &scheme, QWebEngineProfile *profile, QObject *parent = 0);
- virtual ~QWebEngineUrlSchemeHandler();
-
- QByteArray scheme() const;
+ QWebEngineUrlSchemeHandler(QObject *parent = 0);
+ ~QWebEngineUrlSchemeHandler();
virtual void requestStarted(QWebEngineUrlRequestJob*) = 0;
+Q_SIGNALS:
+ void destroyed(QWebEngineUrlSchemeHandler*);
+
private:
+ Q_DISABLE_COPY(QWebEngineUrlSchemeHandler)
Q_DECLARE_PRIVATE(QWebEngineUrlSchemeHandler)
- friend class QWebEngineProfilePrivate;
- QScopedPointer<QWebEngineUrlSchemeHandlerPrivate> d_ptr;
+ QWebEngineUrlSchemeHandlerPrivate *d_ptr;
};
QT_END_NAMESPACE
diff --git a/src/core/authentication_dialog_controller.cpp b/src/core/authentication_dialog_controller.cpp
new file mode 100644
index 000000000..db534a24e
--- /dev/null
+++ b/src/core/authentication_dialog_controller.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "authentication_dialog_controller.h"
+#include "authentication_dialog_controller_p.h"
+
+#include "content/public/browser/browser_thread.h"
+
+namespace QtWebEngineCore {
+
+AuthenticationDialogControllerPrivate::AuthenticationDialogControllerPrivate(ResourceDispatcherHostLoginDelegateQt *loginDelegate)
+ : loginDelegate(loginDelegate)
+{
+}
+
+void AuthenticationDialogControllerPrivate::dialogFinished(bool accepted, const QString &user, const QString &password)
+{
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&ResourceDispatcherHostLoginDelegateQt::sendAuthToRequester, loginDelegate, accepted, user, password));
+}
+
+AuthenticationDialogController::AuthenticationDialogController(AuthenticationDialogControllerPrivate *dd)
+{
+ Q_ASSERT(dd);
+ d.reset(dd);
+}
+
+AuthenticationDialogController::~AuthenticationDialogController()
+{
+}
+
+QUrl AuthenticationDialogController::url() const
+{
+ return d->loginDelegate->url();
+}
+
+QString AuthenticationDialogController::realm() const
+{
+ return d->loginDelegate->realm();
+}
+
+QString AuthenticationDialogController::host() const
+{
+ return d->loginDelegate->host();
+}
+
+bool AuthenticationDialogController::isProxy() const
+{
+ return d->loginDelegate->isProxy();
+}
+
+void AuthenticationDialogController::accept(const QString &user, const QString &password)
+{
+ d->dialogFinished(true, user, password);
+}
+
+void AuthenticationDialogController::reject()
+{
+ d->dialogFinished(false);
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/authentication_dialog_controller.h b/src/core/authentication_dialog_controller.h
new file mode 100644
index 000000000..ae741f537
--- /dev/null
+++ b/src/core/authentication_dialog_controller.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef AUTHENTICATION_DIALOG_CONTROLLER_H
+#define AUTHENTICATION_DIALOG_CONTROLLER_H
+
+#include "qtwebenginecoreglobal.h"
+
+#include <QObject>
+
+namespace QtWebEngineCore {
+
+class AuthenticationDialogControllerPrivate;
+
+class QWEBENGINE_EXPORT AuthenticationDialogController : public QObject {
+ Q_OBJECT
+public:
+ ~AuthenticationDialogController();
+
+ QUrl url() const;
+ QString realm() const;
+ QString host() const;
+ bool isProxy() const;
+
+public Q_SLOTS:
+ void accept(const QString &user, const QString &password);
+ void reject();
+
+private:
+ AuthenticationDialogController(AuthenticationDialogControllerPrivate *);
+
+ QScopedPointer<AuthenticationDialogControllerPrivate> d;
+ friend class ResourceDispatcherHostLoginDelegateQt;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // AUTHENTICATION_DIALOG_CONTROLLER_H
diff --git a/src/core/custom_url_scheme_handler.cpp b/src/core/authentication_dialog_controller_p.h
index b9fcf9c36..5b1d21ae0 100644
--- a/src/core/custom_url_scheme_handler.cpp
+++ b/src/core/authentication_dialog_controller_p.h
@@ -34,34 +34,23 @@
**
****************************************************************************/
-#include "custom_url_scheme_handler.h"
-#include "custom_protocol_handler.h"
+#ifndef AUTHENTICATION_DIALOG_CONTROLLER_P_H
+#define AUTHENTICATION_DIALOG_CONTROLLER_P_H
-namespace QtWebEngineCore {
+#include "base/memory/ref_counted.h"
+#include "resource_dispatcher_host_delegate_qt.h"
-CustomUrlSchemeHandler::CustomUrlSchemeHandler(const QByteArray &scheme)
- : m_scheme(scheme)
-{
-}
+namespace QtWebEngineCore {
-CustomUrlSchemeHandler::~CustomUrlSchemeHandler()
-{
-}
+class AuthenticationDialogControllerPrivate {
-QByteArray CustomUrlSchemeHandler::scheme() const
-{
- return m_scheme;
-}
+public:
+ AuthenticationDialogControllerPrivate(ResourceDispatcherHostLoginDelegateQt *loginDelegate);
+ void dialogFinished(bool accepted, const QString &user = QString(), const QString &password = QString());
-void CustomUrlSchemeHandler::setScheme(const QByteArray &scheme)
-{
- m_scheme = scheme;
-}
+ scoped_refptr<ResourceDispatcherHostLoginDelegateQt> loginDelegate;
+};
-CustomProtocolHandler *CustomUrlSchemeHandler::createProtocolHandler()
-{
- // Will be owned by the JobFactory.
- return new CustomProtocolHandler(this);
-}
+} // namespace QtWebEngineCore
-} // namespace
+#endif // AUTHENTICATION_DIALOG_CONTROLLER_H
diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp
index 7cd5ac21f..ebf99e950 100644
--- a/src/core/browser_accessibility_qt.cpp
+++ b/src/core/browser_accessibility_qt.cpp
@@ -46,7 +46,7 @@
#include "ui/accessibility/ax_node_data.h"
#include "browser_accessibility_manager_qt.h"
-#include "qtwebenginecoreglobal.h"
+#include "qtwebenginecoreglobal_p.h"
#include "type_conversion.h"
using namespace blink;
@@ -86,19 +86,19 @@ void BrowserAccessibilityQt::OnDataChanged()
// always returns the primary name in "name" and the secondary name,
// if any, in "description".
- int title_elem_id = GetIntAttribute(
- ui::AX_ATTR_TITLE_UI_ELEMENT);
- std::string help = GetStringAttribute(ui::AX_ATTR_HELP);
- std::string description = GetStringAttribute(
- ui::AX_ATTR_DESCRIPTION);
+ int title_elem_id = GetIntAttribute(ui::AX_ATTR_TITLE_UI_ELEMENT);
+ base::string16 name = GetString16Attribute(ui::AX_ATTR_NAME);
+ base::string16 description = GetString16Attribute(ui::AX_ATTR_DESCRIPTION);
+ base::string16 help = GetString16Attribute(ui::AX_ATTR_HELP);
+ base::string16 value = GetString16Attribute(ui::AX_ATTR_VALUE);
// WebKit annoyingly puts the title in the description if there's no other
// description, which just confuses the rest of the logic. Put it back.
// Now "help" is always the value of the "title" attribute, if present.
- std::string title_attr;
+ base::string16 title_attr;
if (GetHtmlAttribute("title", &title_attr) &&
- description == title_attr &&
- help.empty()) {
+ description == title_attr &&
+ help.empty()) {
help = description;
description.clear();
}
@@ -107,32 +107,34 @@ void BrowserAccessibilityQt::OnDataChanged()
// it's nonempty, and the help should become the description if
// there's no description - or the name if there's no name or description.
if (!description.empty()) {
- set_name(description);
+ name = description;
description.clear();
}
if (!help.empty() && description.empty()) {
description = help;
help.clear();
}
- if (!description.empty() && name().empty() && !title_elem_id) {
- set_name(description);
+ if (!description.empty() && name.empty() && !title_elem_id) {
+ name = description;
description.clear();
}
// If it's a text field, also consider the placeholder.
- std::string placeholder;
+ base::string16 placeholder;
if (GetRole() == ui::AX_ROLE_TEXT_FIELD &&
- HasState(ui::AX_STATE_FOCUSABLE) &&
- GetHtmlAttribute("placeholder", &placeholder)) {
- if (name().empty() && !title_elem_id) {
- set_name(placeholder);
+ HasState(ui::AX_STATE_FOCUSABLE) &&
+ GetHtmlAttribute("placeholder", &placeholder)) {
+ if (name.empty() && !title_elem_id) {
+ name = placeholder;
} else if (description.empty()) {
description = placeholder;
}
}
- SetStringAttribute(ui::AX_ATTR_DESCRIPTION, description);
- SetStringAttribute(ui::AX_ATTR_HELP, help);
+ m_name = toQt(name);
+ m_description = toQt(description);
+ m_help = toQt(help);
+ m_value = toQt(value);
}
bool BrowserAccessibilityQt::isValid() const
@@ -227,13 +229,13 @@ QString BrowserAccessibilityQt::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
- return toQt(name());
+ return name();
case QAccessible::Description:
- return toQt(GetStringAttribute(ui::AX_ATTR_DESCRIPTION));
+ return description();
case QAccessible::Help:
- return toQt(GetStringAttribute(ui::AX_ATTR_HELP));
+ return help();
case QAccessible::Value:
- return toQt(GetStringAttribute(ui::AX_ATTR_VALUE));
+ return value();
case QAccessible::Accelerator:
return toQt(GetStringAttribute(ui::AX_ATTR_SHORTCUT));
default:
@@ -277,10 +279,10 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::Document; // returning Application here makes Qt return the top level app object
case ui::AX_ROLE_ARTICLE:
return QAccessible::Section;
- case ui::AX_ROLE_BROWSER:
- return QAccessible::Document; // FIXME
case ui::AX_ROLE_BANNER:
return QAccessible::Section;
+ case ui::AX_ROLE_BLOCKQUOTE:
+ return QAccessible::Section;
case ui::AX_ROLE_BUSY_INDICATOR:
return QAccessible::Animation; // FIXME
case ui::AX_ROLE_BUTTON:
@@ -325,10 +327,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::Section;
case ui::AX_ROLE_DOCUMENT:
return QAccessible::Document;
- case ui::AX_ROLE_DRAWER:
- return QAccessible::Client; // FIXME
- case ui::AX_ROLE_EDITABLE_TEXT:
- return QAccessible::EditableText;
case ui::AX_ROLE_EMBEDDED_OBJECT:
return QAccessible::Grouping; // FIXME
case ui::AX_ROLE_FOOTER:
@@ -339,14 +337,8 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::Table;
case ui::AX_ROLE_GROUP:
return QAccessible::Grouping;
- case ui::AX_ROLE_GROW_AREA:
- return QAccessible::Grip;
case ui::AX_ROLE_HEADING:
return QAccessible::Heading;
- case ui::AX_ROLE_HELP_TAG:
- return QAccessible::HelpBalloon; // FIXME
- case ui::AX_ROLE_HORIZONTAL_RULE:
- return QAccessible::Separator;
case ui::AX_ROLE_IFRAME:
return QAccessible::Grouping;
case ui::AX_ROLE_IGNORED:
@@ -357,8 +349,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::Graphic;
case ui::AX_ROLE_IMAGE_MAP_LINK:
return QAccessible::Link;
- case ui::AX_ROLE_INCREMENTOR:
- return QAccessible::NoRole; // FIXME
case ui::AX_ROLE_INLINE_TEXT_BOX:
return QAccessible::EditableText;
case ui::AX_ROLE_LABEL_TEXT:
@@ -387,8 +377,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::NoRole; // FIXME
case ui::AX_ROLE_MATH:
return QAccessible::Equation;
- case ui::AX_ROLE_MATTE:
- return QAccessible::NoRole; // FIXME
case ui::AX_ROLE_MENU:
return QAccessible::PopupMenu;
case ui::AX_ROLE_MENU_BAR:
@@ -413,6 +401,8 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::Paragraph;
case ui::AX_ROLE_POP_UP_BUTTON:
return QAccessible::ComboBox;
+ case ui::AX_ROLE_PRE:
+ return QAccessible::Section;
case ui::AX_ROLE_PRESENTATIONAL:
return QAccessible::NoRole; // FIXME
case ui::AX_ROLE_PROGRESS_INDICATOR:
@@ -429,8 +419,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::RowHeader;
case ui::AX_ROLE_RULER:
return QAccessible::NoRole; // FIXME
- case ui::AX_ROLE_RULER_MARKER:
- return QAccessible::NoRole; // FIXME
case ui::AX_ROLE_SCROLL_AREA:
return QAccessible::Client; // FIXME
case ui::AX_ROLE_SCROLL_BAR:
@@ -439,8 +427,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::NoRole; // FIXME
case ui::AX_ROLE_SEARCH:
return QAccessible::Section;
- case ui::AX_ROLE_SHEET:
- return QAccessible::NoRole; // FIXME
case ui::AX_ROLE_SLIDER:
return QAccessible::Slider;
case ui::AX_ROLE_SLIDER_THUMB:
@@ -451,16 +437,12 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::NoRole; // FIXME
case ui::AX_ROLE_SPLITTER:
return QAccessible::Splitter;
- case ui::AX_ROLE_SPLIT_GROUP:
- return QAccessible::Splitter;
case ui::AX_ROLE_STATIC_TEXT:
return QAccessible::StaticText;
case ui::AX_ROLE_STATUS:
return QAccessible::StatusBar;
case ui::AX_ROLE_SVG_ROOT:
return QAccessible::Graphic;
- case ui::AX_ROLE_SYSTEM_WIDE:
- return QAccessible::NoRole; // FIXME
case ui::AX_ROLE_TABLE:
return QAccessible::Table;
case ui::AX_ROLE_TABLE_HEADER_CONTAINER:
@@ -473,8 +455,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::PageTabList;
case ui::AX_ROLE_TAB_PANEL:
return QAccessible::PageTab;
- case ui::AX_ROLE_TEXT_AREA:
- return QAccessible::EditableText;
case ui::AX_ROLE_TEXT_FIELD:
return QAccessible::EditableText;
case ui::AX_ROLE_TIMER:
@@ -493,8 +473,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::Tree;
case ui::AX_ROLE_TREE_ITEM:
return QAccessible::TreeItem;
- case ui::AX_ROLE_VALUE_INDICATOR:
- return QAccessible::Client; // FIXME
case ui::AX_ROLE_WINDOW:
return QAccessible::Window;
}
diff --git a/src/core/browser_accessibility_qt.h b/src/core/browser_accessibility_qt.h
index 7d58f515e..b7b4c39bc 100644
--- a/src/core/browser_accessibility_qt.h
+++ b/src/core/browser_accessibility_qt.h
@@ -142,6 +142,18 @@ public:
virtual QAccessibleInterface* table() const Q_DECL_OVERRIDE;
virtual void modelChange(QAccessibleTableModelChangeEvent *event) Q_DECL_OVERRIDE;
+
+ QString name() const { return m_name; }
+ QString description() const { return m_description; }
+ QString help() const { return m_help; }
+ QString value() const { return m_value; }
+
+private:
+ // IAccessible name, description, help, value.
+ QString m_name;
+ QString m_description;
+ QString m_help;
+ QString m_value;
};
}
diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp
index a35f313f0..b5fdf2ce0 100644
--- a/src/core/browser_context_adapter.cpp
+++ b/src/core/browser_context_adapter.cpp
@@ -41,6 +41,7 @@
#include "browser_context_qt.h"
#include "content_client_qt.h"
#include "download_manager_delegate_qt.h"
+#include "permission_manager_qt.h"
#include "web_engine_context.h"
#include "web_engine_visited_links_manager.h"
#include "url_request_context_getter_qt.h"
@@ -54,6 +55,8 @@
#include <QStringBuilder>
#include <QStandardPaths>
+#include <numeric>
+
namespace {
inline QString buildLocationFromStandardPath(const QString &standardPath, const QString &name) {
QString location = standardPath;
@@ -133,6 +136,23 @@ DownloadManagerDelegateQt *BrowserContextAdapter::downloadManagerDelegate()
return m_downloadManagerDelegate.data();
}
+QWebEngineCookieStoreClient *BrowserContextAdapter::cookieStoreClient()
+{
+ if (!m_cookieStoreClient)
+ m_cookieStoreClient.reset(new QWebEngineCookieStoreClient);
+ return m_cookieStoreClient.data();
+}
+
+QWebEngineUrlRequestInterceptor *BrowserContextAdapter::requestInterceptor()
+{
+ return m_requestInterceptor.data();
+}
+
+void BrowserContextAdapter::setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
+{
+ m_requestInterceptor = interceptor;
+}
+
void BrowserContextAdapter::addClient(BrowserContextAdapterClient *adapterClient)
{
m_clients.append(adapterClient);
@@ -230,12 +250,12 @@ void BrowserContextAdapter::setHttpUserAgent(const QString &userAgent)
{
if (m_httpUserAgent == userAgent)
return;
- m_httpUserAgent = userAgent;
+ m_httpUserAgent = userAgent.simplified();
std::vector<content::WebContentsImpl *> list = content::WebContentsImpl::GetAllWebContents();
Q_FOREACH (content::WebContentsImpl *web_contents, list)
if (web_contents->GetBrowserContext() == m_browserContext.data())
- web_contents->SetUserAgentOverride(userAgent.toStdString());
+ web_contents->SetUserAgentOverride(m_httpUserAgent.toStdString());
if (m_browserContext->url_request_getter_.get())
m_browserContext->url_request_getter_->updateUserAgent();
@@ -329,7 +349,7 @@ void BrowserContextAdapter::setHttpCacheMaxSize(int maxSize)
m_browserContext->url_request_getter_->updateHttpCache();
}
-QVector<CustomUrlSchemeHandler*> &BrowserContextAdapter::customUrlSchemeHandlers()
+QHash<QByteArray, QWebEngineUrlSchemeHandler *> &BrowserContextAdapter::customUrlSchemeHandlers()
{
return m_customUrlSchemeHandlers;
}
@@ -340,6 +360,37 @@ void BrowserContextAdapter::updateCustomUrlSchemeHandlers()
m_browserContext->url_request_getter_->updateStorageSettings();
}
+bool BrowserContextAdapter::removeCustomUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
+{
+ bool removedOneOrMore = false;
+ auto it = m_customUrlSchemeHandlers.begin();
+ auto end = m_customUrlSchemeHandlers.end();
+ for (; it != end; ++it) {
+ if (it.value() == handler) {
+ it = m_customUrlSchemeHandlers.erase(it);
+ removedOneOrMore = true;
+ continue;
+ }
+ }
+ if (removedOneOrMore)
+ updateCustomUrlSchemeHandlers();
+ return removedOneOrMore;
+}
+
+QWebEngineUrlSchemeHandler *BrowserContextAdapter::takeCustomUrlSchemeHandler(const QByteArray &scheme)
+{
+ QWebEngineUrlSchemeHandler *handler = m_customUrlSchemeHandlers.take(scheme);
+ if (handler)
+ updateCustomUrlSchemeHandlers();
+ return handler;
+}
+
+void BrowserContextAdapter::addCustomUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
+{
+ m_customUrlSchemeHandlers.insert(scheme, handler);
+ updateCustomUrlSchemeHandlers();
+}
+
UserScriptControllerHost *BrowserContextAdapter::userScriptController()
{
if (!m_userScriptController)
@@ -347,4 +398,29 @@ UserScriptControllerHost *BrowserContextAdapter::userScriptController()
return m_userScriptController.data();
}
+void BrowserContextAdapter::permissionRequestReply(const QUrl &origin, PermissionType type, bool reply)
+{
+ static_cast<PermissionManagerQt*>(browserContext()->GetPermissionManager())->permissionRequestReply(origin, type, reply);
+}
+
+QString BrowserContextAdapter::httpAcceptLanguageWithoutQualities() const
+{
+ const QStringList list = m_httpAcceptLanguage.split(QLatin1Char(','));
+ return std::accumulate(list.constBegin(), list.constEnd(), QString(),
+ [](const QString &r, const QString &e) {
+ return (r.isEmpty() ? r : r + QString(QLatin1Char(',')))
+ + e.split(QLatin1Char(';')).first();
+ });
+}
+
+QString BrowserContextAdapter::httpAcceptLanguage() const
+{
+ return m_httpAcceptLanguage;
+}
+
+void BrowserContextAdapter::setHttpAcceptLanguage(const QString &httpAcceptLanguage)
+{
+ m_httpAcceptLanguage = httpAcceptLanguage;
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/browser_context_adapter.h b/src/core/browser_context_adapter.h
index 42787bc23..818dfda3d 100644
--- a/src/core/browser_context_adapter.h
+++ b/src/core/browser_context_adapter.h
@@ -40,18 +40,22 @@
#include "qtwebenginecoreglobal.h"
#include <QList>
+#include <QPointer>
#include <QScopedPointer>
#include <QSharedData>
#include <QString>
#include <QVector>
+#include "api/qwebenginecookiestoreclient.h"
+#include "api/qwebengineurlrequestinterceptor.h"
+#include "api/qwebengineurlschemehandler.h"
+
QT_FORWARD_DECLARE_CLASS(QObject)
namespace QtWebEngineCore {
class BrowserContextAdapterClient;
class BrowserContextQt;
-class CustomUrlSchemeHandler;
class DownloadManagerDelegateQt;
class UserScriptControllerHost;
class WebEngineVisitedLinksManager;
@@ -69,6 +73,11 @@ public:
WebEngineVisitedLinksManager *visitedLinksManager();
DownloadManagerDelegateQt *downloadManagerDelegate();
+ QWebEngineCookieStoreClient *cookieStoreClient();
+
+ QWebEngineUrlRequestInterceptor* requestInterceptor();
+ void setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
+
QList<BrowserContextAdapterClient*> clients() { return m_clients; }
void addClient(BrowserContextAdapterClient *adapterClient);
void removeClient(BrowserContextAdapterClient *adapterClient);
@@ -113,6 +122,13 @@ public:
TrackVisitedLinksOnDisk,
};
+ enum PermissionType {
+ UnsupportedPermission = 0,
+ GeolocationPermission = 1,
+// Reserved:
+// NotificationPermission = 2,
+ };
+
HttpCacheType httpCacheType() const;
void setHttpCacheType(BrowserContextAdapter::HttpCacheType);
@@ -128,10 +144,19 @@ public:
bool trackVisitedLinks() const;
bool persistVisitedLinks() const;
- QVector<CustomUrlSchemeHandler*> &customUrlSchemeHandlers();
+ QHash<QByteArray, QWebEngineUrlSchemeHandler *> &customUrlSchemeHandlers();
void updateCustomUrlSchemeHandlers();
+ void addCustomUrlSchemeHandler(const QByteArray &, QWebEngineUrlSchemeHandler *);
+ bool removeCustomUrlSchemeHandler(QWebEngineUrlSchemeHandler *);
+ QWebEngineUrlSchemeHandler *takeCustomUrlSchemeHandler(const QByteArray &);
UserScriptControllerHost *userScriptController();
+ void permissionRequestReply(const QUrl &origin, PermissionType type, bool reply);
+
+ QString httpAcceptLanguageWithoutQualities() const;
+ QString httpAcceptLanguage() const;
+ void setHttpAcceptLanguage(const QString &httpAcceptLanguage);
+
private:
QString m_name;
bool m_offTheRecord;
@@ -139,14 +164,17 @@ private:
QScopedPointer<WebEngineVisitedLinksManager> m_visitedLinksManager;
QScopedPointer<DownloadManagerDelegateQt> m_downloadManagerDelegate;
QScopedPointer<UserScriptControllerHost> m_userScriptController;
+ QScopedPointer<QWebEngineCookieStoreClient> m_cookieStoreClient;
+ QPointer<QWebEngineUrlRequestInterceptor> m_requestInterceptor;
QString m_dataPath;
QString m_cachePath;
QString m_httpUserAgent;
HttpCacheType m_httpCacheType;
+ QString m_httpAcceptLanguage;
PersistentCookiesPolicy m_persistentCookiesPolicy;
VisitedLinksPolicy m_visitedLinksPolicy;
- QVector<CustomUrlSchemeHandler*> m_customUrlSchemeHandlers;
+ QHash<QByteArray, QWebEngineUrlSchemeHandler *> m_customUrlSchemeHandlers;
QList<BrowserContextAdapterClient*> m_clients;
int m_httpCacheMaxSize;
diff --git a/src/core/browser_context_qt.cpp b/src/core/browser_context_qt.cpp
index 7f285b1e5..28486cced 100644
--- a/src/core/browser_context_qt.cpp
+++ b/src/core/browser_context_qt.cpp
@@ -38,9 +38,10 @@
#include "browser_context_adapter.h"
#include "download_manager_delegate_qt.h"
-#include "type_conversion.h"
-#include "qtwebenginecoreglobal.h"
+#include "permission_manager_qt.h"
+#include "qtwebenginecoreglobal_p.h"
#include "resource_context_qt.h"
+#include "type_conversion.h"
#include "url_request_context_getter_qt.h"
#include "base/time/time.h"
@@ -134,6 +135,18 @@ content::SSLHostStateDelegate* BrowserContextQt::GetSSLHostStateDelegate()
return 0;
}
+scoped_ptr<content::ZoomLevelDelegate> BrowserContextQt::CreateZoomLevelDelegate(const base::FilePath&)
+{
+ return nullptr;
+}
+
+content::PermissionManager *BrowserContextQt::GetPermissionManager()
+{
+ if (!permissionManager)
+ permissionManager.reset(new PermissionManagerQt(m_adapter));
+ return permissionManager.get();
+}
+
net::URLRequestContextGetter *BrowserContextQt::CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers)
{
url_request_getter_ = new URLRequestContextGetterQt(m_adapter, protocol_handlers);
diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h
index af36b55ab..eccd684a3 100644
--- a/src/core/browser_context_qt.h
+++ b/src/core/browser_context_qt.h
@@ -47,6 +47,7 @@
namespace QtWebEngineCore {
class BrowserContextAdapter;
+class PermissionManagerQt;
class URLRequestContextGetterQt;
class BrowserContextQt : public content::BrowserContext
@@ -72,13 +73,17 @@ public:
virtual content::PushMessagingService* GetPushMessagingService() Q_DECL_OVERRIDE;
virtual content::SSLHostStateDelegate* GetSSLHostStateDelegate() Q_DECL_OVERRIDE;
net::URLRequestContextGetter *CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers);
+ virtual scoped_ptr<content::ZoomLevelDelegate> CreateZoomLevelDelegate(const base::FilePath& partition_path) Q_DECL_OVERRIDE;
+ virtual content::PermissionManager *GetPermissionManager() Q_DECL_OVERRIDE;
+
+ BrowserContextAdapter *adapter() { return m_adapter; }
- BrowserContextAdapter* adapter() { return m_adapter; }
private:
friend class ContentBrowserClientQt;
friend class WebContentsAdapter;
scoped_ptr<content::ResourceContext> resourceContext;
scoped_refptr<URLRequestContextGetterQt> url_request_getter_;
+ scoped_ptr<PermissionManagerQt> permissionManager;
BrowserContextAdapter *m_adapter;
friend class BrowserContextAdapter;
diff --git a/src/core/chrome_qt.gyp b/src/core/chrome_qt.gyp
index 703ce7525..0f30b7a04 100644
--- a/src/core/chrome_qt.gyp
+++ b/src/core/chrome_qt.gyp
@@ -19,6 +19,8 @@
'<(chromium_src_dir)/chrome/browser/media/desktop_streams_registry.cc',
'<(chromium_src_dir)/chrome/browser/media/desktop_streams_registry.h',
'<(chromium_src_dir)/chrome/browser/media/desktop_media_list.h',
+ '<(chromium_src_dir)/chrome/common/chrome_switches.cc',
+ '<(chromium_src_dir)/chrome/common/chrome_switches.h',
'<(chromium_src_dir)/chrome/common/localized_error.cc',
'<(chromium_src_dir)/chrome/common/localized_error.h',
],
diff --git a/src/core/chromium_gpu_helper.cpp b/src/core/chromium_gpu_helper.cpp
index ef574eccd..9dfc498ad 100644
--- a/src/core/chromium_gpu_helper.cpp
+++ b/src/core/chromium_gpu_helper.cpp
@@ -43,18 +43,18 @@
// Including gpu/command_buffer headers before content/gpu headers makes sure that
// guards are defined to prevent duplicate definition errors with forward declared
// GL typedefs cascading through content header includes.
+#include "gpu/command_buffer/service/sync_point_manager.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "content/common/gpu/gpu_channel_manager.h"
-#include "content/common/gpu/sync_point_manager.h"
#include "content/gpu/gpu_child_thread.h"
#ifdef Q_OS_QNX
#include "content/common/gpu/stream_texture_qnx.h"
#endif
-static void addSyncPointCallbackDelegate(content::SyncPointManager *syncPointManager, uint32 sync_point, const base::Closure& callback)
+static void addSyncPointCallbackDelegate(gpu::SyncPointManager *syncPointManager, uint32 sync_point, const base::Closure& callback)
{
syncPointManager->AddSyncPointCallback(sync_point, callback);
}
@@ -78,13 +78,13 @@ base::MessageLoop *gpu_message_loop()
return content::GpuChildThread::instance()->message_loop();
}
-content::SyncPointManager *sync_point_manager()
+gpu::SyncPointManager *sync_point_manager()
{
content::GpuChannelManager *gpuChannelManager = content::GpuChildThread::instance()->ChannelManager();
return gpuChannelManager->sync_point_manager();
}
-void AddSyncPointCallbackOnGpuThread(base::MessageLoop *gpuMessageLoop, content::SyncPointManager *syncPointManager, uint32 sync_point, const base::Closure& callback)
+void AddSyncPointCallbackOnGpuThread(base::MessageLoop *gpuMessageLoop, gpu::SyncPointManager *syncPointManager, uint32 sync_point, const base::Closure& callback)
{
// We need to set our callback from the GPU thread, where the SyncPointManager lives.
gpuMessageLoop->PostTask(FROM_HERE, base::Bind(&addSyncPointCallbackDelegate, make_scoped_refptr(syncPointManager), sync_point, callback));
diff --git a/src/core/chromium_gpu_helper.h b/src/core/chromium_gpu_helper.h
index 936ad1d24..6242dd068 100644
--- a/src/core/chromium_gpu_helper.h
+++ b/src/core/chromium_gpu_helper.h
@@ -47,12 +47,9 @@ namespace base {
class MessageLoop;
}
-namespace content {
-class SyncPointManager;
-}
-
namespace gpu {
struct Mailbox;
+class SyncPointManager;
namespace gles2 {
class MailboxManager;
class Texture;
@@ -66,10 +63,10 @@ class Texture;
QMap<uint32, gfx::TransferableFence> transferFences();
base::MessageLoop *gpu_message_loop();
-content::SyncPointManager *sync_point_manager();
+gpu::SyncPointManager *sync_point_manager();
gpu::gles2::MailboxManager *mailbox_manager();
-void AddSyncPointCallbackOnGpuThread(base::MessageLoop *gpuMessageLoop, content::SyncPointManager *syncPointManager, uint32 sync_point, const base::Closure& callback);
+void AddSyncPointCallbackOnGpuThread(base::MessageLoop *gpuMessageLoop, gpu::SyncPointManager *syncPointManager, uint32 sync_point, const base::Closure& callback);
gpu::gles2::Texture* ConsumeTexture(gpu::gles2::MailboxManager *mailboxManager, unsigned target, const gpu::Mailbox& mailbox);
unsigned int service_id(gpu::gles2::Texture *tex);
diff --git a/src/core/chromium_overrides.cpp b/src/core/chromium_overrides.cpp
index 5af8a6ad8..b9ce722dd 100644
--- a/src/core/chromium_overrides.cpp
+++ b/src/core/chromium_overrides.cpp
@@ -37,8 +37,9 @@
#include "chromium_overrides.h"
#include "gl_context_qt.h"
-#include "qtwebenginecoreglobal.h"
+#include "qtwebenginecoreglobal_p.h"
#include "web_contents_view_qt.h"
+
#include "base/values.h"
#include "content/browser/renderer_host/pepper/pepper_truetype_font_list.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
@@ -47,6 +48,8 @@
#include <QGuiApplication>
#include <QScreen>
#include <QWindow>
+#include <QFontDatabase>
+#include <QStringList>
#if defined(USE_X11)
#include "ui/gfx/x/x11_types.h"
@@ -115,8 +118,17 @@ namespace content {
// content/common/font_list.h
scoped_ptr<base::ListValue> GetFontList_SlowBlocking()
{
- QT_NOT_USED
- return scoped_ptr<base::ListValue>(new base::ListValue);
+ scoped_ptr<base::ListValue> font_list(new base::ListValue);
+
+ QFontDatabase database;
+ for (auto family : database.families()){
+ base::ListValue* font_item = new base::ListValue();
+ font_item->Append(new base::StringValue(family.toStdString()));
+ font_item->Append(new base::StringValue(family.toStdString())); // should be localized name.
+ // TODO: Support localized family names.
+ font_list->Append(font_item);
+ }
+ return font_list.Pass();
}
#if defined(ENABLE_PLUGINS)
@@ -142,39 +154,6 @@ OSExchangeData::Provider* OSExchangeData::CreateProvider()
return 0;
}
-}
-
-namespace gfx {
-
-// Stubs for these unused functions that are stripped in case
-// of a release aura build but a debug build needs the symbols.
-
-RenderText* RenderText::CreateNativeInstance()
-{
- QT_NOT_USED;
- return 0;
-}
-
-#if defined(OS_LINUX)
-PlatformFont* PlatformFont::CreateDefault()
-{
- QT_NOT_USED;
- return 0;
-}
-
-PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont)
-{
- QT_NOT_USED;
- return 0;
-}
-
-PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string&, int)
-{
- QT_NOT_USED;
- return 0;
-}
-#endif
-
-} // namespace gfx
+} // namespace ui
#endif // defined(USE_AURA) && !defined(USE_OZONE)
diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp
index 797f5c7f4..206392840 100644
--- a/src/core/clipboard_qt.cpp
+++ b/src/core/clipboard_qt.cpp
@@ -331,7 +331,7 @@ SkBitmap ClipboardQt::ReadImage(ui::ClipboardType type) const
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
QImage image = qvariant_cast<QImage>(mimeData->imageData());
- Q_ASSERT(image.format() == QImage::Format_ARGB32);
+ image = image.convertToFormat(QImage::Format_ARGB32);
SkBitmap bitmap;
bitmap.setInfo(SkImageInfo::MakeN32(image.width(), image.height(), kOpaque_SkAlphaType));
bitmap.setPixels(const_cast<uchar*>(image.constBits()));
@@ -361,7 +361,7 @@ void ClipboardQt::ReadData(const FormatType& format, std::string* result) const
*result = std::string(byteArray.constData(), byteArray.length());
}
-uint64 ClipboardQt::GetSequenceNumber(ui::ClipboardType type)
+uint64 ClipboardQt::GetSequenceNumber(ui::ClipboardType type) const
{
return clipboardChangeObserver()->getSequenceNumber(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
}
diff --git a/src/core/clipboard_qt.h b/src/core/clipboard_qt.h
index 4c7e6ab59..ee1fc7440 100644
--- a/src/core/clipboard_qt.h
+++ b/src/core/clipboard_qt.h
@@ -62,7 +62,7 @@ private:
class ClipboardQt : public ui::Clipboard {
public:
- virtual uint64 GetSequenceNumber(ui::ClipboardType type) Q_DECL_OVERRIDE;
+ virtual uint64 GetSequenceNumber(ui::ClipboardType type) const Q_DECL_OVERRIDE;
virtual bool IsFormatAvailable(const FormatType& format, ui::ClipboardType type) const Q_DECL_OVERRIDE;
virtual void Clear(ui::ClipboardType type) Q_DECL_OVERRIDE;
virtual void ReadAvailableTypes(ui::ClipboardType type, std::vector<base::string16>* types, bool* contains_filenames) const Q_DECL_OVERRIDE;
diff --git a/src/core/common/qt_messages.h b/src/core/common/qt_messages.h
index c692ee5ca..25a995b27 100644
--- a/src/core/common/qt_messages.h
+++ b/src/core/common/qt_messages.h
@@ -31,6 +31,9 @@ IPC_MESSAGE_ROUTED1(QtRenderViewObserver_FetchDocumentMarkup,
IPC_MESSAGE_ROUTED1(QtRenderViewObserver_FetchDocumentInnerText,
uint64 /* requestId */)
+IPC_MESSAGE_ROUTED1(QtRenderViewObserver_SetBackgroundColor,
+ uint32 /* color */)
+
IPC_MESSAGE_ROUTED1(WebChannelIPCTransport_Message, std::vector<char> /*binaryJSON*/)
// User scripts messages
diff --git a/src/core/config/desktop_linux.pri b/src/core/config/desktop_linux.pri
index 041b094a1..f0bf6cb23 100644
--- a/src/core/config/desktop_linux.pri
+++ b/src/core/config/desktop_linux.pri
@@ -1,21 +1,10 @@
GYP_ARGS += "-D qt_os=\"desktop_linux\""
+include(linux.pri)
+
GYP_CONFIG += \
desktop_linux=1 \
- toolkit_uses_gtk=0 \
- use_aura=1 \
- use_ash=0 \
- use_cairo=0 \
- use_clipboard_aurax11=0 \
- use_cups=0 \
- use_gconf=0 \
- use_gio=0 \
- use_gnome_keyring=0 \
- use_kerberos=0 \
- use_pango=0 \
- host_clang=0 \
- clang=0 \
-
-contains(QT_CONFIG, system-jpeg): GYP_CONFIG += use_system_libjpeg=1
+ enable_plugins=1 \
-!contains(QT_CONFIG, pulseaudio): GYP_CONFIG += use_pulseaudio=0
+linux-clang: GYP_CONFIG += clang=1 host_clang=1 clang_use_chrome_plugins=0 make_clang_dir=/usr
+else: GYP_CONFIG += clang=0 host_clang=0
diff --git a/src/core/config/embedded_linux.pri b/src/core/config/embedded_linux.pri
index cc8c40f8e..50f94147e 100644
--- a/src/core/config/embedded_linux.pri
+++ b/src/core/config/embedded_linux.pri
@@ -1,7 +1,8 @@
GYP_ARGS += "-D qt_os=\"embedded_linux\" -I config/embedded_linux.gypi"
+include(linux.pri)
+
GYP_CONFIG += \
- build_ffmpegsumo=1 \
clang=0 \
desktop_linux=0 \
disable_nacl=1 \
@@ -24,31 +25,17 @@ GYP_CONFIG += \
gtest_target_type=none \
host_clang=0 \
notifications=0 \
+ ozone_auto_platforms=0 \
ozone_platform_dri=0 \
ozone_platform_test=0 \
p2p_apis=0 \
safe_browsing=0 \
toolkit_views=1 \
- use_ash=0 \
- use_aura=1 \
- use_cairo=0 \
- use_clipboard_aurax11=0 \
- use_cups=0 \
use_custom_freetype=0 \
- use_gconf=0 \
- use_gio=0 \
- use_gnome_keyring=0 \
- use_kerberos=0 \
use_libpci=0 \
- use_openssl=1 \
use_ozone=1 \
- use_pango=0 \
use_system_fontconfig=1 \
- use_system_icu=1 \
icu_use_data_file_flag=0 \
use_x11=0 \
v8_use_snapshot=false \
want_separate_host_toolset=1 \
-
-contains(QT_CONFIG, system-jpeg): GYP_CONFIG += use_system_libjpeg=1
-!contains(QT_CONFIG, pulseaudio): GYP_CONFIG += use_pulseaudio=0
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
new file mode 100644
index 000000000..8d736d0c1
--- /dev/null
+++ b/src/core/config/linux.pri
@@ -0,0 +1,45 @@
+# linux_use_bundled_gold currently relies on a hardcoded relative path from chromium/src/out/(Release|Debug)
+# Disable it along with the -Wl,--threads flag just in case gold isn't installed on the system.
+GYP_CONFIG += \
+ linux_use_bundled_gold=0 \
+ linux_use_bundled_binutils=0 \
+ linux_use_gold_flags=0 \
+
+GYP_CONFIG += \
+ toolkit_uses_gtk=0 \
+ use_ash=0 \
+ use_aura=1 \
+ use_cairo=0 \
+ use_clipboard_aurax11=0 \
+ use_cups=0 \
+ use_gconf=0 \
+ use_gio=0 \
+ use_gnome_keyring=0 \
+ use_kerberos=0 \
+ use_pango=0
+
+!use?(nss) {
+ GYP_CONFIG += use_nss_certs=0 \
+ use_openssl=1 \
+ use_openssl_certs=1
+}
+
+contains(QT_CONFIG, system-zlib): use?(system_minizip): GYP_CONFIG += use_system_zlib=1
+contains(QT_CONFIG, system-png): GYP_CONFIG += use_system_libpng=1
+contains(QT_CONFIG, system-jpeg): GYP_CONFIG += use_system_libjpeg=1
+contains(QT_CONFIG, system-harfbuzz): GYP_CONFIG += use_system_harfbuzz=1
+!contains(QT_CONFIG, pulseaudio): GYP_CONFIG += use_pulseaudio=0
+
+use?(system_libevent): GYP_CONFIG += use_system_libevent=1
+use?(system_libwebp): GYP_CONFIG += use_system_libwebp=1
+use?(system_libsrtp): GYP_CONFIG += use_system_libsrtp=1
+use?(system_libxslt): GYP_CONFIG += use_system_libxml=1
+use?(system_flac): GYP_CONFIG += use_system_flac=1
+use?(system_jsoncpp): GYP_CONFIG += use_system_jsoncpp=1
+use?(system_opus): GYP_CONFIG += use_system_opus=1
+use?(system_snappy): GYP_CONFIG += use_system_snappy=1
+use?(system_speex): GYP_CONFIG += use_system_speex=1
+use?(system_vpx): GYP_CONFIG += use_system_libvpx=1
+use?(system_icu): GYP_CONFIG += use_system_icu=1
+use?(system_ffmpeg): GYP_CONFIG += use_system_ffmpeg=1
+
diff --git a/src/core/config/mac_osx.pri b/src/core/config/mac_osx.pri
index 3f42b6fd7..93c77623c 100644
--- a/src/core/config/mac_osx.pri
+++ b/src/core/config/mac_osx.pri
@@ -14,7 +14,8 @@ GYP_CONFIG += \
mac_sdk_min=\"10.7\" \
mac_deployment_target=\"$${QMAKE_MACOSX_DEPLOYMENT_TARGET}\" \
make_clang_dir=\"$${QMAKE_CLANG_DIR}\" \
- clang_use_chrome_plugins=0
+ clang_use_chrome_plugins=0 \
+ enable_plugins=1
QMAKE_MAC_SDK_PATH = "$$eval(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.path)"
exists($$QMAKE_MAC_SDK_PATH): GYP_CONFIG += mac_sdk_path=\"$${QMAKE_MAC_SDK_PATH}\"
diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri
index f7644c83b..602afbc67 100644
--- a/src/core/config/windows.pri
+++ b/src/core/config/windows.pri
@@ -28,3 +28,17 @@ contains(QT_CONFIG, angle) {
GYP_ARGS += "-D qt_gl=\"opengl\""
}
+msvc {
+ equals(MSVC_VER, 12.0) {
+ MSVS_VERSION = 2013
+ } else:equals(MSVC_VER, 14.0) {
+ MSVS_VERSION = 2015
+ } else {
+ fatal("Visual Studio compiler version \"$$MSVC_VER\" is not supported by Qt WebEngine")
+ }
+
+ GYP_ARGS += "-G msvs_version=$$MSVS_VERSION"
+
+} else {
+ fatal("Qt WebEngine for Windows can only be built with the Microsoft Visual Studio C++ compiler")
+}
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index fdfbaf0f5..91cd0b0c4 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -56,6 +56,7 @@
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_share_group.h"
+#include "ui/gl/gpu_timing.h"
#include "access_token_store_qt.h"
#include "browser_context_adapter.h"
@@ -74,6 +75,12 @@
#include "web_engine_context.h"
#include "web_engine_library_info.h"
+#if defined(ENABLE_PLUGINS)
+#include "content/public/browser/browser_ppapi_host.h"
+#include "ppapi/host/ppapi_host.h"
+#include "renderer/pepper/pepper_host_factory_qt.h"
+#endif
+
#include <QGuiApplication>
#include <QLocale>
#include <QOpenGLContext>
@@ -277,7 +284,11 @@ public:
virtual bool MakeCurrent(gfx::GLSurface *) Q_DECL_OVERRIDE { Q_UNREACHABLE(); return false; }
virtual void ReleaseCurrent(gfx::GLSurface *) Q_DECL_OVERRIDE { Q_UNREACHABLE(); }
virtual bool IsCurrent(gfx::GLSurface *) Q_DECL_OVERRIDE { Q_UNREACHABLE(); return false; }
- virtual void SetSwapInterval(int) Q_DECL_OVERRIDE { Q_UNREACHABLE(); }
+ virtual void OnSetSwapInterval(int) Q_DECL_OVERRIDE { Q_UNREACHABLE(); }
+ virtual scoped_refptr<gfx::GPUTimingClient> CreateGPUTimingClient() Q_DECL_OVERRIDE
+ {
+ return nullptr;
+ }
private:
void *m_handle;
@@ -360,9 +371,8 @@ content::MediaObserver *ContentBrowserClientQt::GetMediaObserver()
return MediaCaptureDevicesDispatcher::GetInstance();
}
-void ContentBrowserClientQt::OverrideWebkitPrefs(content::RenderViewHost *rvh, const GURL &url, content::WebPreferences *web_prefs)
+void ContentBrowserClientQt::OverrideWebkitPrefs(content::RenderViewHost *rvh, content::WebPreferences *web_prefs)
{
- Q_UNUSED(url);
if (content::WebContents *webContents = rvh->GetDelegate()->GetAsWebContents())
static_cast<WebContentsDelegateQt*>(webContents->GetDelegate())->overrideWebPreferences(webContents, web_prefs);
}
@@ -402,41 +412,6 @@ void ContentBrowserClientQt::AllowCertificateError(int render_process_id, int re
contentsDelegate->allowCertificateError(errorController);
}
-void ContentBrowserClientQt::RequestPermission(content::PermissionType permission,
- content::WebContents* web_contents,
- int bridge_id,
- const GURL& requesting_frame,
- bool user_gesture,
- const base::Callback<void(bool)>& result_callback)
-{
- Q_UNUSED(bridge_id);
- Q_UNUSED(user_gesture);
- WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(web_contents->GetDelegate());
- Q_ASSERT(contentsDelegate);
- if (permission == content::PERMISSION_GEOLOCATION)
- contentsDelegate->requestGeolocationPermission(requesting_frame, result_callback);
- else
- result_callback.Run(false);
-}
-
-
-void ContentBrowserClientQt::CancelPermissionRequest(content::PermissionType permission,
- content::WebContents* web_contents,
- int bridge_id,
- const GURL& requesting_frame)
-{
- Q_UNUSED(bridge_id);
- WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(web_contents->GetDelegate());
- Q_ASSERT(contentsDelegate);
- if (permission == content::PERMISSION_GEOLOCATION)
- contentsDelegate->cancelGeolocationPermissionRequest(requesting_frame);
-}
-
-blink::WebNotificationPermission ContentBrowserClientQt::CheckDesktopNotificationPermission(const GURL&, content::ResourceContext *, int )
-{
- return blink::WebNotificationPermission::WebNotificationPermissionDenied;
-}
-
content::LocationProvider *ContentBrowserClientQt::OverrideSystemLocationProvider()
{
#ifdef QT_USE_POSITIONING
@@ -451,6 +426,11 @@ std::string ContentBrowserClientQt::GetApplicationLocale()
return WebEngineLibraryInfo::getApplicationLocale();
}
+std::string ContentBrowserClientQt::GetAcceptLangs(content::BrowserContext *context)
+{
+ return static_cast<BrowserContextQt*>(context)->adapter()->httpAcceptLanguage().toStdString();
+}
+
void ContentBrowserClientQt::AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id)
{
Q_UNUSED(child_process_id);
@@ -460,6 +440,13 @@ void ContentBrowserClientQt::AppendExtraCommandLineSwitches(base::CommandLine* c
command_line->AppendSwitchASCII(switches::kLang, GetApplicationLocale());
}
+#if defined(ENABLE_PLUGINS)
+ void ContentBrowserClientQt::DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) {
+ browser_host->GetPpapiHost()->AddHostFactoryFilter(
+ scoped_ptr<ppapi::host::HostFactory>(new QtWebEngineCore::PepperHostFactoryQt(browser_host)));
+ }
+#endif
+
content::DevToolsManagerDelegate* ContentBrowserClientQt::GetDevToolsManagerDelegate()
{
return new DevToolsManagerDelegateQt;
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index 0af5ae9d3..eea7d2a22 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -40,7 +40,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/content_browser_client.h"
-#include "third_party/WebKit/public/platform/WebNotificationPermission.h"
+#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationPermission.h"
#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE
@@ -51,6 +51,11 @@ class URLRequestContextGetter;
namespace content {
class BrowserContext;
class BrowserMainParts;
+
+#if defined(ENABLE_PLUGINS)
+class BrowserPpapiHost;
+#endif
+
class DevToolsManagerDelegate;
class RenderProcessHost;
class RenderViewHostDelegateView;
@@ -83,7 +88,7 @@ public:
virtual content::MediaObserver* GetMediaObserver() Q_DECL_OVERRIDE;
virtual content::AccessTokenStore* CreateAccessTokenStore() Q_DECL_OVERRIDE;
virtual content::QuotaPermissionContext *CreateQuotaPermissionContext() Q_DECL_OVERRIDE;
- virtual void OverrideWebkitPrefs(content::RenderViewHost *, const GURL &, content::WebPreferences *) Q_DECL_OVERRIDE;
+ virtual void OverrideWebkitPrefs(content::RenderViewHost *, content::WebPreferences *) Q_DECL_OVERRIDE;
virtual void AllowCertificateError(
int render_process_id,
int render_frame_id,
@@ -96,26 +101,18 @@ public:
bool expired_previous_decision,
const base::Callback<void(bool)>& callback,
content::CertificateRequestResultType* result) Q_DECL_OVERRIDE;
- virtual void RequestPermission(
- content::PermissionType permission,
- content::WebContents* web_contents,
- int bridge_id,
- const GURL& requesting_frame,
- bool user_gesture,
- const base::Callback<void(bool)>& result_callback) Q_DECL_OVERRIDE;
- virtual void CancelPermissionRequest(content::PermissionType permission,
- content::WebContents* web_contents,
- int bridge_id,
- const GURL& requesting_frame) Q_DECL_OVERRIDE;
content::LocationProvider* OverrideSystemLocationProvider() Q_DECL_OVERRIDE;
content::DevToolsManagerDelegate *GetDevToolsManagerDelegate() Q_DECL_OVERRIDE;
virtual net::URLRequestContextGetter *CreateRequestContext(content::BrowserContext *browser_context, content::ProtocolHandlerMap *protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptorss) Q_DECL_OVERRIDE;
- virtual blink::WebNotificationPermission CheckDesktopNotificationPermission(const GURL& source_origin, content::ResourceContext* context, int render_process_id) Q_DECL_OVERRIDE;
-
virtual std::string GetApplicationLocale() Q_DECL_OVERRIDE;
+ std::string GetAcceptLangs(content::BrowserContext* context) Q_DECL_OVERRIDE;
virtual void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) Q_DECL_OVERRIDE;
+#if defined(ENABLE_PLUGINS)
+ virtual void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) Q_DECL_OVERRIDE;
+#endif
+
private:
BrowserMainPartsQt* m_browserMainParts;
scoped_ptr<ResourceDispatcherHostDelegateQt> m_resourceDispatcherHostDelegate;
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 20a8df75e..01e1fe383 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -36,11 +36,119 @@
#include "content_client_qt.h"
+#include "base/command_line.h"
#include "base/strings/string_piece.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "content/public/common/content_constants.h"
#include "content/public/common/user_agent.h"
#include "ui/base/layout.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
+#include "type_conversion.h"
+
+#include <QCoreApplication>
+#include <QFile>
+#include <QStringBuilder>
+
+#if defined(ENABLE_PLUGINS)
+#include "content/public/common/pepper_plugin_info.h"
+#include "ppapi/shared_impl/ppapi_permissions.h"
+
+static const int32 kPepperFlashPermissions = ppapi::PERMISSION_DEV |
+ ppapi::PERMISSION_PRIVATE |
+ ppapi::PERMISSION_BYPASS_USER_GESTURE |
+ ppapi::PERMISSION_FLASH;
+
+namespace switches {
+const char kPpapiFlashPath[] = "ppapi-flash-path";
+const char kPpapiFlashVersion[] = "ppapi-flash-version";
+}
+
+// Adopted from chrome_content_client.cc
+content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path, const std::string& version)
+{
+ content::PepperPluginInfo plugin;
+
+ plugin.is_out_of_process = true;
+ plugin.name = content::kFlashPluginName;
+ plugin.path = path;
+ plugin.permissions = kPepperFlashPermissions;
+
+ std::vector<std::string> flash_version_numbers;
+ base::SplitString(version, '.', &flash_version_numbers);
+ if (flash_version_numbers.size() < 1)
+ flash_version_numbers.push_back("11");
+ else if (flash_version_numbers[0].empty())
+ flash_version_numbers[0] = "11";
+ if (flash_version_numbers.size() < 2)
+ flash_version_numbers.push_back("2");
+ if (flash_version_numbers.size() < 3)
+ flash_version_numbers.push_back("999");
+ if (flash_version_numbers.size() < 4)
+ flash_version_numbers.push_back("999");
+
+ // E.g., "Shockwave Flash 10.2 r154":
+ plugin.description = plugin.name + " " + flash_version_numbers[0] + "." + flash_version_numbers[1] + " r" + flash_version_numbers[2];
+ plugin.version = JoinString(flash_version_numbers, '.');
+ content::WebPluginMimeType swf_mime_type(content::kFlashPluginSwfMimeType,
+ content::kFlashPluginSwfExtension,
+ content::kFlashPluginSwfDescription);
+ plugin.mime_types.push_back(swf_mime_type);
+ content::WebPluginMimeType spl_mime_type(content::kFlashPluginSplMimeType,
+ content::kFlashPluginSplExtension,
+ content::kFlashPluginSplDescription);
+ plugin.mime_types.push_back(spl_mime_type);
+
+ return plugin;
+}
+
+void AddPepperFlashFromSystem(std::vector<content::PepperPluginInfo>* plugins)
+{
+ QStringList pluginPaths;
+#if defined(Q_OS_WIN) && defined(Q_PROCESSOR_X86_32)
+ QDir pluginDir("C:/Windows/SysWOW64/Macromed/Flash");
+ pluginDir.setFilter(QDir::Files);
+ QStringList nameFilters("pepflashplayer*.dll");
+ pluginPaths << pluginDir.entryList(nameFilters);
+#endif
+#if defined(Q_OS_OSX)
+ pluginPaths << "/Library/Internet Plug-Ins/PepperFlashPlayer/PepperFlashPlayer.plugin"; // Mac OS X
+#endif
+#if defined(Q_OS_LINUX)
+ pluginPaths << "/usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so" // Ubuntu
+ << "/usr/lib/PepperFlash/libpepflashplayer.so" // Arch
+ << "/usr/lib64/chromium/PepperFlash/libpepflashplayer.so"; // OpenSuSE
+#endif
+ for (auto it = pluginPaths.constBegin(); it != pluginPaths.constEnd(); ++it) {
+ if (!QFile(*it).exists())
+ continue;
+ plugins->push_back(CreatePepperFlashInfo(QtWebEngineCore::toFilePath(*it), std::string()));
+ return;
+ }
+}
+
+void AddPepperFlashFromCommandLine(std::vector<content::PepperPluginInfo>* plugins)
+{
+ const base::CommandLine::StringType flash_path = base::CommandLine::ForCurrentProcess()->GetSwitchValueNative(switches::kPpapiFlashPath);
+ if (flash_path.empty() || !QFile(QtWebEngineCore::toQt(flash_path)).exists())
+ return;
+
+ // Read pepper flash plugin version from command-line. (e.g. 16.0.0.235)
+ std::string flash_version = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kPpapiFlashVersion);
+ plugins->push_back(CreatePepperFlashInfo(base::FilePath(flash_path), flash_version));
+}
+
+namespace QtWebEngineCore {
+
+void ContentClientQt::AddPepperPlugins(std::vector<content::PepperPluginInfo>* plugins)
+{
+ AddPepperFlashFromSystem(plugins);
+ AddPepperFlashFromCommandLine(plugins);
+}
+
+}
+#endif
#include <QCoreApplication>
#include <QStringBuilder>
diff --git a/src/core/content_client_qt.h b/src/core/content_client_qt.h
index f68282dcf..309e049dc 100644
--- a/src/core/content_client_qt.h
+++ b/src/core/content_client_qt.h
@@ -48,6 +48,10 @@ class ContentClientQt : public content::ContentClient {
public:
static std::string getUserAgent();
+#if defined(ENABLE_PLUGINS)
+ virtual void AddPepperPlugins(std::vector<content::PepperPluginInfo>* plugins) Q_DECL_OVERRIDE;
+#endif
+
virtual base::StringPiece GetDataResource(int, ui::ScaleFactor) const Q_DECL_OVERRIDE;
virtual std::string GetUserAgent() const Q_DECL_OVERRIDE { return getUserAgent(); }
virtual base::string16 GetLocalizedString(int message_id) const Q_DECL_OVERRIDE;
diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp
index 4003823b1..0688fb015 100644
--- a/src/core/content_main_delegate_qt.cpp
+++ b/src/core/content_main_delegate_qt.cpp
@@ -72,7 +72,7 @@ void ContentMainDelegateQt::PreSandboxStartup()
// Suppress info, warning and error messages per default.
int logLevel = logging::LOG_FATAL;
- CommandLine* parsedCommandLine = CommandLine::ForCurrentProcess();
+ base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess();
if (parsedCommandLine->HasSwitch(switches::kLoggingLevel)) {
std::string logLevelValue = parsedCommandLine->GetSwitchValueASCII(switches::kLoggingLevel);
int level = 0;
diff --git a/src/core/cookie_monster_delegate_qt.cpp b/src/core/cookie_monster_delegate_qt.cpp
new file mode 100644
index 000000000..7622614ca
--- /dev/null
+++ b/src/core/cookie_monster_delegate_qt.cpp
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cookie_monster_delegate_qt.h"
+
+#include "base/bind.h"
+#include "content/public/browser/browser_thread.h"
+#include "net/cookies/cookie_util.h"
+
+#include "api/qwebenginecookiestoreclient.h"
+#include "api/qwebenginecookiestoreclient_p.h"
+#include "type_conversion.h"
+
+#include <QStringBuilder>
+
+namespace QtWebEngineCore {
+
+static GURL sourceUrlForCookie(const QNetworkCookie &cookie) {
+ QString urlFragment = QStringLiteral("%1%2").arg(cookie.domain()).arg(cookie.path());
+ return net::cookie_util::CookieOriginToURL(urlFragment.toStdString(), /* is_https */ cookie.isSecure());
+}
+
+static void onSetCookieCallback(QWebEngineCookieStoreClientPrivate *client, qint64 callbackId, bool success) {
+ client->onSetCallbackResult(callbackId, success);
+}
+
+static void onDeleteCookiesCallback(QWebEngineCookieStoreClientPrivate *client, qint64 callbackId, int numCookies) {
+ client->onDeleteCallbackResult(callbackId, numCookies);
+}
+
+static void onGetAllCookiesCallback(QWebEngineCookieStoreClientPrivate *client, qint64 callbackId, const net::CookieList& cookies) {
+ QByteArray rawCookies;
+ for (auto&& cookie: cookies)
+ rawCookies += toQt(cookie).toRawForm() % QByteArrayLiteral("\n");
+
+ client->onGetAllCallbackResult(callbackId, rawCookies);
+}
+
+CookieMonsterDelegateQt::CookieMonsterDelegateQt()
+ : m_client(0)
+ , m_cookieMonster(0)
+{
+
+}
+
+CookieMonsterDelegateQt::~CookieMonsterDelegateQt()
+{
+
+}
+
+bool CookieMonsterDelegateQt::hasCookieMonster()
+{
+ return m_cookieMonster.get();
+}
+
+void CookieMonsterDelegateQt::getAllCookies(quint64 callbackId)
+{
+ net::CookieMonster::GetCookieListCallback callback = base::Bind(&onGetAllCookiesCallback, m_client->d_func(), callbackId);
+ m_cookieMonster->GetAllCookiesAsync(callback);
+}
+
+void CookieMonsterDelegateQt::setCookie(quint64 callbackId, const QNetworkCookie &cookie, const QUrl &origin)
+{
+ Q_ASSERT(hasCookieMonster());
+ Q_ASSERT(m_client);
+
+ net::CookieStore::SetCookiesCallback callback;
+ if (callbackId != CallbackDirectory::NoCallbackId)
+ callback = base::Bind(&onSetCookieCallback, m_client->d_func(), callbackId);
+
+ net::CookieOptions options;
+ options.set_include_httponly();
+
+ GURL gurl = origin.isEmpty() ? sourceUrlForCookie(cookie) : toGurl(origin);
+
+ m_cookieMonster->SetCookieWithOptionsAsync(gurl, cookie.toRawForm().toStdString(), options, callback);
+}
+
+void CookieMonsterDelegateQt::deleteCookie(const QNetworkCookie &cookie, const QUrl &origin)
+{
+ Q_ASSERT(hasCookieMonster());
+ Q_ASSERT(m_client);
+
+ GURL gurl = origin.isEmpty() ? sourceUrlForCookie(cookie) : toGurl(origin);
+
+ m_cookieMonster->DeleteCookieAsync(gurl, cookie.name().toStdString(), base::Closure());
+}
+
+void CookieMonsterDelegateQt::deleteSessionCookies(quint64 callbackId)
+{
+ Q_ASSERT(hasCookieMonster());
+ Q_ASSERT(m_client);
+
+ net::CookieMonster::DeleteCallback callback = base::Bind(&onDeleteCookiesCallback, m_client->d_func(), callbackId);
+ m_cookieMonster->DeleteSessionCookiesAsync(callback);
+}
+
+void CookieMonsterDelegateQt::deleteAllCookies(quint64 callbackId)
+{
+ Q_ASSERT(hasCookieMonster());
+ Q_ASSERT(m_client);
+
+ net::CookieMonster::DeleteCallback callback = base::Bind(&onDeleteCookiesCallback, m_client->d_func(), callbackId);
+ m_cookieMonster->DeleteAllAsync(callback);
+}
+
+void CookieMonsterDelegateQt::setCookieMonster(net::CookieMonster* monster)
+{
+ m_cookieMonster = monster;
+
+ if (m_client)
+ m_client->d_func()->processPendingUserCookies();
+}
+
+void CookieMonsterDelegateQt::setClient(QWebEngineCookieStoreClient *client)
+{
+ m_client = client;
+
+ if (!m_client)
+ return;
+
+ m_client->d_ptr->delegate = this;
+
+ if (hasCookieMonster())
+ m_client->d_func()->processPendingUserCookies();
+}
+
+bool CookieMonsterDelegateQt::canSetCookie(const QUrl &firstPartyUrl, const QByteArray &cookieLine, const QUrl &url)
+{
+ if (!m_client)
+ return true;
+
+ return m_client->d_ptr->canSetCookie(firstPartyUrl, cookieLine, url);
+}
+
+void CookieMonsterDelegateQt::OnCookieChanged(const net::CanonicalCookie& cookie, bool removed, ChangeCause cause)
+{
+ if (!m_client)
+ return;
+ m_client->d_ptr->onCookieChanged(toQt(cookie), removed);
+}
+
+}
diff --git a/src/core/cookie_monster_delegate_qt.h b/src/core/cookie_monster_delegate_qt.h
new file mode 100644
index 000000000..7592d57fa
--- /dev/null
+++ b/src/core/cookie_monster_delegate_qt.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COOKIE_MONSTER_DELEGATE_QT_H
+#define COOKIE_MONSTER_DELEGATE_QT_H
+
+#include "qtwebenginecoreglobal.h"
+
+QT_WARNING_PUSH
+// For some reason adding -Wno-unused-parameter to QMAKE_CXXFLAGS has no
+// effect with clang, so use a pragma for these dirty chromium headers
+QT_WARNING_DISABLE_CLANG("-Wunused-parameter")
+#include "base/memory/ref_counted.h"
+#include "net/cookies/cookie_monster.h"
+QT_WARNING_POP
+
+#include <QList>
+#include <QNetworkCookie>
+#include <QPointer>
+
+QT_FORWARD_DECLARE_CLASS(QWebEngineCookieStoreClient)
+
+namespace QtWebEngineCore {
+
+// Extends net::CookieMonster::kDefaultCookieableSchemes with qrc, without enabling
+// cookies for the file:// scheme, which is disabled by default in Chromium.
+// Since qrc:// is similar to file:// and there are some unknowns about how
+// to correctly handle file:// cookies, qrc:// should only be used for testing.
+static const char* const kCookieableSchemes[] =
+ { "http", "https", "qrc", "ws", "wss" };
+
+class QWEBENGINE_EXPORT CookieMonsterDelegateQt: public net::CookieMonsterDelegate {
+ QPointer<QWebEngineCookieStoreClient> m_client;
+ scoped_refptr<net::CookieMonster> m_cookieMonster;
+public:
+ CookieMonsterDelegateQt();
+ ~CookieMonsterDelegateQt();
+
+ bool hasCookieMonster();
+
+ void setCookie(quint64 callbackId, const QNetworkCookie &cookie, const QUrl &origin);
+ void deleteCookie(const QNetworkCookie &cookie, const QUrl &origin);
+ void getAllCookies(quint64 callbackId);
+ void deleteSessionCookies(quint64 callbackId);
+ void deleteAllCookies(quint64 callbackId);
+
+ void setCookieMonster(net::CookieMonster* monster);
+ void setClient(QWebEngineCookieStoreClient *client);
+
+ bool canSetCookie(const QUrl &firstPartyUrl, const QByteArray &cookieLine, const QUrl &url);
+ void OnCookieChanged(const net::CanonicalCookie& cookie, bool removed, ChangeCause cause) override;
+};
+
+}
+
+#endif // COOKIE_MONSTER_DELEGATE_QT_H
diff --git a/src/core/core.pro b/src/core/core.pro
index cf00f39cb..7ddad4ed6 100644
--- a/src/core/core.pro
+++ b/src/core/core.pro
@@ -8,13 +8,14 @@ core_gyp_generator.file = core_gyp_generator.pro
gyp_run.file = gyp_run.pro
gyp_run.depends = core_gyp_generator
+core_api.file = api/core_api.pro
+core_api.depends = gyp_run
+
# This will take the compile output of ninja, and link+deploy the final binary.
core_module.file = core_module.pro
-core_module.depends = gyp_run
+core_module.depends = core_api
-SUBDIRS += core_gyp_generator \
- gyp_run \
- core_module
+SUBDIRS += core_gyp_generator
!win32 {
# gyp_configure_host.pro and gyp_configure_target.pro are phony pro files that
@@ -28,3 +29,7 @@ SUBDIRS += core_gyp_generator \
gyp_run.depends += gyp_configure_host gyp_configure_target
SUBDIRS += gyp_configure_host gyp_configure_target
}
+
+SUBDIRS += gyp_run \
+ core_api \
+ core_module
diff --git a/src/core/core_common.pri b/src/core/core_common.pri
index cefde4302..1ea4e1862 100644
--- a/src/core/core_common.pri
+++ b/src/core/core_common.pri
@@ -6,7 +6,7 @@ QT += qml quick webchannel
QT_PRIVATE += quick-private gui-private core-private
# Make QtCreator happy.
-CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$${getChromiumSrcDir()}
+CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$$getChromiumSrcDir()
INCLUDEPATH += $$CHROMIUM_SRC_DIR
qtHaveModule(positioning):QT += positioning
diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro
index c745fd19e..813626dc3 100644
--- a/src/core/core_gyp_generator.pro
+++ b/src/core/core_gyp_generator.pro
@@ -18,17 +18,18 @@ DEFINES += QT_NO_KEYWORDS \
# Assume that we want mobile touch and low-end hardware behaviors
# whenever we are cross compiling.
-cross_compile: DEFINES += QTWEBENGINE_MOBILE_SWITCHES
+cross_compile: DEFINES += QTWEBENGINE_EMBEDDED_SWITCHES
contains(QT_CONFIG, egl): CONFIG += egl
else: DEFINES += QT_NO_EGL
RESOURCES += devtools.qrc
-INCLUDEPATH += $$PWD
+INCLUDEPATH += $$PWD $$PWD/api
SOURCES = \
access_token_store_qt.cpp \
+ authentication_dialog_controller.cpp \
browser_accessibility_manager_qt.cpp \
browser_accessibility_qt.cpp \
browser_context_adapter.cpp \
@@ -42,12 +43,13 @@ SOURCES = \
content_client_qt.cpp \
content_browser_client_qt.cpp \
content_main_delegate_qt.cpp \
+ cookie_monster_delegate_qt.cpp \
custom_protocol_handler.cpp \
- custom_url_scheme_handler.cpp \
delegated_frame_node.cpp \
desktop_screen_qt.cpp \
dev_tools_http_handler_delegate_qt.cpp \
download_manager_delegate_qt.cpp \
+ file_picker_controller.cpp \
gl_context_qt.cpp \
gl_surface_qt.cpp \
javascript_dialog_controller.cpp \
@@ -56,11 +58,18 @@ SOURCES = \
native_web_keyboard_event_qt.cpp \
network_delegate_qt.cpp \
ozone_platform_eglfs.cpp \
+ permission_manager_qt.cpp \
process_main.cpp \
+ proxy_config_service_qt.cpp \
qrc_protocol_handler_qt.cpp \
qt_render_view_observer_host.cpp \
render_widget_host_view_qt.cpp \
renderer/content_renderer_client_qt.cpp \
+ renderer/pepper/pepper_flash_browser_host_qt.cpp \
+ renderer/pepper/pepper_flash_renderer_host_qt.cpp \
+ renderer/pepper/pepper_host_factory_qt.cpp \
+ renderer/pepper/pepper_renderer_host_factory_qt.cpp \
+ renderer/qt_render_frame_observer.cpp \
renderer/qt_render_view_observer.cpp \
renderer/user_script_controller.cpp \
renderer/web_channel_ipc_transport.cpp \
@@ -89,6 +98,8 @@ SOURCES = \
HEADERS = \
access_token_store_qt.h \
+ authentication_dialog_controller_p.h \
+ authentication_dialog_controller.h \
browser_accessibility_manager_qt.h \
browser_accessibility_qt.h \
browser_context_adapter.h \
@@ -103,13 +114,14 @@ HEADERS = \
content_client_qt.h \
content_browser_client_qt.h \
content_main_delegate_qt.h \
+ cookie_monster_delegate_qt.h \
custom_protocol_handler.h \
- custom_url_scheme_handler.h \
delegated_frame_node.h \
desktop_screen_qt.h \
dev_tools_http_handler_delegate_qt.h \
download_manager_delegate_qt.h \
chromium_gpu_helper.h \
+ file_picker_controller.h \
gl_context_qt.h \
gl_surface_qt.h \
javascript_dialog_controller_p.h \
@@ -118,13 +130,19 @@ HEADERS = \
media_capture_devices_dispatcher.h \
network_delegate_qt.h \
ozone_platform_eglfs.h \
+ permission_manager_qt.h \
process_main.h \
+ proxy_config_service_qt.h \
qrc_protocol_handler_qt.h \
qt_render_view_observer_host.h \
- qtwebenginecoreglobal.h \
render_widget_host_view_qt.h \
render_widget_host_view_qt_delegate.h \
renderer/content_renderer_client_qt.h \
+ renderer/pepper/pepper_flash_browser_host_qt.h \
+ renderer/pepper/pepper_flash_renderer_host_qt.h \
+ renderer/pepper/pepper_host_factory_qt.h \
+ renderer/pepper/pepper_renderer_host_factory_qt.h \
+ renderer/qt_render_frame_observer.h \
renderer/qt_render_view_observer.h \
renderer/user_script_controller.h \
renderer/web_channel_ipc_transport.h \
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index e6a36332f..68d46cd5a 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -9,10 +9,31 @@ QMAKE_INFO_PLIST = Info_mac.plist
error("Could not find the linking information that gyp should have generated.")
}
-# We distribute the module binary but headers are only available in-tree.
-CONFIG += no_module_headers
load(qt_module)
+api_library_name = qtwebenginecoreapi$$qtPlatformTargetSuffix()
+api_library_path = $$OUT_PWD/api/$$getConfigDir()
+
+
+LIBS_PRIVATE += -L$$api_library_path
+CONFIG *= no_smart_library_merge
+osx {
+ LIBS_PRIVATE += -Wl,-force_load,$${api_library_path}$${QMAKE_DIR_SEP}lib$${api_library_name}.a
+} else:msvc {
+ # Simulate -whole-archive by passing the list of object files that belong to the public
+ # API library as response file to the linker.
+ QMAKE_LFLAGS += /OPT:REF
+ QMAKE_LFLAGS += @$${api_library_path}$${QMAKE_DIR_SEP}$${api_library_name}.lib.objects
+} else {
+ LIBS_PRIVATE += -Wl,-whole-archive -l$$api_library_name -Wl,-no-whole-archive
+}
+
+win32-msvc* {
+ POST_TARGETDEPS += $${api_library_path}$${QMAKE_DIR_SEP}$${api_library_name}.lib
+} else {
+ POST_TARGETDEPS += $${api_library_path}$${QMAKE_DIR_SEP}lib$${api_library_name}.a
+}
+
# Using -Wl,-Bsymbolic-functions seems to confuse the dynamic linker
# and doesn't let Chromium get access to libc symbols through dlsym.
CONFIG -= bsymbolic_functions
@@ -31,17 +52,8 @@ resources.files = $$REPACK_DIR/qtwebengine_resources.pak \
$$REPACK_DIR/qtwebengine_resources_100p.pak \
$$REPACK_DIR/qtwebengine_resources_200p.pak
-PLUGIN_EXTENSION = .so
-PLUGIN_PREFIX = lib
-osx: PLUGIN_PREFIX =
-win32 {
- PLUGIN_EXTENSION = .dll
- PLUGIN_PREFIX =
-}
icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat
-plugins.files = $$OUT_PWD/$$getConfigDir()/$${PLUGIN_PREFIX}ffmpegsumo$${PLUGIN_EXTENSION}
-
!debug_and_release|!build_all|CONFIG(release, debug|release) {
contains(QT_CONFIG, qt_framework) {
locales.version = Versions
@@ -50,12 +62,10 @@ plugins.files = $$OUT_PWD/$$getConfigDir()/$${PLUGIN_PREFIX}ffmpegsumo$${PLUGIN_
resources.path = Resources
icu.version = Versions
icu.path = Resources
- plugins.version = Versions
- plugins.path = Libraries
# No files, this prepares the bundle Helpers symlink, process.pro will create the directories
qtwebengineprocessplaceholder.version = Versions
qtwebengineprocessplaceholder.path = Helpers
- QMAKE_BUNDLE_DATA += icu locales resources plugins qtwebengineprocessplaceholder
+ QMAKE_BUNDLE_DATA += icu locales resources qtwebengineprocessplaceholder
} else {
locales.CONFIG += no_check_exist
locales.path = $$[QT_INSTALL_TRANSLATIONS]/qtwebengine_locales
@@ -63,9 +73,7 @@ plugins.files = $$OUT_PWD/$$getConfigDir()/$${PLUGIN_PREFIX}ffmpegsumo$${PLUGIN_
resources.path = $$[QT_INSTALL_DATA]
icu.CONFIG += no_check_exist
icu.path = $$[QT_INSTALL_DATA]
- plugins.CONFIG += no_check_exist
- plugins.path = $$[QT_INSTALL_PLUGINS]/qtwebengine
- INSTALLS += icu locales resources plugins
+ INSTALLS += icu locales resources
}
!contains(QT_CONFIG, qt_framework): contains(QT_CONFIG, private_tests) {
@@ -75,15 +83,7 @@ plugins.files = $$OUT_PWD/$$getConfigDir()/$${PLUGIN_PREFIX}ffmpegsumo$${PLUGIN_
unix: icu_rule.commands = if [ -e $$ICU_FILE ] ; then $$QMAKE_COPY $$ICU_FILE $$ICU_TARGET ; fi
win32: icu_rule.commands = if exist $$ICU_FILE ( $$QMAKE_COPY $$ICU_FILE $$ICU_TARGET )
- PLUGIN_DIR = $$shell_path($$[QT_INSTALL_PLUGINS/get]/qtwebengine)
- PLUGIN_TARGET = $$shell_path($$PLUGIN_DIR/$${PLUGIN_PREFIX}ffmpegsumo$${PLUGIN_EXTENSION})
- PLUGIN_FILE = $$shell_path($$OUT_PWD/$$getConfigDir()/$${PLUGIN_PREFIX}ffmpegsumo$${PLUGIN_EXTENSION})
- plugins_rule.target = $$PLUGIN_TARGET
- unix: plugins_rule.commands = $$QMAKE_MKDIR $$PLUGIN_DIR && if [ -e $$PLUGIN_FILE ] ; then $$QMAKE_COPY $$PLUGIN_FILE $$PLUGIN_TARGET ; fi
- win32: plugins_rule.commands = (if not exist $$PLUGIN_DIR ( $$QMAKE_MKDIR $$PLUGIN_DIR )) && \
- if exist $$PLUGIN_FILE ( $$QMAKE_COPY $$PLUGIN_FILE $$PLUGIN_TARGET )
-
- QMAKE_EXTRA_TARGETS += icu_rule plugins_rule
- PRE_TARGETDEPS += $$ICU_TARGET $$PLUGIN_TARGET
+ QMAKE_EXTRA_TARGETS += icu_rule
+ PRE_TARGETDEPS += $$ICU_TARGET
}
}
diff --git a/src/core/custom_protocol_handler.cpp b/src/core/custom_protocol_handler.cpp
index f140f98cf..fd1a4de41 100644
--- a/src/core/custom_protocol_handler.cpp
+++ b/src/core/custom_protocol_handler.cpp
@@ -43,7 +43,7 @@
namespace QtWebEngineCore {
-CustomProtocolHandler::CustomProtocolHandler(CustomUrlSchemeHandler *schemeHandler)
+CustomProtocolHandler::CustomProtocolHandler(QWebEngineUrlSchemeHandler *schemeHandler)
: m_schemeHandler(schemeHandler)
{
}
diff --git a/src/core/custom_protocol_handler.h b/src/core/custom_protocol_handler.h
index 225bb0567..94da28673 100644
--- a/src/core/custom_protocol_handler.h
+++ b/src/core/custom_protocol_handler.h
@@ -45,6 +45,7 @@
#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE
QT_FORWARD_DECLARE_CLASS(QIODevice)
+QT_FORWARD_DECLARE_CLASS(QWebEngineUrlSchemeHandler)
namespace net {
class NetworkDelegate;
@@ -54,20 +55,19 @@ class URLRequestJob;
namespace QtWebEngineCore {
class BrowserContextAdapter;
-class CustomUrlSchemeHandler;
// Implements a ProtocolHandler for custom URL schemes.
// If |network_delegate_| is NULL then all file requests will fail with ERR_ACCESS_DENIED.
class QWEBENGINE_EXPORT CustomProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
public:
- CustomProtocolHandler(CustomUrlSchemeHandler *);
+ CustomProtocolHandler(QWebEngineUrlSchemeHandler *);
virtual net::URLRequestJob *MaybeCreateJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate) const Q_DECL_OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
- CustomUrlSchemeHandler *m_schemeHandler;
+ QWebEngineUrlSchemeHandler *m_schemeHandler;
};
} // namespace
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp
index 6f79d4952..aebdfd027 100644
--- a/src/core/delegated_frame_node.cpp
+++ b/src/core/delegated_frame_node.cpp
@@ -76,6 +76,10 @@
#include <EGL/eglext.h>
#endif
+#ifndef GL_TIMEOUT_IGNORED
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#endif
+
namespace QtWebEngineCore {
class MailboxTexture : public QSGTexture, protected QOpenGLFunctions {
@@ -161,9 +165,9 @@ static QSGNode *buildLayerChain(QSGNode *chainParent, const cc::SharedQuadState
layerChain->appendChildNode(clipNode);
layerChain = clipNode;
}
- if (!layerState->content_to_target_transform.IsIdentity()) {
+ if (!layerState->quad_to_target_transform.IsIdentity()) {
QSGTransformNode *transformNode = new QSGTransformNode;
- transformNode->setMatrix(toQt(layerState->content_to_target_transform.matrix()));
+ transformNode->setMatrix(toQt(layerState->quad_to_target_transform.matrix()));
layerChain->appendChildNode(transformNode);
layerChain = transformNode;
}
@@ -205,7 +209,6 @@ static void waitChromiumSync(gfx::TransferableFence *sync)
#endif
break;
case gfx::TransferableFence::ArbSync:
-#ifdef GL_ARB_sync
typedef void (QOPENGLF_APIENTRYP WaitSyncPtr)(GLsync sync, GLbitfield flags, GLuint64 timeout);
static WaitSyncPtr glWaitSync_ = 0;
if (!glWaitSync_) {
@@ -214,7 +217,6 @@ static void waitChromiumSync(gfx::TransferableFence *sync)
Q_ASSERT(glWaitSync_);
}
glWaitSync_(sync->arb.sync, 0, GL_TIMEOUT_IGNORED);
-#endif
break;
}
}
@@ -250,7 +252,6 @@ static void deleteChromiumSync(gfx::TransferableFence *sync)
#endif
break;
case gfx::TransferableFence::ArbSync:
-#ifdef GL_ARB_sync
typedef void (QOPENGLF_APIENTRYP DeleteSyncPtr)(GLsync sync);
static DeleteSyncPtr glDeleteSync_ = 0;
if (!glDeleteSync_) {
@@ -260,7 +261,6 @@ static void deleteChromiumSync(gfx::TransferableFence *sync)
}
glDeleteSync_(sync->arb.sync);
sync->reset();
-#endif
break;
}
// If Chromium was able to create a sync, we should have been able to handle its type here too.
@@ -409,7 +409,7 @@ void DelegatedFrameNode::preprocess()
{
QMutexLocker lock(&m_mutex);
base::MessageLoop *gpuMessageLoop = gpu_message_loop();
- content::SyncPointManager *syncPointManager = sync_point_manager();
+ gpu::SyncPointManager *syncPointManager = sync_point_manager();
Q_FOREACH (MailboxTexture *mailboxTexture, mailboxesToFetch) {
m_numPendingSyncPoints++;
@@ -444,6 +444,20 @@ void DelegatedFrameNode::preprocess()
}
}
+static YUVVideoMaterial::ColorSpace toQt(cc::YUVVideoDrawQuad::ColorSpace color_space)
+{
+ switch (color_space) {
+ case cc::YUVVideoDrawQuad::REC_601:
+ return YUVVideoMaterial::REC_601;
+ case cc::YUVVideoDrawQuad::REC_709:
+ return YUVVideoMaterial::REC_709;
+ case cc::YUVVideoDrawQuad::JPEG:
+ return YUVVideoMaterial::JPEG;
+ }
+ Q_UNREACHABLE();
+ return YUVVideoMaterial::REC_601;
+}
+
void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, cc::ReturnedResourceArray *resourcesToRelease, RenderWidgetHostViewQtDelegate *apiDelegate)
{
m_chromiumCompositorData = chromiumCompositorData;
@@ -557,10 +571,10 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData,
break;
} case cc::DrawQuad::TEXTURE_CONTENT: {
const cc::TextureDrawQuad *tquad = cc::TextureDrawQuad::MaterialCast(quad);
- ResourceHolder *resource = findAndHoldResource(tquad->resource_id, resourceCandidates);
+ ResourceHolder *resource = findAndHoldResource(tquad->resource_id(), resourceCandidates);
QSGSimpleTextureNode *textureNode = new QSGSimpleTextureNode;
- textureNode->setTextureCoordinatesTransform(tquad->flipped ? QSGSimpleTextureNode::MirrorVertically : QSGSimpleTextureNode::NoTransform);
+ textureNode->setTextureCoordinatesTransform(tquad->y_flipped ? QSGSimpleTextureNode::MirrorVertically : QSGSimpleTextureNode::NoTransform);
textureNode->setRect(toQt(quad->rect));
textureNode->setFiltering(resource->transferableResource().filter == GL_LINEAR ? QSGTexture::Linear : QSGTexture::Nearest);
textureNode->setTexture(initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate));
@@ -605,7 +619,7 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData,
break;
} case cc::DrawQuad::TILED_CONTENT: {
const cc::TileDrawQuad *tquad = cc::TileDrawQuad::MaterialCast(quad);
- ResourceHolder *resource = findAndHoldResource(tquad->resource_id, resourceCandidates);
+ ResourceHolder *resource = findAndHoldResource(tquad->resource_id(), resourceCandidates);
QSGSimpleTextureNode *textureNode = new QSGSimpleTextureNode;
textureNode->setRect(toQt(quad->rect));
@@ -616,26 +630,28 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData,
break;
} case cc::DrawQuad::YUV_VIDEO_CONTENT: {
const cc::YUVVideoDrawQuad *vquad = cc::YUVVideoDrawQuad::MaterialCast(quad);
- ResourceHolder *yResource = findAndHoldResource(vquad->y_plane_resource_id, resourceCandidates);
- ResourceHolder *uResource = findAndHoldResource(vquad->u_plane_resource_id, resourceCandidates);
- ResourceHolder *vResource = findAndHoldResource(vquad->v_plane_resource_id, resourceCandidates);
+ ResourceHolder *yResource = findAndHoldResource(vquad->y_plane_resource_id(), resourceCandidates);
+ ResourceHolder *uResource = findAndHoldResource(vquad->u_plane_resource_id(), resourceCandidates);
+ ResourceHolder *vResource = findAndHoldResource(vquad->v_plane_resource_id(), resourceCandidates);
ResourceHolder *aResource = 0;
// This currently requires --enable-vp8-alpha-playback and needs a video with alpha data to be triggered.
- if (vquad->a_plane_resource_id)
- aResource = findAndHoldResource(vquad->a_plane_resource_id, resourceCandidates);
+ if (vquad->a_plane_resource_id())
+ aResource = findAndHoldResource(vquad->a_plane_resource_id(), resourceCandidates);
YUVVideoNode *videoNode = new YUVVideoNode(
initAndHoldTexture(yResource, quad->ShouldDrawWithBlending()),
initAndHoldTexture(uResource, quad->ShouldDrawWithBlending()),
initAndHoldTexture(vResource, quad->ShouldDrawWithBlending()),
- aResource ? initAndHoldTexture(aResource, quad->ShouldDrawWithBlending()) : 0, toQt(vquad->tex_coord_rect));
+ aResource ? initAndHoldTexture(aResource, quad->ShouldDrawWithBlending()) : 0,
+ toQt(vquad->ya_tex_coord_rect), toQt(vquad->uv_tex_coord_rect),
+ toQt(vquad->ya_tex_size), toQt(vquad->uv_tex_size), toQt(vquad->color_space));
videoNode->setRect(toQt(quad->rect));
currentLayerChain->appendChildNode(videoNode);
break;
#ifdef GL_OES_EGL_image_external
} case cc::DrawQuad::STREAM_VIDEO_CONTENT: {
const cc::StreamVideoDrawQuad *squad = cc::StreamVideoDrawQuad::MaterialCast(quad);
- ResourceHolder *resource = findAndHoldResource(squad->resource_id, resourceCandidates);
+ ResourceHolder *resource = findAndHoldResource(squad->resource_id(), resourceCandidates);
MailboxTexture *texture = static_cast<MailboxTexture *>(initAndHoldTexture(resource, quad->ShouldDrawWithBlending()));
texture->setTarget(GL_TEXTURE_EXTERNAL_OES); // since this is not default TEXTURE_2D type
diff --git a/src/core/dev_tools_http_handler_delegate_qt.cpp b/src/core/dev_tools_http_handler_delegate_qt.cpp
index 964d6ad38..793ed0981 100644
--- a/src/core/dev_tools_http_handler_delegate_qt.cpp
+++ b/src/core/dev_tools_http_handler_delegate_qt.cpp
@@ -49,9 +49,11 @@
#include "base/files/file_path.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "components/devtools_discovery/devtools_discovery_manager.h"
+#include "components/devtools_discovery/devtools_target_descriptor.h"
+#include "components/devtools_http_handler/devtools_http_handler.h"
#include "content/public/browser/devtools_agent_host.h"
-#include "content/public/browser/devtools_http_handler.h"
-#include "content/public/browser/devtools_target.h"
+#include "content/public/browser/devtools_frontend_host.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_view_host.h"
@@ -59,14 +61,17 @@
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/content_switches.h"
#include "net/base/ip_endpoint.h"
-#include "net/socket/stream_listen_socket.h"
+#include "net/base/net_errors.h"
#include "net/socket/tcp_server_socket.h"
using namespace content;
+using namespace devtools_discovery;
+using namespace devtools_http_handler;
namespace {
const char kTargetTypePage[] = "page";
+const char kTargetTypeSharedWorker[] = "worker";
const char kTargetTypeServiceWorker[] = "service_worker";
const char kTargetTypeOther[] = "other";
@@ -74,15 +79,29 @@ class TCPServerSocketFactory
: public DevToolsHttpHandler::ServerSocketFactory {
public:
TCPServerSocketFactory(const std::string& address, int port, int backlog)
- : DevToolsHttpHandler::ServerSocketFactory(address, port, backlog) {}
+ : m_address(address), m_port(port), m_backlog(backlog)
+ {}
private:
- scoped_ptr<net::ServerSocket> Create() const override {
- return scoped_ptr<net::ServerSocket>(new net::TCPServerSocket(NULL, net::NetLog::Source()));
- }
- DISALLOW_COPY_AND_ASSIGN(TCPServerSocketFactory);
+ scoped_ptr<net::ServerSocket> CreateForHttpServer() override {
+ scoped_ptr<net::ServerSocket> socket(new net::TCPServerSocket(nullptr, net::NetLog::Source()));
+ if (socket->ListenWithAddressAndPort(m_address, m_port, m_backlog) != net::OK)
+ return scoped_ptr<net::ServerSocket>();
+
+ return socket;
+ }
+
+ const std::string m_address;
+ int m_port;
+ int m_backlog;
+ DISALLOW_COPY_AND_ASSIGN(TCPServerSocketFactory);
};
-class Target : public content::DevToolsTarget {
+class DevToolsDiscoveryProviderQt : public DevToolsDiscoveryManager::Provider {
+public:
+ DevToolsTargetDescriptor::List GetDescriptors() override;
+};
+
+class Target : public DevToolsTargetDescriptor {
public:
explicit Target(scoped_refptr<DevToolsAgentHost> agent_host);
@@ -92,6 +111,8 @@ public:
switch (agent_host_->GetType()) {
case DevToolsAgentHost::TYPE_WEB_CONTENTS:
return kTargetTypePage;
+ case DevToolsAgentHost::TYPE_SHARED_WORKER:
+ return kTargetTypeSharedWorker;
case DevToolsAgentHost::TYPE_SERVICE_WORKER:
return kTargetTypeServiceWorker;
default:
@@ -141,17 +162,40 @@ bool Target::Close() const {
return agent_host_->Close();
}
+DevToolsTargetDescriptor::List DevToolsDiscoveryProviderQt::GetDescriptors()
+{
+ DevToolsTargetDescriptor::List targets;
+ for (const auto& agent_host : DevToolsAgentHost::GetOrCreateAll()) {
+ targets.push_back(new Target(agent_host));
+ }
+ return targets;
+}
+
} // namespace
namespace QtWebEngineCore {
+scoped_ptr<DevToolsHttpHandler> createDevToolsHttpHandler()
+{
+ DevToolsHttpHandlerDelegateQt *delegate = new DevToolsHttpHandlerDelegateQt();
+ if (!delegate->isValid()) {
+ delete delegate;
+ return nullptr;
+ }
+ scoped_ptr<DevToolsHttpHandler::ServerSocketFactory> factory(new TCPServerSocketFactory(delegate->bindAddress().toStdString(), delegate->port(), 1));
+ // Ownership of the delegate is taken over the devtools http handler.
+ scoped_ptr<DevToolsHttpHandler> handler(new DevToolsHttpHandler(factory.Pass(), std::string(), delegate, base::FilePath(), base::FilePath(), std::string(), std::string()));
+ DevToolsDiscoveryManager::GetInstance()->AddProvider(scoped_ptr<DevToolsDiscoveryManager::Provider>(new DevToolsDiscoveryProviderQt()));
+ return handler;
+}
+
DevToolsHttpHandlerDelegateQt::DevToolsHttpHandlerDelegateQt()
- : m_devtoolsHttpHandler(0)
- , m_bindAddress(QLatin1String("127.0.0.1"))
+ : m_bindAddress(QLatin1String("127.0.0.1"))
, m_port(0)
+ , m_valid(false)
{
const QString inspectorEnv = QString::fromUtf8(qgetenv("QTWEBENGINE_REMOTE_DEBUGGING"));
- const CommandLine &commandLine = *CommandLine::ForCurrentProcess();
+ const base::CommandLine &commandLine = *base::CommandLine::ForCurrentProcess();
QString portStr;
if (commandLine.HasSwitch(switches::kRemoteDebuggingPort)) {
@@ -166,26 +210,16 @@ DevToolsHttpHandlerDelegateQt::DevToolsHttpHandlerDelegateQt()
} else
return;
- bool ok = false;
- m_port = portStr.toInt(&ok);
- if (ok && m_port > 0 && m_port < 65535) {
- scoped_ptr<content::DevToolsHttpHandler::ServerSocketFactory> factory(new TCPServerSocketFactory(m_bindAddress.toStdString(), m_port, 1));
- m_devtoolsHttpHandler = DevToolsHttpHandler::Start(factory.Pass(), std::string(), this, base::FilePath());
- } else
+ m_port = portStr.toInt(&m_valid);
+ m_valid = m_valid && m_port > 0 && m_port < 65535;
+ if (!m_valid)
qWarning("Invalid port given for the inspector server \"%s\". Examples of valid input: \"12345\" or \"192.168.2.14:12345\" (with the address of one of this host's network interface).", qPrintable(portStr));
}
-DevToolsHttpHandlerDelegateQt::~DevToolsHttpHandlerDelegateQt()
-{
- // Stop() takes care of deleting the DevToolsHttpHandler.
- if (m_devtoolsHttpHandler)
- m_devtoolsHttpHandler->Stop();
-}
-
-void DevToolsHttpHandlerDelegateQt::Initialized(const net::IPEndPoint& ip_address)
+void DevToolsHttpHandlerDelegateQt::Initialized(const net::IPEndPoint *ip_address)
{
- if (ip_address.address().size()) {
- QString addressAndPort = QString::fromStdString(ip_address.ToString());
+ if (ip_address && ip_address->address().size()) {
+ QString addressAndPort = QString::fromStdString(ip_address->ToString());
qWarning("Remote debugging server started successfully. Try pointing a Chromium-based browser to http://%s", qPrintable(addressAndPort));
} else
qWarning("Couldn't start the inspector server on bind address \"%s\" and port \"%d\". In case of invalid input, try something like: \"12345\" or \"192.168.2.14:12345\" (with the address of one of this host's interface).", qPrintable(m_bindAddress), m_port);
@@ -203,42 +237,19 @@ std::string DevToolsHttpHandlerDelegateQt::GetDiscoveryPageHTML()
return html;
}
-bool DevToolsHttpHandlerDelegateQt::BundlesFrontendResources()
-{
- return true;
-}
-
-base::FilePath DevToolsHttpHandlerDelegateQt::GetDebugFrontendDir()
-{
- return base::FilePath();
-}
-
-scoped_ptr<net::StreamListenSocket> DevToolsHttpHandlerDelegateQt::CreateSocketForTethering(net::StreamListenSocket::Delegate* delegate, std::string* name)
-{
- return scoped_ptr<net::StreamListenSocket>();
-}
-
-base::DictionaryValue* DevToolsManagerDelegateQt::HandleCommand(DevToolsAgentHost *, base::DictionaryValue *) {
- return 0;
-}
-
-std::string DevToolsManagerDelegateQt::GetPageThumbnailData(const GURL& url)
+std::string DevToolsHttpHandlerDelegateQt::GetPageThumbnailData(const GURL& url)
{
return std::string();
}
-scoped_ptr<DevToolsTarget> DevToolsManagerDelegateQt::CreateNewTarget(const GURL &)
+std::string DevToolsHttpHandlerDelegateQt::GetFrontendResource(const std::string &path)
{
- return scoped_ptr<DevToolsTarget>();
+ return content::DevToolsFrontendHost::GetFrontendResource(path).as_string();
}
-void DevToolsManagerDelegateQt::EnumerateTargets(TargetCallback callback)
+base::DictionaryValue* DevToolsManagerDelegateQt::HandleCommand(DevToolsAgentHost *, base::DictionaryValue *)
{
- TargetList targets;
- for (const auto& agent_host : DevToolsAgentHost::GetOrCreateAll()) {
- targets.push_back(new Target(agent_host));
- }
- callback.Run(targets);
+ return 0;
}
} //namespace QtWebEngineCore
diff --git a/src/core/dev_tools_http_handler_delegate_qt.h b/src/core/dev_tools_http_handler_delegate_qt.h
index 902e99507..0fe9ad0ce 100644
--- a/src/core/dev_tools_http_handler_delegate_qt.h
+++ b/src/core/dev_tools_http_handler_delegate_qt.h
@@ -37,43 +37,42 @@
#ifndef DEV_TOOLS_HTTP_HANDLER_DELEGATE_QT_H
#define DEV_TOOLS_HTTP_HANDLER_DELEGATE_QT_H
-#include "content/public/browser/devtools_http_handler_delegate.h"
+#include "components/devtools_http_handler/devtools_http_handler_delegate.h"
#include "content/public/browser/devtools_manager_delegate.h"
#include <QString>
#include <QtCore/qcompilerdetection.h> // needed for Q_DECL_OVERRIDE
-namespace net {
-class StreamListenSocket;
-}
-
namespace content {
class BrowserContext;
+}
+
+namespace devtools_http_handler {
class DevToolsHttpHandler;
-class RenderViewHost;
}
namespace QtWebEngineCore {
-class DevToolsHttpHandlerDelegateQt : public content::DevToolsHttpHandlerDelegate {
-public:
+scoped_ptr<devtools_http_handler::DevToolsHttpHandler> createDevToolsHttpHandler();
+class DevToolsHttpHandlerDelegateQt : public devtools_http_handler::DevToolsHttpHandlerDelegate {
+public:
DevToolsHttpHandlerDelegateQt();
- virtual ~DevToolsHttpHandlerDelegateQt();
- // content::DevToolsHttpHandlerDelegate Overrides
- virtual void Initialized(const net::IPEndPoint &ip_address) Q_DECL_OVERRIDE;
- virtual std::string GetDiscoveryPageHTML() Q_DECL_OVERRIDE;
- virtual bool BundlesFrontendResources() Q_DECL_OVERRIDE;
- virtual base::FilePath GetDebugFrontendDir() Q_DECL_OVERRIDE;
- // Requests the list of all inspectable targets.
- // The caller gets the ownership of the returned targets.
- virtual scoped_ptr<net::StreamListenSocket> CreateSocketForTethering(net::StreamListenSocket::Delegate *delegate, std::string *name) Q_DECL_OVERRIDE;
+ bool isValid() const { return m_valid; }
+ QString bindAddress() const { return m_bindAddress; }
+ int port() const { return m_port; }
+
+ // devtools_http_handler::DevToolsHttpHandlerDelegate Overrides
+ void Initialized(const net::IPEndPoint *ip_address) Q_DECL_OVERRIDE;
+ std::string GetDiscoveryPageHTML() Q_DECL_OVERRIDE;
+ std::string GetFrontendResource(const std::string&) Q_DECL_OVERRIDE;
+ std::string GetPageThumbnailData(const GURL &url) Q_DECL_OVERRIDE;
private:
- content::DevToolsHttpHandler *m_devtoolsHttpHandler;
QString m_bindAddress;
int m_port;
+ bool m_valid;
};
class DevToolsManagerDelegateQt : public content::DevToolsManagerDelegate {
@@ -81,9 +80,6 @@ public:
void Inspect(content::BrowserContext *browser_context, content::DevToolsAgentHost *agent_host) Q_DECL_OVERRIDE { }
void DevToolsAgentStateChanged(content::DevToolsAgentHost *agent_host, bool attached) Q_DECL_OVERRIDE { }
base::DictionaryValue *HandleCommand(content::DevToolsAgentHost *agent_host, base::DictionaryValue *command) Q_DECL_OVERRIDE;
- scoped_ptr<content::DevToolsTarget> CreateNewTarget(const GURL &url) Q_DECL_OVERRIDE;
- void EnumerateTargets(TargetCallback callback) Q_DECL_OVERRIDE;
- std::string GetPageThumbnailData(const GURL &url) Q_DECL_OVERRIDE;
};
} // namespace QtWebEngineCore
diff --git a/src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc b/src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc
new file mode 100644
index 000000000..4806359c9
--- /dev/null
+++ b/src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc
@@ -0,0 +1,8 @@
+//! [0]
+QT += webenginecore
+//! [0]
+
+
+//! [1]
+#include <QtWebEngineCore>
+//! [1]
diff --git a/src/core/doc/src/qtwebenginecore-index.qdoc b/src/core/doc/src/qtwebenginecore-index.qdoc
new file mode 100644
index 000000000..49231c8f2
--- /dev/null
+++ b/src/core/doc/src/qtwebenginecore-index.qdoc
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page qtwebenginecore-index.html
+ \title Qt WebEngine Core
+ \ingroup modules
+
+ \brief Provides common API shared by Qt WebEngine and Qt WebEngine Widgets.
+
+ Qt WebEngine Core provides API shared by \l {Qt WebEngine} and \l {Qt WebEngine Widgets}.
+
+ \section1 Getting Started
+
+ To include the definitions of the module's classes, use the
+ following directive:
+
+ \snippet qtwebenginecore_build_snippet.qdoc 1
+
+ To link against the module, add this line to your qmake project file:
+
+ \snippet qtwebenginecore_build_snippet.qdoc 0
+
+ \section1 Articles and Guides
+
+ \list
+ \li \l{Qt WebEngine Overview}
+ \endlist
+
+ \section1 API Reference
+
+ \list
+ \li \l{Qt WebEngine Core C++ Classes}
+ \endlist
+
+ \section1 License Information
+
+ This is a snapshot of the integration of Chromium into Qt.
+
+ Qt Commercial Edition licensees that wish to distribute applications that
+ use the Qt WebEngine module need to be aware of their obligations under the
+ GNU Library General Public License (LGPLv2).
+
+ Developers using the Open Source Edition can choose to redistribute
+ the module under the GNU LGPLv3 or GPLv2 and up.
+
+ \legalese
+
+ Chromium is licensed under the following license:
+
+ Copyright (c) 2013 The Chromium Authors. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Google Inc. nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ \endlegalese
+*/
diff --git a/src/core/doc/src/qtwebenginecore-module.qdoc b/src/core/doc/src/qtwebenginecore-module.qdoc
new file mode 100644
index 000000000..750a0244e
--- /dev/null
+++ b/src/core/doc/src/qtwebenginecore-module.qdoc
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+/*!
+ \module QtWebEngineCore
+ \title Qt WebEngine Core C++ Classes
+ \brief Provides public API shared by both QtWebEngine and QtWebEngineWidgets
+ \since 5.6
+ \ingroup qtwebengine-modules
+
+ To include the definitions of the module's classes, use the
+ following directive:
+
+ \snippet qtwebenginecore_build_snippet.qdoc 1
+
+ If you use qmake to build your projects, Qt WebEngine Core is usually
+ indirectly included through the \l[QtWebEngine]{Qt WebEngine} or
+ \l[QtWebEngineWidgets]{Qt WebEngine Widgets} modules.
+*/
diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp
new file mode 100644
index 000000000..18896c6b4
--- /dev/null
+++ b/src/core/file_picker_controller.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "file_picker_controller.h"
+#include "type_conversion.h"
+#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+
+#include <QFileInfo>
+#include <QDir>
+#include <QVariant>
+#include <QStringList>
+
+namespace QtWebEngineCore {
+
+FilePickerController::FilePickerController(FileChooserMode mode, content::WebContents *contents, const QString &defaultFileName, const QStringList &acceptedMimeTypes, QObject *parent)
+ : QObject(parent)
+ , m_defaultFileName(defaultFileName)
+ , m_acceptedMimeTypes(acceptedMimeTypes)
+ , m_contents(contents)
+ , m_mode(mode)
+{
+}
+
+void FilePickerController::accepted(const QStringList &files)
+{
+ FilePickerController::filesSelectedInChooser(files, m_contents);
+}
+
+void FilePickerController::accepted(const QVariant &files)
+{
+ QStringList stringList;
+
+ if (files.canConvert(QVariant::StringList)) {
+ stringList = files.toStringList();
+ } else if (files.canConvert<QList<QUrl> >()) {
+ Q_FOREACH (const QUrl &url, files.value<QList<QUrl> >())
+ stringList.append(url.toLocalFile());
+ } else {
+ qWarning("An unhandled type '%s' was provided in FilePickerController::accepted(QVariant)", files.typeName());
+ }
+
+ FilePickerController::filesSelectedInChooser(stringList, m_contents);
+}
+
+void FilePickerController::rejected()
+{
+ FilePickerController::filesSelectedInChooser(QStringList(), m_contents);
+}
+
+static QStringList listRecursively(const QDir &dir)
+{
+ QStringList ret;
+ QFileInfoList infoList(dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden));
+ Q_FOREACH (const QFileInfo &fileInfo, infoList) {
+ if (fileInfo.isDir()) {
+ ret.append(fileInfo.absolutePath() + QStringLiteral("/.")); // Match chromium's behavior. See chrome/browser/file_select_helper.cc
+ ret.append(listRecursively(QDir(fileInfo.absoluteFilePath())));
+ } else
+ ret.append(fileInfo.absoluteFilePath());
+ }
+ return ret;
+}
+
+ASSERT_ENUMS_MATCH(FilePickerController::Open, content::FileChooserParams::Open)
+ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, content::FileChooserParams::OpenMultiple)
+ASSERT_ENUMS_MATCH(FilePickerController::UploadFolder, content::FileChooserParams::UploadFolder)
+ASSERT_ENUMS_MATCH(FilePickerController::Save, content::FileChooserParams::Save)
+
+void FilePickerController::filesSelectedInChooser(const QStringList &filesList, content::WebContents *contents)
+{
+ content::RenderViewHost *rvh = contents->GetRenderViewHost();
+ Q_ASSERT(rvh);
+ QStringList files(filesList);
+ if (this->m_mode == UploadFolder && !filesList.isEmpty()
+ && QFileInfo(filesList.first()).isDir()) // Enumerate the directory
+ files = listRecursively(QDir(filesList.first()));
+ rvh->FilesSelectedInChooser(toVector<content::FileChooserFileInfo>(files), static_cast<content::FileChooserParams::Mode>(this->m_mode));
+}
+
+QStringList FilePickerController::acceptedMimeTypes()
+{
+ return m_acceptedMimeTypes;
+}
+
+FilePickerController::FileChooserMode FilePickerController::mode()
+{
+ return m_mode;
+}
+
+QString FilePickerController::defaultFileName()
+{
+ return m_defaultFileName;
+}
+
+} // namespace
diff --git a/src/core/file_picker_controller.h b/src/core/file_picker_controller.h
new file mode 100644
index 000000000..347dd11ef
--- /dev/null
+++ b/src/core/file_picker_controller.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FILE_PICKER_CONTROLLER_H
+#define FILE_PICKER_CONTROLLER_H
+
+#include "qtwebenginecoreglobal.h"
+#include <QObject>
+#include <QStringList>
+
+namespace content {
+ class WebContents;
+}
+
+namespace QtWebEngineCore {
+
+class QWEBENGINE_EXPORT FilePickerController : public QObject {
+ Q_OBJECT
+public:
+ enum FileChooserMode {
+ Open,
+ OpenMultiple,
+ UploadFolder,
+ Save
+ };
+
+ FilePickerController(FileChooserMode mode, content::WebContents *contents, const QString &defaultFileName, const QStringList &acceptedMimeTypes, QObject * = 0);
+ QStringList acceptedMimeTypes();
+ QString defaultFileName();
+ FileChooserMode mode();
+ void filesSelectedInChooser(const QStringList &filesList, content::WebContents *contents);
+
+public Q_SLOTS:
+ void accepted(const QStringList &files);
+ void accepted(const QVariant &files);
+ void rejected();
+
+private:
+ QString m_defaultFileName;
+ QStringList m_acceptedMimeTypes;
+ content::WebContents *m_contents;
+ FileChooserMode m_mode;
+
+};
+
+} // namespace
+
+#endif // FILE_PICKER_CONTROLLER_H
diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp
index 584bdc227..86bb4fda9 100644
--- a/src/core/gl_surface_qt.cpp
+++ b/src/core/gl_surface_qt.cpp
@@ -44,7 +44,7 @@
#include <QGuiApplication>
#include "gl_context_qt.h"
-#include "qtwebenginecoreglobal.h"
+#include "qtwebenginecoreglobal_p.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
@@ -439,11 +439,11 @@ bool GLSurfaceQt::IsOffscreen()
return true;
}
-bool GLSurfaceQt::SwapBuffers()
+gfx::SwapResult GLSurfaceQt::SwapBuffers()
{
LOG(ERROR) << "Attempted to call SwapBuffers on a pbuffer.";
Q_UNREACHABLE();
- return false;
+ return gfx::SwapResult::SWAP_FAILED;
}
gfx::Size GLSurfaceQt::GetSize()
@@ -533,6 +533,17 @@ GLSurface::CreateViewGLSurface(gfx::AcceleratedWidget window)
return NULL;
}
+std::string DriverEGL::GetPlatformExtensions()
+{
+ EGLDisplay display = GLContextHelper::getEGLDisplay();
+ if (display == EGL_NO_DISPLAY)
+ return "";
+
+ DCHECK(g_driver_egl.fn.eglQueryStringFn);
+ const char* str = g_driver_egl.fn.eglQueryStringFn(display, EGL_EXTENSIONS);
+ return str ? std::string(str) : "";
+}
+
} // namespace gfx
namespace content {
diff --git a/src/core/gl_surface_qt.h b/src/core/gl_surface_qt.h
index 21c46e699..7646063b2 100644
--- a/src/core/gl_surface_qt.h
+++ b/src/core/gl_surface_qt.h
@@ -39,7 +39,7 @@
#ifndef GL_SURFACE_QT_H_
#define GL_SURFACE_QT_H_
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
#include "ui/gl/gl_surface.h"
#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE
@@ -56,7 +56,7 @@ public:
virtual void* GetDisplay() Q_DECL_OVERRIDE;
virtual void* GetConfig() Q_DECL_OVERRIDE;
virtual bool IsOffscreen() Q_DECL_OVERRIDE;
- virtual bool SwapBuffers() Q_DECL_OVERRIDE;
+ virtual gfx::SwapResult SwapBuffers() Q_DECL_OVERRIDE;
virtual gfx::Size GetSize() Q_DECL_OVERRIDE;
protected:
diff --git a/src/core/gyp_run.pro b/src/core/gyp_run.pro
index 3f631302c..def7d4698 100644
--- a/src/core/gyp_run.pro
+++ b/src/core/gyp_run.pro
@@ -28,9 +28,6 @@ force_debug_info {
else: GYP_CONFIG += release_extra_cflags=-g
}
-# Append additional platform options defined in GYP_CONFIG
-for (config, GYP_CONFIG): GYP_ARGS += "-D $$config"
-
# Copy this logic from qt_module.prf so that ninja can run according
# to the same rules as the final module linking in core_module.pro.
!host_build:if(win32|mac):!macx-xcode {
@@ -40,58 +37,63 @@ for (config, GYP_CONFIG): GYP_ARGS += "-D $$config"
cross_compile {
TOOLCHAIN_SYSROOT = $$[QT_SYSROOT]
+ !isEmpty(TOOLCHAIN_SYSROOT): GYP_CONFIG += sysroot=\"$${TOOLCHAIN_SYSROOT}\"
+
+ # Needed for v8, see chromium/v8/build/toolchain.gypi
+ GYP_CONFIG += CXX=\"$$which($$QMAKE_CXX)\"
+}
+
+contains(QT_ARCH, "arm") {
+ # Chromium will set a default sysroot on arm unless we give it one.
+ !cross_compile: GYP_CONFIG += sysroot=\"\"
+
+ GYP_CONFIG += target_arch=arm
+
+ # Extract ARM specific compiler options that we have to pass to gyp,
+ # but let gyp figure out a default if an option is not present.
+ MARCH = $$extractCFlag("-march=.*")
+ !isEmpty(MARCH): GYP_CONFIG += arm_arch=\"$$MARCH\"
- !isEmpty(TOOLCHAIN_SYSROOT): GYP_ARGS += "-D sysroot=\"$${TOOLCHAIN_SYSROOT}\""
-
- contains(QT_ARCH, "arm") {
- GYP_ARGS += "-D target_arch=arm"
-
- # Extract ARM specific compiler options that we have to pass to gyp,
- # but let gyp figure out a default if an option is not present.
- MARCH = $$extractCFlag("-march=.*")
- !isEmpty(MARCH): GYP_ARGS += "-D arm_arch=\"$$MARCH\""
-
- MTUNE = $$extractCFlag("-mtune=.*")
- GYP_ARGS += "-D arm_tune=\"$$MTUNE\""
-
- MFLOAT = $$extractCFlag("-mfloat-abi=.*")
- !isEmpty(MFLOAT): GYP_ARGS += "-D arm_float_abi=\"$$MFLOAT\""
-
- MARMV = $$replace(MARCH, "armv",)
- !isEmpty(MARMV) {
- MARMV = $$split(MARMV,)
- MARMV = $$member(MARMV, 0)
- lessThan(MARMV, 6): error("$$MARCH architecture is not supported")
- GYP_ARGS += "-D arm_version=\"$$MARMV\""
- }
-
- MFPU = $$extractCFlag("-mfpu=.*")
- !isEmpty(MFPU) {
- # If the toolchain does not explicitly specify to use NEON instructions
- # we use arm_neon_optional for ARMv7 and newer and let chromium decide
- # about the mfpu option.
- contains(MFPU, "neon")|contains(MFPU, "neon-vfpv4"): GYP_ARGS += "-D arm_fpu=\"$$MFPU\" -D arm_neon=1"
- else:!lessThan(MARMV, 7): GYP_ARGS += "-D arm_neon=0 -D arm_neon_optional=1"
- else: GYP_ARGS += "-D arm_fpu=\"$$MFPU\" -D arm_neon=0 -D arm_neon_optional=0"
- }
-
- contains(QMAKE_CFLAGS, "-mthumb"): GYP_ARGS += "-D arm_thumb=1"
+ MTUNE = $$extractCFlag("-mtune=.*")
+ !isEmpty(MTUNE): GYP_CONFIG += arm_tune=\"$$MTUNE\"
+
+ MFLOAT = $$extractCFlag("-mfloat-abi=.*")
+ !isEmpty(MFLOAT): GYP_CONFIG += arm_float_abi=\"$$MFLOAT\"
+
+ MARMV = $$replace(MARCH, "armv",)
+ !isEmpty(MARMV) {
+ MARMV = $$split(MARMV,)
+ MARMV = $$member(MARMV, 0)
+ lessThan(MARMV, 6): error("$$MARCH architecture is not supported")
+ GYP_CONFIG += arm_version=\"$$MARMV\"
}
- # Needed for v8, see chromium/v8/build/toolchain.gypi
- GYP_ARGS += "-D CXX=\"$$which($$QMAKE_CXX)\""
+ MFPU = $$extractCFlag("-mfpu=.*")
+ !isEmpty(MFPU) {
+ # If the toolchain does not explicitly specify to use NEON instructions
+ # we use arm_neon_optional for ARMv7 and newer and let chromium decide
+ # about the mfpu option.
+ contains(MFPU, "neon")|contains(MFPU, "neon-vfpv4"): GYP_CONFIG += arm_fpu=\"$$MFPU\" arm_neon=1
+ else:!lessThan(MARMV, 7): GYP_CONFIG += arm_neon=0 arm_neon_optional=1
+ else: GYP_CONFIG += arm_fpu=\"$$MFPU\" arm_neon=0 arm_neon_optional=0
+ }
+
+ contains(QMAKE_CFLAGS, "-mthumb"): GYP_CONFIG += arm_thumb=1
}
-contains(QT_ARCH, "x86_64"): GYP_ARGS += "-D target_arch=x64"
-contains(QT_ARCH, "i386"): GYP_ARGS += "-D target_arch=ia32"
+contains(QT_ARCH, "x86_64"): GYP_CONFIG += target_arch=x64
+contains(QT_ARCH, "i386"): GYP_CONFIG += target_arch=ia32
-contains(WEBENGINE_CONFIG, proprietary_codecs): GYP_ARGS += "-Dproprietary_codecs=1 -Dffmpeg_branding=Chrome -Duse_system_ffmpeg=0"
+contains(WEBENGINE_CONFIG, use_proprietary_codecs): GYP_CONFIG += proprietary_codecs=1 ffmpeg_branding=Chrome
!contains(QT_CONFIG, qt_framework): contains(QT_CONFIG, private_tests) {
- GYP_ARGS += "-D qt_install_data=\"$$[QT_INSTALL_DATA/get]\""
- GYP_ARGS += "-D qt_install_translations=\"$$[QT_INSTALL_TRANSLATIONS/get]\""
+ GYP_CONFIG += qt_install_data=\"$$[QT_INSTALL_DATA/get]\"
+ GYP_CONFIG += qt_install_translations=\"$$[QT_INSTALL_TRANSLATIONS/get]\"
}
+# Append additional platform options defined in GYP_CONFIG
+for (config, GYP_CONFIG): GYP_ARGS += "-D $$config"
+
!build_pass {
message("Running gyp_qtwebengine \"$$OUT_PWD\" $${GYP_ARGS}...")
!system("python $$QTWEBENGINE_ROOT/tools/buildscripts/gyp_qtwebengine \"$$OUT_PWD\" $${GYP_ARGS}"): error("-- running gyp_qtwebengine failed --")
diff --git a/src/core/javascript_dialog_manager_qt.cpp b/src/core/javascript_dialog_manager_qt.cpp
index fdcd7bdbc..24d426098 100644
--- a/src/core/javascript_dialog_manager_qt.cpp
+++ b/src/core/javascript_dialog_manager_qt.cpp
@@ -67,6 +67,12 @@ void JavaScriptDialogManagerQt::RunJavaScriptDialog(content::WebContents *webCon
runDialogForContents(webContents, dialogType, toQt(messageText).toHtmlEscaped(), toQt(defaultPromptText).toHtmlEscaped(), toQt(originUrl), callback);
}
+void JavaScriptDialogManagerQt::RunBeforeUnloadDialog(content::WebContents *webContents, const base::string16 &messageText,
+ bool isReload, const content::JavaScriptDialogManager::DialogClosedCallback &callback) {
+ Q_UNUSED(isReload);
+ runDialogForContents(webContents, WebContentsAdapterClient::UnloadDialog, toQt(messageText).toHtmlEscaped(), QString() , QUrl(), callback);
+}
+
bool JavaScriptDialogManagerQt::HandleJavaScriptDialog(content::WebContents *contents, bool accept, const base::string16 *promptOverride)
{
QSharedPointer<JavaScriptDialogController> dialog = m_activeDialogs.value(contents);
diff --git a/src/core/javascript_dialog_manager_qt.h b/src/core/javascript_dialog_manager_qt.h
index 4682ce5b8..fb47166c1 100644
--- a/src/core/javascript_dialog_manager_qt.h
+++ b/src/core/javascript_dialog_manager_qt.h
@@ -63,11 +63,10 @@ public:
const content::JavaScriptDialogManager::DialogClosedCallback &callback, bool *didSuppressMessage) Q_DECL_OVERRIDE;
virtual void RunBeforeUnloadDialog(content::WebContents *, const base::string16 &messageText, bool isReload,
- const content::JavaScriptDialogManager::DialogClosedCallback &callback) Q_DECL_OVERRIDE { Q_UNUSED(messageText); Q_UNUSED(isReload); Q_UNUSED(callback); }
+ const content::JavaScriptDialogManager::DialogClosedCallback &callback) Q_DECL_OVERRIDE;
virtual bool HandleJavaScriptDialog(content::WebContents *, bool accept, const base::string16 *promptOverride) Q_DECL_OVERRIDE;
virtual void CancelActiveAndPendingDialogs(content::WebContents *contents) Q_DECL_OVERRIDE { takeDialogForContents(contents); }
- virtual void WebContentsDestroyed(content::WebContents *contents) Q_DECL_OVERRIDE { takeDialogForContents(contents); }
-
+ virtual void ResetDialogState(content::WebContents *contents) Q_DECL_OVERRIDE { takeDialogForContents(contents); }
void runDialogForContents(content::WebContents *, WebContentsAdapterClient::JavascriptDialogType, const QString &messageText, const QString &defaultPrompt
, const QUrl &,const content::JavaScriptDialogManager::DialogClosedCallback &callback, const QString &title = QString());
diff --git a/src/core/location_provider_qt.cpp b/src/core/location_provider_qt.cpp
index d17fc3d21..e3be01b36 100644
--- a/src/core/location_provider_qt.cpp
+++ b/src/core/location_provider_qt.cpp
@@ -60,7 +60,7 @@ public:
QtPositioningHelper(LocationProviderQt *provider);
~QtPositioningHelper();
- bool start(bool highAccuracy);
+ void start(bool highAccuracy);
void stop();
void refresh();
@@ -88,15 +88,20 @@ QtPositioningHelper::~QtPositioningHelper()
m_locationProvider->m_positioningHelper = 0;
}
-bool QtPositioningHelper::start(bool highAccuracy)
+void QtPositioningHelper::start(bool highAccuracy)
{
DCHECK_CURRENTLY_ON(BrowserThread::UI);
Q_UNUSED(highAccuracy);
// FIXME: go through availableSources until one supports QGeoPositionInfoSource::SatellitePositioningMethods
// for the highAccuracy case.
m_positionInfoSource = QGeoPositionInfoSource::createDefaultSource(this);
- if (!m_positionInfoSource)
- return false;
+ if (!m_positionInfoSource) {
+ qWarning("Failed to initialize location provider: The system either has no default "
+ "position source, no valid plugins could be found or the user does not have "
+ "the right permissions.");
+ error(QGeoPositionInfoSource::UnknownSourceError);
+ return;
+ }
connect(m_positionInfoSource, &QGeoPositionInfoSource::positionUpdated, this, &QtPositioningHelper::updatePosition);
// disambiguate the error getter and the signal in QGeoPositionInfoSource.
@@ -105,7 +110,7 @@ bool QtPositioningHelper::start(bool highAccuracy)
connect(m_positionInfoSource, &QGeoPositionInfoSource::updateTimeout, this, &QtPositioningHelper::timeout);
m_positionInfoSource->startUpdates();
- return true;
+ return;
}
void QtPositioningHelper::stop()
@@ -208,7 +213,7 @@ bool LocationProviderQt::StartProvider(bool highAccuracy)
m_positioningHelper = new QtPositioningHelper(this);
m_positioningHelper->moveToThread(guiThread);
}
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(base::IgnoreResult(&QtPositioningHelper::start)
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(&QtPositioningHelper::start
, base::Unretained(m_positioningHelper), highAccuracy));
return true;
}
diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp
index 6866afc41..b31d22a76 100644
--- a/src/core/media_capture_devices_dispatcher.cpp
+++ b/src/core/media_capture_devices_dispatcher.cpp
@@ -91,9 +91,8 @@ scoped_ptr<content::MediaStreamUI> getDevicesForDesktopCapture(content::MediaStr
devices.push_back(content::MediaStreamDevice(
content::MEDIA_DESKTOP_VIDEO_CAPTURE, mediaId.ToString(), "Screen"));
if (captureAudio) {
- // Use the special loopback device ID for system audio capture.
devices.push_back(content::MediaStreamDevice(
- content::MEDIA_LOOPBACK_AUDIO_CAPTURE,
+ content::MEDIA_DESKTOP_AUDIO_CAPTURE,
media::AudioManagerBase::kLoopbackInputDeviceId, "System Audio"));
}
@@ -225,7 +224,7 @@ void MediaCaptureDevicesDispatcher::processMediaAccessRequest(WebContentsAdapter
if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE || request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE)
return;
- if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE || request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE)
+ if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE || request.audio_type == content::MEDIA_DESKTOP_AUDIO_CAPTURE)
// It's still unclear what to make of screen capture. We can rely on existing javascript dialog infrastructure
// to experiment with this without exposing it through our API yet.
processDesktopCaptureAccessRequest(webContents, request, callback);
@@ -279,7 +278,7 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::
// Audio is only supported for screen capture streams.
bool capture_audio = (mediaId.type == content::DesktopMediaID::TYPE_SCREEN &&
- request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE);
+ request.audio_type == content::MEDIA_DESKTOP_AUDIO_CAPTURE);
ui = getDevicesForDesktopCapture(
devices, mediaId, capture_audio, true,
@@ -305,8 +304,8 @@ void MediaCaptureDevicesDispatcher::processScreenCaptureAccessRequest(content::W
base::Unretained(this), base::Unretained(webContents));
QUrl securityOrigin(toQt(request.security_origin));
- QString message = QObject::tr("Do you want %1 to share your screen?").arg(securityOrigin.toString());
- QString title = QObject::tr("%1 Screen Sharing request").arg(securityOrigin.toString());
+ QString message = QCoreApplication::translate("MediaCaptureDevicesDispatcher", "Do you want %1 to share your screen?").arg(securityOrigin.toString());
+ QString title = QCoreApplication::translate("MediaCaptureDevicesDispatcher", "%1 Screen Sharing request").arg(securityOrigin.toString());
JavaScriptDialogManagerQt::GetInstance()->runDialogForContents(webContents, WebContentsAdapterClient::InternalAuthorizationDialog, message
, QString(), securityOrigin, dialogCallback, title);
} else
diff --git a/src/core/network_delegate_qt.cpp b/src/core/network_delegate_qt.cpp
index 4e726fec8..3f67e7c0d 100644
--- a/src/core/network_delegate_qt.cpp
+++ b/src/core/network_delegate_qt.cpp
@@ -36,13 +36,19 @@
#include "network_delegate_qt.h"
+#include "browser_context_adapter.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/resource_request_details.h"
#include "content/public/browser/resource_request_info.h"
+#include "cookie_monster_delegate_qt.h"
#include "ui/base/page_transition_types.h"
+#include "url_request_context_getter_qt.h"
#include "net/base/load_flags.h"
#include "net/url_request/url_request.h"
+#include "qwebengineurlrequestinfo.h"
+#include "qwebengineurlrequestinfo_p.h"
+#include "qwebengineurlrequestinterceptor.h"
#include "type_conversion.h"
#include "web_contents_adapter_client.h"
#include "web_contents_view_qt.h"
@@ -56,11 +62,11 @@ int pageTransitionToNavigationType(ui::PageTransition transition)
if (qualifier & ui::PAGE_TRANSITION_FORWARD_BACK)
return WebContentsAdapterClient::BackForwardNavigation;
- ui::PageTransition stippedTransition = ui::PageTransitionStripQualifier(transition);
+ ui::PageTransition strippedTransition = ui::PageTransitionStripQualifier(transition);
- switch (stippedTransition) {
+ switch (strippedTransition) {
case ui::PAGE_TRANSITION_LINK:
- return WebContentsAdapterClient::LinkClickedNavigation;
+ return WebContentsAdapterClient::LinkNavigation;
case ui::PAGE_TRANSITION_TYPED:
return WebContentsAdapterClient::TypedNavigation;
case ui::PAGE_TRANSITION_FORM_SUBMIT:
@@ -72,29 +78,69 @@ int pageTransitionToNavigationType(ui::PageTransition transition)
}
}
-int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, const net::CompletionCallback &callback, GURL *)
+NetworkDelegateQt::NetworkDelegateQt(URLRequestContextGetterQt *requestContext)
+ : m_requestContextGetter(requestContext)
+{
+}
+
+int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, const net::CompletionCallback &callback, GURL *newUrl)
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
- const content::ResourceRequestInfo *info = content::ResourceRequestInfo::ForRequest(request);
- if (!info)
+ Q_ASSERT(m_requestContextGetter);
+ Q_ASSERT(m_requestContextGetter->m_browserContext);
+
+ const content::ResourceRequestInfo *resourceInfo = content::ResourceRequestInfo::ForRequest(request);
+
+ content::ResourceType resourceType = content::RESOURCE_TYPE_LAST_TYPE;
+ int navigationType = QWebEngineUrlRequestInfo::NavigationTypeOther;
+
+ if (resourceInfo) {
+ resourceType = resourceInfo->GetResourceType();
+ navigationType = pageTransitionToNavigationType(resourceInfo->GetPageTransition());
+ }
+
+ const QUrl qUrl = toQt(request->url());
+
+ QWebEngineUrlRequestInterceptor* interceptor = m_requestContextGetter->m_browserContext->requestInterceptor();
+ if (interceptor) {
+ QWebEngineUrlRequestInfoPrivate *infoPrivate = new QWebEngineUrlRequestInfoPrivate(static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType)
+ , static_cast<QWebEngineUrlRequestInfo::NavigationType>(navigationType)
+ , qUrl
+ , toQt(request->first_party_for_cookies())
+ , QByteArray::fromStdString(request->method()));
+ QWebEngineUrlRequestInfo requestInfo(infoPrivate);
+ if (interceptor->interceptRequest(requestInfo)) {
+ int result = infoPrivate->shouldBlockRequest ? net::ERR_ABORTED : net::OK;
+
+ if (qUrl != infoPrivate->url)
+ *newUrl = toGurl(infoPrivate->url);
+
+ if (!infoPrivate->extraHeaders.isEmpty()) {
+ auto end = infoPrivate->extraHeaders.constEnd();
+ for (auto header = infoPrivate->extraHeaders.constBegin(); header != end; ++header)
+ request->SetExtraRequestHeaderByName(header.key().toStdString(), header.value().toStdString(), /* overwrite */ true);
+ }
+
+ return result;
+ }
+ }
+
+ if (!resourceInfo)
return net::OK;
- content::ResourceType resourceType = info->GetResourceType();
int renderProcessId;
int renderFrameId;
// Only intercept MAIN_FRAME and SUB_FRAME with an associated render frame.
- if (!content::IsResourceTypeFrame(resourceType) || !info->GetRenderFrameForRequest(request, &renderProcessId, &renderFrameId))
+ if (!content::IsResourceTypeFrame(resourceType) || !resourceInfo->GetRenderFrameForRequest(request, &renderProcessId, &renderFrameId))
return net::OK;
// Track active requests since |callback| and |new_url| are valid
// only until OnURLRequestDestroyed is called for this request.
m_activeRequests.insert(request);
- int navigationType = pageTransitionToNavigationType(info->GetPageTransition());
-
RequestParams params = {
- toQt(request->url()),
- info->IsMainFrame(),
+ qUrl,
+ resourceInfo->IsMainFrame(),
navigationType,
renderProcessId,
renderFrameId
@@ -172,4 +218,88 @@ void NetworkDelegateQt::NotifyNavigationRequestedOnUIThread(net::URLRequest *req
);
}
+bool NetworkDelegateQt::OnCanSetCookie(const net::URLRequest& request,
+ const std::string& cookie_line,
+ net::CookieOptions*)
+{
+ Q_ASSERT(m_requestContextGetter);
+ return m_requestContextGetter->m_cookieDelegate->canSetCookie(toQt(request.first_party_for_cookies()), QByteArray::fromStdString(cookie_line), toQt(request.url()));
+}
+
+void NetworkDelegateQt::OnResolveProxy(const GURL&, int, const net::ProxyService&, net::ProxyInfo*)
+{
+}
+
+void NetworkDelegateQt::OnProxyFallback(const net::ProxyServer&, int)
+{
+}
+
+int NetworkDelegateQt::OnBeforeSendHeaders(net::URLRequest*, const net::CompletionCallback&, net::HttpRequestHeaders*)
+{
+ return net::OK;
+}
+
+void NetworkDelegateQt::OnBeforeSendProxyHeaders(net::URLRequest*, const net::ProxyInfo&, net::HttpRequestHeaders*)
+{
+}
+
+void NetworkDelegateQt::OnSendHeaders(net::URLRequest*, const net::HttpRequestHeaders&)
+{
+}
+
+int NetworkDelegateQt::OnHeadersReceived(net::URLRequest*, const net::CompletionCallback&, const net::HttpResponseHeaders*, scoped_refptr<net::HttpResponseHeaders>*, GURL*)
+{
+ return net::OK;
+}
+
+void NetworkDelegateQt::OnBeforeRedirect(net::URLRequest*, const GURL&)
+{
+}
+
+void NetworkDelegateQt::OnResponseStarted(net::URLRequest*)
+{
+}
+
+void NetworkDelegateQt::OnRawBytesRead(const net::URLRequest&, int)
+{
+}
+
+void NetworkDelegateQt::OnCompleted(net::URLRequest*, bool)
+{
+}
+
+void NetworkDelegateQt::OnPACScriptError(int, const base::string16&)
+{
+}
+
+net::NetworkDelegate::AuthRequiredResponse NetworkDelegateQt::OnAuthRequired(net::URLRequest*, const net::AuthChallengeInfo&, const AuthCallback&, net::AuthCredentials*)
+{
+ return AUTH_REQUIRED_RESPONSE_NO_ACTION;
+}
+
+bool NetworkDelegateQt::OnCanGetCookies(const net::URLRequest&, const net::CookieList&)
+{
+ return true;
+}
+
+bool NetworkDelegateQt::OnCanAccessFile(const net::URLRequest& request, const base::FilePath& path) const
+{
+ return true;
+}
+
+bool NetworkDelegateQt::OnCanEnablePrivacyMode(const GURL&, const GURL&) const
+{
+ return false;
+}
+
+bool NetworkDelegateQt::OnFirstPartyOnlyCookieExperimentEnabled() const
+{
+ return false;
+}
+
+bool NetworkDelegateQt::OnCancelURLRequestWithPolicyViolatingReferrerHeader(const net::URLRequest&, const GURL&, const GURL&) const
+{
+ return false;
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/network_delegate_qt.h b/src/core/network_delegate_qt.h
index 4f4097fd3..41b5b98b6 100644
--- a/src/core/network_delegate_qt.h
+++ b/src/core/network_delegate_qt.h
@@ -42,19 +42,16 @@
#include <QUrl>
#include <QSet>
-#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE
namespace QtWebEngineCore {
+class URLRequestContextGetterQt;
+
class NetworkDelegateQt : public net::NetworkDelegate {
+ QSet<net::URLRequest *> m_activeRequests;
+ URLRequestContextGetterQt *m_requestContextGetter;
public:
- NetworkDelegateQt() {}
- virtual ~NetworkDelegateQt() {}
-
- // net::NetworkDelegate implementation
- virtual int OnBeforeURLRequest(net::URLRequest* request, const net::CompletionCallback& callback, GURL* new_url) Q_DECL_OVERRIDE;
- virtual void OnURLRequestDestroyed(net::URLRequest* request) Q_DECL_OVERRIDE;
- virtual bool OnCanAccessFile(const net::URLRequest& request, const base::FilePath& path) const Q_DECL_OVERRIDE { return true; }
+ NetworkDelegateQt(URLRequestContextGetterQt *requestContext);
struct RequestParams {
QUrl url;
@@ -72,7 +69,27 @@ public:
int navigationRequestAction,
const net::CompletionCallback &callback);
- QSet<net::URLRequest *> m_activeRequests;
+ // net::NetworkDelegate implementation
+ virtual int OnBeforeURLRequest(net::URLRequest* request, const net::CompletionCallback& callback, GURL* newUrl) override;
+ virtual void OnURLRequestDestroyed(net::URLRequest* request) override;
+ virtual bool OnCanSetCookie(const net::URLRequest&, const std::string&, net::CookieOptions*) override;
+ virtual void OnResolveProxy(const GURL&, int, const net::ProxyService&, net::ProxyInfo*) override;
+ virtual void OnProxyFallback(const net::ProxyServer&, int) override;
+ virtual int OnBeforeSendHeaders(net::URLRequest*, const net::CompletionCallback&, net::HttpRequestHeaders*) override;
+ virtual void OnBeforeSendProxyHeaders(net::URLRequest*, const net::ProxyInfo&, net::HttpRequestHeaders*) override;
+ virtual void OnSendHeaders(net::URLRequest*, const net::HttpRequestHeaders&) override;
+ virtual int OnHeadersReceived(net::URLRequest*, const net::CompletionCallback&, const net::HttpResponseHeaders*, scoped_refptr<net::HttpResponseHeaders>*, GURL*) override;
+ virtual void OnBeforeRedirect(net::URLRequest*, const GURL&) override;
+ virtual void OnResponseStarted(net::URLRequest*) override;
+ virtual void OnRawBytesRead(const net::URLRequest&, int) override;
+ virtual void OnCompleted(net::URLRequest*, bool) override;
+ virtual void OnPACScriptError(int, const base::string16&) override;
+ virtual net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(net::URLRequest*, const net::AuthChallengeInfo&, const AuthCallback&, net::AuthCredentials*) override;
+ virtual bool OnCanGetCookies(const net::URLRequest&, const net::CookieList&) override;
+ virtual bool OnCanAccessFile(const net::URLRequest& request, const base::FilePath& path) const override;
+ virtual bool OnCanEnablePrivacyMode(const GURL&, const GURL&) const override;
+ virtual bool OnFirstPartyOnlyCookieExperimentEnabled() const override;
+ virtual bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(const net::URLRequest&, const GURL&, const GURL&) const override;
};
} // namespace QtWebEngineCore
diff --git a/src/core/ozone_platform_eglfs.cpp b/src/core/ozone_platform_eglfs.cpp
index 43a3e4a11..834e41fdf 100644
--- a/src/core/ozone_platform_eglfs.cpp
+++ b/src/core/ozone_platform_eglfs.cpp
@@ -45,6 +45,7 @@
#include "ui/events/ozone/events_ozone.h"
#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/ozone/common/native_display_delegate_ozone.h"
+#include "ui/ozone/common/stub_overlay_manager.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/cursor_factory_ozone.h"
#include "ui/ozone/public/gpu_platform_support.h"
@@ -95,6 +96,7 @@ public:
void Restore() override { }
void SetCursor(PlatformCursor) override { }
void MoveCursorTo(const gfx::Point&) override { }
+ void ConfineCursorToBounds(const gfx::Rect&) override { }
// PlatformEventDispatcher:
bool CanDispatchEvent(const PlatformEvent& event) override;
@@ -160,6 +162,18 @@ scoped_ptr<PlatformWindow> OzonePlatformEglfs::CreatePlatformWindow(
bounds));
}
+ui::InputController* OzonePlatformEglfs::GetInputController() {
+ return input_controller_.get();
+}
+
+scoped_ptr<ui::SystemInputInjector> OzonePlatformEglfs::CreateSystemInputInjector() {
+ return nullptr; // no input injection support.
+}
+
+ui::OverlayManagerOzone* OzonePlatformEglfs::GetOverlayManager() {
+ return overlay_manager_.get();
+}
+
scoped_ptr<ui::NativeDisplayDelegate> OzonePlatformEglfs::CreateNativeDisplayDelegate()
{
return scoped_ptr<NativeDisplayDelegate>(new NativeDisplayDelegateOzone());
@@ -168,10 +182,12 @@ scoped_ptr<ui::NativeDisplayDelegate> OzonePlatformEglfs::CreateNativeDisplayDel
OzonePlatform* CreateOzonePlatformEglfs() { return new OzonePlatformEglfs; }
void OzonePlatformEglfs::InitializeUI() {
+ overlay_manager_.reset(new StubOverlayManager());
device_manager_ = CreateDeviceManager();
cursor_factory_ozone_.reset(new CursorFactoryOzone());
- event_factory_ozone_.reset(new EventFactoryEvdev(NULL, device_manager_.get()));
+ event_factory_ozone_.reset(new EventFactoryEvdev(NULL, device_manager_.get(), NULL));
gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost());
+ input_controller_ = CreateStubInputController();
}
void OzonePlatformEglfs::InitializeGPU() {
diff --git a/src/core/ozone_platform_eglfs.h b/src/core/ozone_platform_eglfs.h
index 6954595dd..69ff2508f 100644
--- a/src/core/ozone_platform_eglfs.h
+++ b/src/core/ozone_platform_eglfs.h
@@ -62,6 +62,9 @@ class OzonePlatformEglfs : public OzonePlatform {
PlatformWindowDelegate* delegate,
const gfx::Rect& bounds) override;
virtual scoped_ptr<ui::NativeDisplayDelegate> CreateNativeDisplayDelegate() override;
+ virtual ui::InputController* GetInputController() override;
+ virtual scoped_ptr<ui::SystemInputInjector> CreateSystemInputInjector() override;
+ virtual ui::OverlayManagerOzone* GetOverlayManager() override;
private:
virtual void InitializeUI() override;
@@ -74,6 +77,8 @@ class OzonePlatformEglfs : public OzonePlatform {
scoped_ptr<GpuPlatformSupport> gpu_platform_support_;
scoped_ptr<GpuPlatformSupportHost> gpu_platform_support_host_;
+ scoped_ptr<InputController> input_controller_;
+ scoped_ptr<OverlayManagerOzone> overlay_manager_;
DISALLOW_COPY_AND_ASSIGN(OzonePlatformEglfs);
};
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
new file mode 100644
index 000000000..d89b530ee
--- /dev/null
+++ b/src/core/permission_manager_qt.cpp
@@ -0,0 +1,211 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "permission_manager_qt.h"
+
+#include "content/browser/renderer_host/render_view_host_delegate.h"
+#include "content/public/browser/permission_type.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/web_contents.h"
+
+#include "type_conversion.h"
+#include "web_contents_delegate_qt.h"
+
+namespace QtWebEngineCore {
+
+BrowserContextAdapter::PermissionType toQt(content::PermissionType type)
+{
+ switch (type) {
+ case content::PermissionType::GEOLOCATION:
+ return BrowserContextAdapter::GeolocationPermission;
+ case content::PermissionType::NOTIFICATIONS:
+ case content::PermissionType::MIDI_SYSEX:
+ case content::PermissionType::PUSH_MESSAGING:
+ case content::PermissionType::PROTECTED_MEDIA_IDENTIFIER:
+ case content::PermissionType::NUM:
+ break;
+ }
+ return BrowserContextAdapter::UnsupportedPermission;
+}
+
+PermissionManagerQt::PermissionManagerQt(BrowserContextAdapter *contextAdapter)
+ : m_contextAdapter(contextAdapter)
+ , m_subscriberCount(0)
+{
+}
+
+PermissionManagerQt::~PermissionManagerQt()
+{
+}
+
+void PermissionManagerQt::permissionRequestReply(const QUrl &origin, BrowserContextAdapter::PermissionType type, bool reply)
+{
+ QPair<QUrl, BrowserContextAdapter::PermissionType> key(origin, type);
+ m_permissions[key] = reply;
+ content::PermissionStatus status = reply ? content::PERMISSION_STATUS_GRANTED : content::PERMISSION_STATUS_DENIED;
+ auto it = m_requests.begin();
+ const auto end = m_requests.end();
+ while (it != end) {
+ if (it->origin == origin && it->type == type) {
+ it->callback.Run(status);
+ it = m_requests.erase(it);
+ } else
+ ++it;
+ }
+ Q_FOREACH (const Subscriber &subscriber, m_subscribers) {
+ if (subscriber.origin == origin && subscriber.type == type)
+ subscriber.callback.Run(status);
+ }
+}
+
+void PermissionManagerQt::RequestPermission(content::PermissionType permission,
+ content::RenderFrameHost *frameHost,
+ int request_id,
+ const GURL& requesting_origin,
+ bool user_gesture,
+ const base::Callback<void(content::PermissionStatus)>& callback)
+{
+ Q_UNUSED(user_gesture);
+ BrowserContextAdapter::PermissionType permissionType = toQt(permission);
+ if (permissionType == BrowserContextAdapter::UnsupportedPermission) {
+ callback.Run(content::PERMISSION_STATUS_DENIED);
+ return;
+ }
+
+ content::WebContents *webContents = frameHost->GetRenderViewHost()->GetDelegate()->GetAsWebContents();
+ WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
+ Q_ASSERT(contentsDelegate);
+ Request request = {
+ request_id,
+ permissionType,
+ toQt(requesting_origin),
+ callback
+ };
+ m_requests.append(request);
+ if (permissionType == BrowserContextAdapter::GeolocationPermission)
+ contentsDelegate->requestGeolocationPermission(request.origin);
+}
+
+void PermissionManagerQt::CancelPermissionRequest(content::PermissionType permission,
+ content::RenderFrameHost *frameHost,
+ int request_id,
+ const GURL& requesting_origin)
+{
+ Q_UNUSED(frameHost);
+ const BrowserContextAdapter::PermissionType permissionType = toQt(permission);
+ if (permissionType == BrowserContextAdapter::UnsupportedPermission)
+ return;
+
+ // Should we add API to cancel permissions in the UI level?
+ const QUrl origin = toQt(requesting_origin);
+ auto it = m_requests.begin();
+ const auto end = m_requests.end();
+ while (it != end) {
+ if (it->id == request_id && it->type == permissionType && it->origin == origin) {
+ m_requests.erase(it);
+ return;
+ }
+ }
+ qWarning() << "PermissionManagerQt::CancelPermissionRequest called on unknown request" << request_id << origin << permissionType;
+}
+
+content::PermissionStatus PermissionManagerQt::GetPermissionStatus(
+ content::PermissionType permission,
+ const GURL& requesting_origin,
+ const GURL& /*embedding_origin*/)
+{
+ const BrowserContextAdapter::PermissionType permissionType = toQt(permission);
+ if (permissionType == BrowserContextAdapter::UnsupportedPermission)
+ return content::PERMISSION_STATUS_DENIED;
+
+ QPair<QUrl, BrowserContextAdapter::PermissionType> key(toQt(requesting_origin), permissionType);
+ if (!m_permissions.contains(key))
+ return content::PERMISSION_STATUS_ASK;
+ if (m_permissions[key])
+ return content::PERMISSION_STATUS_GRANTED;
+ return content::PERMISSION_STATUS_DENIED;
+}
+
+void PermissionManagerQt::ResetPermission(
+ content::PermissionType permission,
+ const GURL& requesting_origin,
+ const GURL& /*embedding_origin*/)
+{
+ const BrowserContextAdapter::PermissionType permissionType = toQt(permission);
+ if (permissionType == BrowserContextAdapter::UnsupportedPermission)
+ return;
+
+ QPair<QUrl, BrowserContextAdapter::PermissionType> key(toQt(requesting_origin), permissionType);
+ m_permissions.remove(key);
+}
+
+void PermissionManagerQt::RegisterPermissionUsage(
+ content::PermissionType /*permission*/,
+ const GURL& /*requesting_origin*/,
+ const GURL& /*embedding_origin*/)
+{
+ // We do not currently track which permissions are used.
+}
+
+int PermissionManagerQt::SubscribePermissionStatusChange(
+ content::PermissionType permission,
+ const GURL& requesting_origin,
+ const GURL& /*embedding_origin*/,
+ const base::Callback<void(content::PermissionStatus)>& callback)
+{
+ Subscriber subscriber = {
+ m_subscriberCount++,
+ toQt(permission),
+ toQt(requesting_origin),
+ callback
+ };
+ m_subscribers.append(subscriber);
+ return subscriber.id;
+}
+
+void PermissionManagerQt::UnsubscribePermissionStatusChange(int subscription_id)
+{
+ for (int i = 0; i < m_subscribers.count(); i++) {
+ if (m_subscribers[i].id == subscription_id) {
+ m_subscribers.removeAt(i);
+ return;
+ }
+ }
+ qWarning() << "PermissionManagerQt::UnsubscribePermissionStatusChange called on unknown subscription id" << subscription_id;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h
new file mode 100644
index 000000000..d4ee72bae
--- /dev/null
+++ b/src/core/permission_manager_qt.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PERMISSION_MANAGER_QT_H
+#define PERMISSION_MANAGER_QT_H
+
+#include "base/callback.h"
+#include "content/public/browser/permission_manager.h"
+#include "browser_context_adapter.h"
+
+#include <QHash>
+#include <QList>
+
+namespace QtWebEngineCore {
+
+class PermissionManagerQt : public content::PermissionManager {
+
+public:
+ PermissionManagerQt(BrowserContextAdapter *);
+ ~PermissionManagerQt();
+ typedef BrowserContextAdapter::PermissionType PermissionType;
+
+ void permissionRequestReply(const QUrl &origin, PermissionType type, bool reply);
+
+ // content::PermissionManager implementation:
+ void RequestPermission(
+ content::PermissionType permission,
+ content::RenderFrameHost* render_frame_host,
+ int request_id,
+ const GURL& requesting_origin,
+ bool user_gesture,
+ const base::Callback<void(content::PermissionStatus)>& callback) override;
+
+ void CancelPermissionRequest(
+ content::PermissionType permission,
+ content::RenderFrameHost* render_frame_host,
+ int request_id,
+ const GURL& requesting_origin) override;
+
+ content::PermissionStatus GetPermissionStatus(
+ content::PermissionType permission,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin) override;
+
+ void ResetPermission(
+ content::PermissionType permission,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin) override;
+
+ void RegisterPermissionUsage(
+ content::PermissionType permission,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin) override;
+
+ int SubscribePermissionStatusChange(
+ content::PermissionType permission,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin,
+ const base::Callback<void(content::PermissionStatus)>& callback) override;
+
+ void UnsubscribePermissionStatusChange(int subscription_id) override;
+
+private:
+ BrowserContextAdapter *m_contextAdapter;
+ QHash<QPair<QUrl, PermissionType>, bool> m_permissions;
+ struct Request {
+ int id;
+ PermissionType type;
+ QUrl origin;
+ base::Callback<void(content::PermissionStatus)> callback;
+ };
+ QList<Request> m_requests;
+ struct Subscriber {
+ int id;
+ PermissionType type;
+ QUrl origin;
+ base::Callback<void(content::PermissionStatus)> callback;
+ };
+ int m_subscriberCount;
+ QList<Subscriber> m_subscribers;
+
+};
+
+} // namespace QtWebEngineCore
+
+#endif // PERMISSION_MANAGER_QT_H
diff --git a/src/core/proxy_config_service_qt.cpp b/src/core/proxy_config_service_qt.cpp
new file mode 100644
index 000000000..fc0959eef
--- /dev/null
+++ b/src/core/proxy_config_service_qt.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "proxy_config_service_qt.h"
+
+#include "base/bind.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qtProxy)
+{
+ net::ProxyServer::Scheme proxyScheme = net::ProxyServer::SCHEME_INVALID;
+ switch (qtProxy.type()) {
+ case QNetworkProxy::Socks5Proxy:
+ proxyScheme = net::ProxyServer::SCHEME_SOCKS5;
+ break;
+ case QNetworkProxy::HttpProxy:
+ case QNetworkProxy::HttpCachingProxy:
+ case QNetworkProxy::FtpCachingProxy:
+ proxyScheme = net::ProxyServer::SCHEME_HTTP;
+ break;
+ case QNetworkProxy::NoProxy:
+ default:
+ proxyScheme = net::ProxyServer::SCHEME_DIRECT;
+ break;
+ }
+ return net::ProxyServer(proxyScheme, net::HostPortPair(qtProxy.hostName().toStdString(), qtProxy.port()));
+}
+
+//================ Based on ChromeProxyConfigService =======================
+
+ProxyConfigServiceQt::ProxyConfigServiceQt(net::ProxyConfigService *baseService)
+ : m_baseService(baseService),
+ m_registeredObserver(false)
+{
+}
+
+ProxyConfigServiceQt::~ProxyConfigServiceQt()
+{
+ if (m_registeredObserver && m_baseService.get())
+ m_baseService->RemoveObserver(this);
+}
+
+void ProxyConfigServiceQt::AddObserver(net::ProxyConfigService::Observer *observer)
+{
+ RegisterObserver();
+ m_observers.AddObserver(observer);
+}
+
+void ProxyConfigServiceQt::RemoveObserver(net::ProxyConfigService::Observer *observer)
+{
+ m_observers.RemoveObserver(observer);
+}
+
+net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxyConfig(net::ProxyConfig *config)
+{
+ RegisterObserver();
+
+ // Ask the base service if available.
+ net::ProxyConfig systemConfig;
+ ConfigAvailability systemAvailability = net::ProxyConfigService::CONFIG_UNSET;
+ if (m_baseService.get())
+ systemAvailability = m_baseService->GetLatestProxyConfig(&systemConfig);
+
+ const QNetworkProxy &qtProxy = QNetworkProxy::applicationProxy();
+ if (qtProxy == m_qtApplicationProxy && !m_qtProxyConfig.proxy_rules().empty()) {
+ *config = m_qtProxyConfig;
+ return CONFIG_VALID;
+ }
+ m_qtApplicationProxy = qtProxy;
+ m_qtProxyConfig = net::ProxyConfig();
+ if (qtProxy.type() == QNetworkProxy::NoProxy) {
+ *config = systemConfig;
+ return systemAvailability;
+ }
+
+ net::ProxyConfig::ProxyRules qtRules;
+ net::ProxyServer server = fromQNetworkProxy(qtProxy);
+ switch (qtProxy.type()) {
+ case QNetworkProxy::HttpProxy:
+ case QNetworkProxy::Socks5Proxy:
+ qtRules.type = net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY;
+ qtRules.single_proxies.SetSingleProxyServer(server);
+ break;
+ case QNetworkProxy::HttpCachingProxy:
+ qtRules.type = net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
+ qtRules.proxies_for_http.SetSingleProxyServer(server);
+ break;
+ case QNetworkProxy::FtpCachingProxy:
+ qtRules.type = net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
+ qtRules.proxies_for_ftp.SetSingleProxyServer(server);
+ break;
+ default:
+ qtRules.type = net::ProxyConfig::ProxyRules::TYPE_NO_RULES;
+ }
+
+ m_qtProxyConfig.proxy_rules() = qtRules;
+ *config = m_qtProxyConfig;
+ return CONFIG_VALID;
+}
+
+void ProxyConfigServiceQt::OnLazyPoll()
+{
+ if (m_qtApplicationProxy != QNetworkProxy::applicationProxy()) {
+ net::ProxyConfig unusedConfig;
+ OnProxyConfigChanged(unusedConfig, CONFIG_VALID);
+ }
+ if (m_baseService.get())
+ m_baseService->OnLazyPoll();
+}
+
+
+void ProxyConfigServiceQt::OnProxyConfigChanged(const net::ProxyConfig &config, ConfigAvailability availability)
+{
+ Q_UNUSED(config);
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ if (m_qtApplicationProxy != QNetworkProxy::applicationProxy()
+ || m_qtApplicationProxy.type() == QNetworkProxy::NoProxy) {
+ net::ProxyConfig actual_config;
+ availability = GetLatestProxyConfig(&actual_config);
+ if (availability == CONFIG_PENDING)
+ return;
+ FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, m_observers,
+ OnProxyConfigChanged(actual_config, availability));
+ }
+}
+
+void ProxyConfigServiceQt::RegisterObserver()
+{
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (!m_registeredObserver && m_baseService.get()) {
+ m_baseService->AddObserver(this);
+ m_registeredObserver = true;
+ }
+}
diff --git a/src/core/proxy_config_service_qt.h b/src/core/proxy_config_service_qt.h
new file mode 100644
index 000000000..ee4263314
--- /dev/null
+++ b/src/core/proxy_config_service_qt.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROXY_CONFIG_SERVICE_QT_H
+#define PROXY_CONFIG_SERVICE_QT_H
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/observer_list.h"
+
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_config_service.h"
+
+#include <QNetworkProxy>
+
+class ProxyConfigServiceQt
+ : public net::ProxyConfigService,
+ public net::ProxyConfigService::Observer {
+public:
+
+ static net::ProxyServer fromQNetworkProxy(const QNetworkProxy &);
+
+ explicit ProxyConfigServiceQt(net::ProxyConfigService *baseService);
+ ~ProxyConfigServiceQt() override;
+
+ // ProxyConfigService implementation:
+ void AddObserver(net::ProxyConfigService::Observer *observer) override;
+ void RemoveObserver(net::ProxyConfigService::Observer *observer) override;
+ ConfigAvailability GetLatestProxyConfig(net::ProxyConfig *config) override;
+ void OnLazyPoll() override;
+
+private:
+ // ProxyConfigService::Observer implementation:
+ void OnProxyConfigChanged(const net::ProxyConfig& config,
+ ConfigAvailability availability) override;
+
+ // Makes sure that the observer registration with the base service is set up.
+ void RegisterObserver();
+
+ scoped_ptr<net::ProxyConfigService> m_baseService;
+ base::ObserverList<net::ProxyConfigService::Observer, true> m_observers;
+
+ // Keep the last QNetworkProxy::applicationProxy state around.
+ QNetworkProxy m_qtApplicationProxy;
+ net::ProxyConfig m_qtProxyConfig;
+
+ // Indicates whether the base service registration is done.
+ bool m_registeredObserver;
+
+ DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceQt);
+};
+
+#endif // PROXY_CONFIG_SERVICE_QT_H
diff --git a/src/core/qtwebengine.gypi b/src/core/qtwebengine.gypi
index b8af2aca8..a420918a0 100644
--- a/src/core/qtwebengine.gypi
+++ b/src/core/qtwebengine.gypi
@@ -8,6 +8,8 @@
'dependencies': [
'<(chromium_src_dir)/base/base.gyp:base',
'<(chromium_src_dir)/base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
+ '<(chromium_src_dir)/components/components.gyp:devtools_discovery',
+ '<(chromium_src_dir)/components/components.gyp:devtools_http_handler',
'<(chromium_src_dir)/components/components.gyp:error_page_renderer',
'<(chromium_src_dir)/components/components.gyp:visitedlink_browser',
'<(chromium_src_dir)/components/components.gyp:visitedlink_renderer',
@@ -16,6 +18,7 @@
'<(chromium_src_dir)/content/content.gyp:content_browser',
'<(chromium_src_dir)/content/content.gyp:content_common',
'<(chromium_src_dir)/content/content.gyp:content_gpu',
+ '<(chromium_src_dir)/content/content.gyp:content_ppapi_plugin',
'<(chromium_src_dir)/content/content.gyp:content_renderer',
'<(chromium_src_dir)/content/content.gyp:content_utility',
'<(chromium_src_dir)/content/app/resources/content_resources.gyp:content_resources',
@@ -81,6 +84,9 @@
],
},
},
+ 'dependencies': [
+ '<(chromium_src_dir)/ui/events/ozone/events_ozone.gyp:events_ozone_evdev'
+ ]
}],
['qt_os=="win32" and qt_gl=="opengl"', {
'include_dirs': [
diff --git a/src/core/qtwebengine_extras.gypi b/src/core/qtwebengine_extras.gypi
index e28d6436e..a5de08b55 100644
--- a/src/core/qtwebengine_extras.gypi
+++ b/src/core/qtwebengine_extras.gypi
@@ -57,6 +57,8 @@
['exclude', 'win/accessibility_ids_win\\.h$'],
['exclude', 'win/accessibility_misc_utils\\.(cc|h)$'],
['exclude', 'win/atl_module\\.h$'],
+ ['exclude', 'platform/ax_platform_node_win\\.(cc|h)$'],
+ ['exclude', 'audio_classifier\\.(cc|h)$'],
],
'defines': [
'TOOLKIT_QT',
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 7c5ed64e7..90c91fd47 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -36,10 +36,12 @@
#include "render_widget_host_view_qt.h"
+#include "common/qt_messages.h"
#include "browser_accessibility_manager_qt.h"
#include "browser_accessibility_qt.h"
#include "chromium_overrides.h"
#include "delegated_frame_node.h"
+#include "qtwebenginecoreglobal_p.h"
#include "render_widget_host_view_qt_delegate.h"
#include "type_conversion.h"
#include "web_contents_adapter.h"
@@ -60,10 +62,11 @@
#include "third_party/WebKit/public/platform/WebCursorInfo.h"
#include "third_party/WebKit/public/web/WebCompositionUnderline.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
+#include "ui/events/blink/blink_event_util.h"
#include "ui/events/event.h"
#include "ui/events/gesture_detection/gesture_provider_config_helper.h"
#include "ui/events/gesture_detection/motion_event.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
#include <QEvent>
#include <QFocusEvent>
@@ -142,7 +145,7 @@ static inline int firstAvailableId(const QMap<int, int> &map)
}
static inline ui::GestureProvider::Config QtGestureProviderConfig() {
- ui::GestureProvider::Config config = ui::DefaultGestureProviderConfig();
+ ui::GestureProvider::Config config = ui::GetGestureProviderConfig(ui::GestureProviderConfigType::CURRENT_PLATFORM);
// Causes an assert in CreateWebGestureEventFromGestureEventData and we don't need them in Qt.
config.gesture_begin_end_types_enabled = false;
config.gesture_detector_config.swipe_enabled = false;
@@ -180,12 +183,14 @@ static inline int flagsFromModifiers(Qt::KeyboardModifiers modifiers)
return modifierFlags;
}
+static uint32 s_eventId = 0;
class MotionEventQt : public ui::MotionEvent {
public:
MotionEventQt(const QList<QTouchEvent::TouchPoint> &touchPoints, const base::TimeTicks &eventTime, Action action, const Qt::KeyboardModifiers modifiers, float dpiScale, int index = -1)
: touchPoints(touchPoints)
, eventTime(eventTime)
, action(action)
+ , eventId(++s_eventId)
, flags(flagsFromModifiers(modifiers))
, index(index)
, dpiScale(dpiScale)
@@ -194,7 +199,7 @@ public:
Q_ASSERT((action != ACTION_DOWN && action != ACTION_UP) || index == 0);
}
- virtual int GetId() const Q_DECL_OVERRIDE { return 0; }
+ virtual uint32 GetUniqueEventId() const Q_DECL_OVERRIDE { return eventId; }
virtual Action GetAction() const Q_DECL_OVERRIDE { return action; }
virtual int GetActionIndex() const Q_DECL_OVERRIDE { return index; }
virtual size_t GetPointerCount() const Q_DECL_OVERRIDE { return touchPoints.size(); }
@@ -233,6 +238,7 @@ private:
QList<QTouchEvent::TouchPoint> touchPoints;
base::TimeTicks eventTime;
Action action;
+ const uint32 eventId;
int flags;
int index;
float dpiScale;
@@ -410,6 +416,14 @@ gfx::Rect RenderWidgetHostViewQt::GetViewBounds() const
return gfx::BoundingRect(p1, p2);
}
+void RenderWidgetHostViewQt::SetBackgroundColor(SkColor color) {
+ RenderWidgetHostViewBase::SetBackgroundColor(color);
+ // Set the background of the compositor if necessary
+ m_delegate->setClearColor(toQt(color));
+ // Set the background of the blink::FrameView
+ m_host->Send(new QtRenderViewObserver_SetBackgroundColor(m_host->GetRoutingID(), color));
+}
+
// Return value indicates whether the mouse is locked successfully or not.
bool RenderWidgetHostViewQt::LockMouse()
{
@@ -428,27 +442,11 @@ void RenderWidgetHostViewQt::UnlockMouse()
m_host->LostMouseLock();
}
-void RenderWidgetHostViewQt::WasShown()
-{
- m_host->WasShown(ui::LatencyInfo());
-}
-
-void RenderWidgetHostViewQt::WasHidden()
-{
- m_host->WasHidden();
-}
-
void RenderWidgetHostViewQt::MovePluginWindows(const std::vector<content::WebPluginGeometry>&)
{
// QT_NOT_YET_IMPLEMENTED
}
-void RenderWidgetHostViewQt::Blur()
-{
- m_host->SetInputMethodActive(false);
- m_host->Blur();
-}
-
void RenderWidgetHostViewQt::UpdateCursor(const content::WebCursor &webCursor)
{
content::WebCursor::CursorInfo cursorInfo;
@@ -571,8 +569,11 @@ void RenderWidgetHostViewQt::ImeCompositionRangeChanged(const gfx::Range&, const
QT_NOT_YET_IMPLEMENTED
}
-void RenderWidgetHostViewQt::RenderProcessGone(base::TerminationStatus, int)
+void RenderWidgetHostViewQt::RenderProcessGone(base::TerminationStatus terminationStatus,
+ int exitCode)
{
+ m_adapterClient->renderProcessTerminated(
+ m_adapterClient->renderProcessExitStatus(terminationStatus), exitCode);
Destroy();
}
@@ -602,13 +603,13 @@ void RenderWidgetHostViewQt::SelectionBoundsChanged(const ViewHostMsg_SelectionB
m_cursorRect = QRect(caretRect.x(), caretRect.y(), caretRect.width(), caretRect.height());
}
-void RenderWidgetHostViewQt::CopyFromCompositingSurface(const gfx::Rect& src_subrect, const gfx::Size& dst_size, content::CopyFromCompositingSurfaceCallback& callback, const SkColorType color_type)
+void RenderWidgetHostViewQt::CopyFromCompositingSurface(const gfx::Rect& src_subrect, const gfx::Size& dst_size, content::ReadbackRequestCallback& callback, const SkColorType color_type)
{
NOTIMPLEMENTED();
Q_UNUSED(src_subrect);
Q_UNUSED(dst_size);
Q_UNUSED(color_type);
- callback.Run(false, SkBitmap());
+ callback.Run(SkBitmap(), content::READBACK_FAILED);
}
void RenderWidgetHostViewQt::CopyFromCompositingSurfaceToVideoFrame(const gfx::Rect& src_subrect, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(bool)>& callback)
@@ -690,7 +691,7 @@ void RenderWidgetHostViewQt::SelectionChanged(const base::string16 &text, size_t
void RenderWidgetHostViewQt::OnGestureEvent(const ui::GestureEventData& gesture)
{
- m_host->ForwardGestureEvent(content::CreateWebGestureEventFromGestureEventData(gesture));
+ m_host->ForwardGestureEvent(ui::CreateWebGestureEventFromGestureEventData(gesture));
}
QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode)
@@ -719,12 +720,12 @@ void RenderWidgetHostViewQt::notifyResize()
void RenderWidgetHostViewQt::notifyShown()
{
- WasShown();
+ m_host->WasShown(ui::LatencyInfo());
}
void RenderWidgetHostViewQt::notifyHidden()
{
- WasHidden();
+ m_host->WasHidden();
}
void RenderWidgetHostViewQt::windowBoundsChanged()
@@ -810,7 +811,7 @@ QVariant RenderWidgetHostViewQt::inputMethodQuery(Qt::InputMethodQuery query) co
void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) {
Q_UNUSED(touch);
const bool eventConsumed = ack_result == content::INPUT_EVENT_ACK_STATE_CONSUMED;
- m_gestureProvider.OnTouchEventAck(eventConsumed);
+ m_gestureProvider.OnTouchEventAck(touch.event.uniqueTouchEventId, eventConsumed);
}
void RenderWidgetHostViewQt::sendDelegatedFrameAck()
@@ -824,16 +825,10 @@ void RenderWidgetHostViewQt::sendDelegatedFrameAck()
void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEvent)
{
- if (!m_gestureProvider.OnTouchEvent(motionEvent))
+ if (!m_gestureProvider.OnTouchEvent(motionEvent).succeeded)
return;
- // Short-circuit touch forwarding if no touch handlers exist.
- if (!m_host->ShouldForwardTouchEvent()) {
- const bool eventConsumed = false;
- m_gestureProvider.OnTouchEventAck(eventConsumed);
- return;
- }
- blink::WebTouchEvent touchEvent = content::CreateWebTouchEventFromMotionEvent(motionEvent);
+ blink::WebTouchEvent touchEvent = ui::CreateWebTouchEventFromMotionEvent(motionEvent, false);
m_host->ForwardTouchEventWithLatencyInfo(touchEvent, CreateLatencyInfo(touchEvent));
}
@@ -933,14 +928,9 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev)
if (preeditString.isEmpty())
break;
- QTextCharFormat textCharFormat = attribute.value.value<QTextFormat>().toCharFormat();
- QColor qcolor = textCharFormat.underlineColor();
- QColor qBackgroundColor = textCharFormat.background().color();
- blink::WebColor color = SkColorSetARGB(qcolor.alpha(), qcolor.red(), qcolor.green(), qcolor.blue());
- blink::WebColor backgroundColor = SkColorSetARGB(qBackgroundColor.alpha(), qBackgroundColor.red(), qBackgroundColor.green(), qBackgroundColor.blue());
int start = qMin(attribute.start, (attribute.start + attribute.length));
int end = qMax(attribute.start, (attribute.start + attribute.length));
- underlines.push_back(blink::WebCompositionUnderline(start, end, color, false, backgroundColor));
+ underlines.push_back(blink::WebCompositionUnderline(start, end, /*color*/ SK_ColorBLACK, /*thick*/ false, /*backgroundColor*/ SK_ColorTRANSPARENT));
break;
}
case QInputMethodEvent::Cursor:
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 248c52f6e..274138dcf 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -47,6 +47,7 @@
#include "content/common/gpu/gpu_messages.h"
#include "content/common/view_messages.h"
#include "ui/events/gesture_detection/filtered_gesture_provider.h"
+#include "qtwebenginecoreglobal_p.h"
#include <QMap>
#include <QPoint>
#include <QRect>
@@ -125,12 +126,10 @@ public:
virtual void Hide() Q_DECL_OVERRIDE;
virtual bool IsShowing() Q_DECL_OVERRIDE;
virtual gfx::Rect GetViewBounds() const Q_DECL_OVERRIDE;
+ virtual void SetBackgroundColor(SkColor color) Q_DECL_OVERRIDE;
virtual bool LockMouse() Q_DECL_OVERRIDE;
virtual void UnlockMouse() Q_DECL_OVERRIDE;
- virtual void WasShown() Q_DECL_OVERRIDE;
- virtual void WasHidden() Q_DECL_OVERRIDE;
virtual void MovePluginWindows(const std::vector<content::WebPluginGeometry>&) Q_DECL_OVERRIDE;
- virtual void Blur() Q_DECL_OVERRIDE;
virtual void UpdateCursor(const content::WebCursor&) Q_DECL_OVERRIDE;
virtual void SetIsLoading(bool) Q_DECL_OVERRIDE;
virtual void TextInputTypeChanged(ui::TextInputType type, ui::TextInputMode mode, bool can_compose_inline, int flags) Q_DECL_OVERRIDE;
@@ -140,7 +139,7 @@ public:
virtual void Destroy() Q_DECL_OVERRIDE;
virtual void SetTooltipText(const base::string16 &tooltip_text) Q_DECL_OVERRIDE;
virtual void SelectionBoundsChanged(const ViewHostMsg_SelectionBounds_Params&) Q_DECL_OVERRIDE;
- virtual void CopyFromCompositingSurface(const gfx::Rect& src_subrect, const gfx::Size& dst_size, content::CopyFromCompositingSurfaceCallback& callback, const SkColorType color_type) Q_DECL_OVERRIDE;
+ virtual void CopyFromCompositingSurface(const gfx::Rect& src_subrect, const gfx::Size& dst_size, content::ReadbackRequestCallback& callback, const SkColorType color_type) Q_DECL_OVERRIDE;
virtual void CopyFromCompositingSurfaceToVideoFrame(const gfx::Rect& src_subrect, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(bool)>& callback) Q_DECL_OVERRIDE;
virtual bool CanCopyToVideoFrame() const Q_DECL_OVERRIDE;
virtual bool HasAcceleratedSurface(const gfx::Size&) Q_DECL_OVERRIDE;
diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h
index da595b91f..f4aa9b27d 100644
--- a/src/core/render_widget_host_view_qt_delegate.h
+++ b/src/core/render_widget_host_view_qt_delegate.h
@@ -96,6 +96,7 @@ public:
virtual void move(const QPoint &) = 0;
virtual void inputMethodStateChanged(bool editorVisible) = 0;
virtual void setTooltip(const QString &) = 0;
+ virtual void setClearColor(const QColor &color) = 0;
};
} // namespace QtWebEngineCore
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index e1333144a..72ca29be9 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -44,13 +44,16 @@
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "net/base/net_errors.h"
+#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURLError.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
+#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/webui/jstemplate_builder.h"
#include "content/public/common/web_preferences.h"
#include "renderer/web_channel_ipc_transport.h"
+#include "renderer/qt_render_frame_observer.h"
#include "renderer/qt_render_view_observer.h"
#include "renderer/user_script_controller.h"
@@ -59,6 +62,7 @@
namespace QtWebEngineCore {
static const char kHttpErrorDomain[] = "http";
+static const char kQrcSchemeQt[] = "qrc";
ContentRendererClientQt::ContentRendererClientQt()
{
@@ -75,6 +79,9 @@ void ContentRendererClientQt::RenderThreadStarted()
m_visitedLinkSlave.reset(new visitedlink::VisitedLinkSlave);
renderThread->AddObserver(m_visitedLinkSlave.data());
renderThread->AddObserver(UserScriptController::instance());
+
+ // mark qrc as a secure scheme (avoids deprecation warnings)
+ blink::WebSecurityPolicy::registerURLSchemeAsSecure(blink::WebString::fromLatin1(kQrcSchemeQt));
}
void ContentRendererClientQt::RenderViewCreated(content::RenderView* render_view)
@@ -85,6 +92,11 @@ void ContentRendererClientQt::RenderViewCreated(content::RenderView* render_view
UserScriptController::instance()->renderViewCreated(render_view);
}
+void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame* render_frame)
+{
+ new QtWebEngineCore::QtRenderFrameObserver(render_frame);
+}
+
bool ContentRendererClientQt::HasErrorPage(int httpStatusCode, std::string *errorDomain)
{
// Use an internal error page, if we have one for the status code.
@@ -105,7 +117,7 @@ bool ContentRendererClientQt::ShouldSuppressErrorPage(content::RenderFrame *fram
void ContentRendererClientQt::GetNavigationErrorStrings(content::RenderView* renderView, blink::WebFrame *frame, const blink::WebURLRequest &failedRequest, const blink::WebURLError &error, std::string *errorHtml, base::string16 *errorDescription)
{
Q_UNUSED(frame)
- const bool isPost = EqualsASCII(failedRequest.httpMethod(), "POST");
+ const bool isPost = base::EqualsASCII(failedRequest.httpMethod(), "POST");
if (errorHtml) {
// Use a local error page.
diff --git a/src/core/renderer/content_renderer_client_qt.h b/src/core/renderer/content_renderer_client_qt.h
index dcb4e7fcb..fab88441f 100644
--- a/src/core/renderer/content_renderer_client_qt.h
+++ b/src/core/renderer/content_renderer_client_qt.h
@@ -53,7 +53,7 @@ public:
~ContentRendererClientQt();
virtual void RenderThreadStarted() Q_DECL_OVERRIDE;
virtual void RenderViewCreated(content::RenderView *render_view) Q_DECL_OVERRIDE;
-
+ virtual void RenderFrameCreated(content::RenderFrame* render_frame) Q_DECL_OVERRIDE;
virtual bool ShouldSuppressErrorPage(content::RenderFrame *, const GURL &) Q_DECL_OVERRIDE;
virtual bool HasErrorPage(int httpStatusCode, std::string *errorDomain) Q_DECL_OVERRIDE;
virtual void GetNavigationErrorStrings(content::RenderView* renderView, blink::WebFrame* frame, const blink::WebURLRequest& failedRequest
diff --git a/src/core/renderer/pepper/pepper_flash_browser_host_qt.cpp b/src/core/renderer/pepper/pepper_flash_browser_host_qt.cpp
new file mode 100644
index 000000000..625e89ae4
--- /dev/null
+++ b/src/core/renderer/pepper/pepper_flash_browser_host_qt.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pepper_flash_browser_host_qt.h"
+
+#include "base/time/time.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_ppapi_host.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
+#include "ipc/ipc_message_macros.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/private/ppb_flash.h"
+#include "ppapi/host/dispatch_host_message.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/resource_message_params.h"
+#include "ppapi/shared_impl/time_conversion.h"
+#include "qtwebenginecoreglobal_p.h"
+#include "url/gurl.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#elif defined(OS_MACOSX)
+#include <CoreServices/CoreServices.h>
+#endif
+
+using content::BrowserPpapiHost;
+using content::BrowserThread;
+using content::RenderProcessHost;
+
+namespace QtWebEngineCore {
+
+
+PepperFlashBrowserHostQt::PepperFlashBrowserHostQt(BrowserPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource)
+ : ResourceHost(host->GetPpapiHost(), instance, resource),
+ host_(host),
+ weak_factory_(this)
+{
+ int unused;
+ host->GetRenderFrameIDsForInstance(instance, &render_process_id_, &unused);
+}
+
+PepperFlashBrowserHostQt::~PepperFlashBrowserHostQt() {}
+
+int32_t PepperFlashBrowserHostQt::OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context)
+{
+ PPAPI_BEGIN_MESSAGE_MAP(PepperFlashBrowserHostQt, msg)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Flash_UpdateActivity,
+ OnUpdateActivity)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_GetLocalTimeZoneOffset,
+ OnGetLocalTimeZoneOffset)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Flash_GetLocalDataRestrictions,
+ OnGetLocalDataRestrictions)
+ PPAPI_END_MESSAGE_MAP()
+ return PP_ERROR_FAILED;
+}
+
+int32_t PepperFlashBrowserHostQt::OnUpdateActivity(ppapi::host::HostMessageContext* host_context)
+{
+#if defined(OS_WIN)
+ // Reading then writing back the same value to the screensaver timeout system
+ // setting resets the countdown which prevents the screensaver from turning
+ // on "for a while". As long as the plugin pings us with this message faster
+ // than the screensaver timeout, it won't go on.
+ int value = 0;
+ if (SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, &value, 0))
+ SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, value, NULL, 0);
+#elif defined(OS_MACOSX)
+ UpdateSystemActivity(OverallAct);
+#endif
+ return PP_OK;
+}
+
+int32_t PepperFlashBrowserHostQt::OnGetLocalTimeZoneOffset(
+ ppapi::host::HostMessageContext* host_context,
+ const base::Time& t)
+{
+ // The reason for this processing being in the browser process is that on
+ // Linux, the localtime calls require filesystem access prohibited by the
+ // sandbox.
+ host_context->reply_msg = PpapiPluginMsg_Flash_GetLocalTimeZoneOffsetReply(
+ ppapi::PPGetLocalTimeZoneOffset(t));
+ return PP_OK;
+}
+
+int32_t PepperFlashBrowserHostQt::OnGetLocalDataRestrictions(
+ ppapi::host::HostMessageContext* context)
+{
+ QT_NOT_YET_IMPLEMENTED
+ return PP_OK;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/renderer/pepper/pepper_flash_browser_host_qt.h b/src/core/renderer/pepper/pepper_flash_browser_host_qt.h
new file mode 100644
index 000000000..c5165a1b0
--- /dev/null
+++ b/src/core/renderer/pepper/pepper_flash_browser_host_qt.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PEPPER_FLASH_BROWSER_HOST_QT_H
+#define PEPPER_FLASH_BROWSER_HOST_QT_H
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "ppapi/host/host_message_context.h"
+#include "ppapi/host/resource_host.h"
+
+namespace base {
+class Time;
+}
+
+namespace content {
+class BrowserPpapiHost;
+class ResourceContext;
+}
+
+class GURL;
+
+namespace QtWebEngineCore {
+
+class PepperFlashBrowserHostQt : public ppapi::host::ResourceHost {
+public:
+ PepperFlashBrowserHostQt(content::BrowserPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource);
+ ~PepperFlashBrowserHostQt() override;
+
+ // ppapi::host::ResourceHost override.
+ int32_t OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context) override;
+
+private:
+ int32_t OnUpdateActivity(ppapi::host::HostMessageContext* host_context);
+ int32_t OnGetLocalTimeZoneOffset(
+ ppapi::host::HostMessageContext* host_context,
+ const base::Time& t);
+ int32_t OnGetLocalDataRestrictions(ppapi::host::HostMessageContext* context);
+
+ void GetLocalDataRestrictions(ppapi::host::ReplyMessageContext reply_context,
+ const GURL& document_url,
+ const GURL& plugin_url);
+
+ content::BrowserPpapiHost* host_;
+ int render_process_id_;
+ base::WeakPtrFactory<PepperFlashBrowserHostQt> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperFlashBrowserHostQt);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // PEPPER_FLASH_BROWSER_HOST_QT_H
diff --git a/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp
new file mode 100644
index 000000000..8e68d1682
--- /dev/null
+++ b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp
@@ -0,0 +1,349 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pepper_flash_renderer_host_qt.h"
+
+#include <map>
+#include <vector>
+
+#include "base/lazy_instance.h"
+#include "base/metrics/histogram.h"
+#include "base/strings/string_util.h"
+#include "content/public/renderer/pepper_plugin_instance.h"
+#include "content/public/renderer/render_thread.h"
+#include "content/public/renderer/renderer_ppapi_host.h"
+#include "ipc/ipc_message_macros.h"
+#include "net/http/http_util.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/trusted/ppb_browser_font_trusted.h"
+#include "ppapi/host/dispatch_host_message.h"
+#include "ppapi/proxy/host_dispatcher.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/resource_message_params.h"
+#include "ppapi/proxy/serialized_structs.h"
+#include "ppapi/thunk/enter.h"
+#include "ppapi/thunk/ppb_image_data_api.h"
+#include "skia/ext/platform_canvas.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkMatrix.h"
+#include "third_party/skia/include/core/SkPaint.h"
+#include "third_party/skia/include/core/SkPoint.h"
+#include "third_party/skia/include/core/SkTemplates.h"
+#include "third_party/skia/include/core/SkTypeface.h"
+#include "ui/gfx/geometry/rect.h"
+#include "url/gurl.h"
+
+using ppapi::thunk::EnterResourceNoLock;
+using ppapi::thunk::PPB_ImageData_API;
+
+namespace {
+
+// Some non-simple HTTP request headers that Flash may set.
+// (Please see http://www.w3.org/TR/cors/#simple-header for the definition of
+// simple headers.)
+//
+// The list and the enum defined below are used to collect data about request
+// headers used in PPB_Flash.Navigate() calls, in order to understand the impact
+// of rejecting PPB_Flash.Navigate() requests with non-simple headers.
+//
+// TODO(yzshen): We should be able to remove the histogram recording code once
+// we get the answer.
+const char* const kRejectedHttpRequestHeaders[] = {
+ "authorization", //
+ "cache-control", //
+ "content-encoding", //
+ "content-md5", //
+ "content-type", // If the media type is not one of those covered by the
+ // simple header definition.
+ "expires", //
+ "from", //
+ "if-match", //
+ "if-none-match", //
+ "if-range", //
+ "if-unmodified-since", //
+ "pragma", //
+ "referer" //
+};
+
+// Please note that new entries should be added right above
+// FLASH_NAVIGATE_USAGE_ENUM_COUNT, and existing entries shouldn't be re-ordered
+// or removed, since this ordering is used in a histogram.
+enum FlashNavigateUsage {
+ // This section must be in the same order as kRejectedHttpRequestHeaders.
+ REJECT_AUTHORIZATION = 0,
+ REJECT_CACHE_CONTROL,
+ REJECT_CONTENT_ENCODING,
+ REJECT_CONTENT_MD5,
+ REJECT_CONTENT_TYPE,
+ REJECT_EXPIRES,
+ REJECT_FROM,
+ REJECT_IF_MATCH,
+ REJECT_IF_NONE_MATCH,
+ REJECT_IF_RANGE,
+ REJECT_IF_UNMODIFIED_SINCE,
+ REJECT_PRAGMA,
+ REJECT_REFERER,
+
+ // The navigate request is rejected because of headers not listed above
+ // (e.g., custom headers).
+ REJECT_OTHER_HEADERS,
+
+ // Total number of rejected navigate requests.
+ TOTAL_REJECTED_NAVIGATE_REQUESTS,
+
+ // Total number of navigate requests.
+ TOTAL_NAVIGATE_REQUESTS,
+ FLASH_NAVIGATE_USAGE_ENUM_COUNT
+};
+
+static base::LazyInstance<std::map<std::string, FlashNavigateUsage> >
+g_rejected_headers = LAZY_INSTANCE_INITIALIZER;
+
+bool IsSimpleHeader(const std::string& lower_case_header_name,
+ const std::string& header_value)
+{
+ if (lower_case_header_name == "accept" ||
+ lower_case_header_name == "accept-language" ||
+ lower_case_header_name == "content-language")
+ return true;
+
+ if (lower_case_header_name == "content-type") {
+ std::string lower_case_mime_type;
+ std::string lower_case_charset;
+ bool had_charset = false;
+ net::HttpUtil::ParseContentType(header_value,
+ &lower_case_mime_type,
+ &lower_case_charset,
+ &had_charset,
+ NULL);
+ return lower_case_mime_type == "application/x-www-form-urlencoded" ||
+ lower_case_mime_type == "multipart/form-data" ||
+ lower_case_mime_type == "text/plain";
+ }
+
+ return false;
+}
+
+void RecordFlashNavigateUsage(FlashNavigateUsage usage)
+{
+ DCHECK_NE(FLASH_NAVIGATE_USAGE_ENUM_COUNT, usage);
+ UMA_HISTOGRAM_ENUMERATION(
+ "Plugin.FlashNavigateUsage",
+ usage,
+ FLASH_NAVIGATE_USAGE_ENUM_COUNT);
+}
+
+} // namespace
+
+namespace QtWebEngineCore {
+
+PepperFlashRendererHostQt::PepperFlashRendererHostQt(
+ content::RendererPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource)
+ : ResourceHost(host->GetPpapiHost(), instance, resource),
+ host_(host),
+ weak_factory_(this)
+{
+}
+
+PepperFlashRendererHostQt::~PepperFlashRendererHostQt() {
+ // This object may be destroyed in the middle of a sync message. If that is
+ // the case, make sure we respond to all the pending navigate calls.
+ std::vector<ppapi::host::ReplyMessageContext>::reverse_iterator it;
+ for (it = navigate_replies_.rbegin(); it != navigate_replies_.rend(); ++it)
+ SendReply(*it, IPC::Message());
+}
+
+int32_t PepperFlashRendererHostQt::OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context)
+{
+ PPAPI_BEGIN_MESSAGE_MAP(PepperFlashRendererHostQt, msg)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_GetProxyForURL,
+ OnGetProxyForURL)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_SetInstanceAlwaysOnTop,
+ OnSetInstanceAlwaysOnTop)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_DrawGlyphs,
+ OnDrawGlyphs)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_Navigate, OnNavigate)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_IsRectTopmost,
+ OnIsRectTopmost)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Flash_InvokePrinting,
+ OnInvokePrinting)
+ PPAPI_END_MESSAGE_MAP()
+ return PP_ERROR_FAILED;
+}
+
+int32_t PepperFlashRendererHostQt::OnGetProxyForURL(
+ ppapi::host::HostMessageContext* host_context,
+ const std::string& url)
+{
+ GURL gurl(url);
+ if (!gurl.is_valid())
+ return PP_ERROR_FAILED;
+ std::string proxy;
+ bool result = content::RenderThread::Get()->ResolveProxy(gurl, &proxy);
+ if (!result)
+ return PP_ERROR_FAILED;
+ host_context->reply_msg = PpapiPluginMsg_Flash_GetProxyForURLReply(proxy);
+ return PP_OK;
+}
+
+int32_t PepperFlashRendererHostQt::OnSetInstanceAlwaysOnTop(
+ ppapi::host::HostMessageContext* host_context,
+ bool on_top)
+{
+ content::PepperPluginInstance* plugin_instance =
+ host_->GetPluginInstance(pp_instance());
+ if (plugin_instance)
+ plugin_instance->SetAlwaysOnTop(on_top);
+ return PP_OK;
+}
+
+int32_t PepperFlashRendererHostQt::OnDrawGlyphs(
+ ppapi::host::HostMessageContext* host_context,
+ ppapi::proxy::PPBFlash_DrawGlyphs_Params params)
+{
+ if (params.glyph_indices.size() != params.glyph_advances.size() ||
+ params.glyph_indices.empty())
+ return PP_ERROR_FAILED;
+
+ return PP_OK;
+}
+
+// CAUTION: This code is subtle because Navigate is a sync call which may
+// cause re-entrancy or cause the instance to be destroyed. If the instance
+// is destroyed we need to ensure that we respond to all outstanding sync
+// messages so that the plugin process does not remain blocked.
+int32_t PepperFlashRendererHostQt::OnNavigate(
+ ppapi::host::HostMessageContext* host_context,
+ const ppapi::URLRequestInfoData& data,
+ const std::string& target,
+ bool from_user_action)
+{
+ // If our PepperPluginInstance is already destroyed, just return a failure.
+ content::PepperPluginInstance* plugin_instance =
+ host_->GetPluginInstance(pp_instance());
+ if (!plugin_instance)
+ return PP_ERROR_FAILED;
+
+ std::map<std::string, FlashNavigateUsage>& rejected_headers =
+ g_rejected_headers.Get();
+ if (rejected_headers.empty()) {
+ for (size_t i = 0; i < arraysize(kRejectedHttpRequestHeaders); ++i)
+ rejected_headers[kRejectedHttpRequestHeaders[i]] =
+ static_cast<FlashNavigateUsage>(i);
+ }
+
+ net::HttpUtil::HeadersIterator header_iter(
+ data.headers.begin(), data.headers.end(), "\n\r");
+ bool rejected = false;
+ while (header_iter.GetNext()) {
+ std::string lower_case_header_name =
+ base::StringToLowerASCII(header_iter.name());
+ if (!IsSimpleHeader(lower_case_header_name, header_iter.values())) {
+ rejected = true;
+
+ std::map<std::string, FlashNavigateUsage>::const_iterator iter =
+ rejected_headers.find(lower_case_header_name);
+ FlashNavigateUsage usage =
+ iter != rejected_headers.end() ? iter->second : REJECT_OTHER_HEADERS;
+ RecordFlashNavigateUsage(usage);
+ }
+ }
+
+ RecordFlashNavigateUsage(TOTAL_NAVIGATE_REQUESTS);
+ if (rejected) {
+ RecordFlashNavigateUsage(TOTAL_REJECTED_NAVIGATE_REQUESTS);
+ return PP_ERROR_NOACCESS;
+ }
+
+ // Navigate may call into Javascript (e.g. with a "javascript:" URL),
+ // or do things like navigate away from the page, either one of which will
+ // need to re-enter into the plugin. It is safe, because it is essentially
+ // equivalent to NPN_GetURL, where Flash would expect re-entrancy.
+ ppapi::proxy::HostDispatcher* host_dispatcher =
+ ppapi::proxy::HostDispatcher::GetForInstance(pp_instance());
+ host_dispatcher->set_allow_plugin_reentrancy();
+
+ // Grab a weak pointer to ourselves on the stack so we can check if we are
+ // still alive.
+ base::WeakPtr<PepperFlashRendererHostQt> weak_ptr = weak_factory_.GetWeakPtr();
+ // Keep track of reply contexts in case we are destroyed during a Navigate
+ // call. Even if we are destroyed, we still need to send these replies to
+ // unblock the plugin process.
+ navigate_replies_.push_back(host_context->MakeReplyMessageContext());
+ plugin_instance->Navigate(data, target.c_str(), from_user_action);
+ // This object might have been destroyed by this point. If it is destroyed
+ // the reply will be sent in the destructor. Otherwise send the reply here.
+ if (weak_ptr.get()) {
+ SendReply(navigate_replies_.back(), IPC::Message());
+ navigate_replies_.pop_back();
+ }
+
+ // Return PP_OK_COMPLETIONPENDING so that no reply is automatically sent.
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t PepperFlashRendererHostQt::OnIsRectTopmost(
+ ppapi::host::HostMessageContext* host_context,
+ const PP_Rect& rect)
+{
+ content::PepperPluginInstance* plugin_instance =
+ host_->GetPluginInstance(pp_instance());
+ if (plugin_instance &&
+ plugin_instance->IsRectTopmost(
+ gfx::Rect(
+ rect.point.x,
+ rect.point.y,
+ rect.size.width,
+ rect.size.height)))
+ return PP_OK;
+ return PP_ERROR_FAILED;
+}
+
+int32_t PepperFlashRendererHostQt::OnInvokePrinting(
+ ppapi::host::HostMessageContext* host_context)
+{
+ return PP_ERROR_FAILED;
+}
+
+} //QtWebEngineCore
diff --git a/src/core/renderer/pepper/pepper_flash_renderer_host_qt.h b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.h
new file mode 100644
index 000000000..4a731fad4
--- /dev/null
+++ b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PEPPER_FLASH_RENDERER_HOST_QT_H
+#define PEPPER_FLASH_RENDERER_HOST_QT_H
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/weak_ptr.h"
+#include "ppapi/host/host_message_context.h"
+#include "ppapi/host/resource_host.h"
+
+struct PP_Rect;
+
+namespace ppapi {
+struct URLRequestInfoData;
+}
+
+namespace ppapi {
+namespace proxy {
+struct PPBFlash_DrawGlyphs_Params;
+}
+}
+
+namespace content {
+class RendererPpapiHost;
+}
+
+namespace QtWebEngineCore {
+
+class PepperFlashRendererHostQt : public ppapi::host::ResourceHost {
+public:
+ PepperFlashRendererHostQt(content::RendererPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource);
+ ~PepperFlashRendererHostQt() override;
+
+ // ppapi::host::ResourceHost override.
+ int32_t OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context) override;
+
+private:
+ int32_t OnGetProxyForURL(ppapi::host::HostMessageContext* host_context,
+ const std::string& url);
+ int32_t OnSetInstanceAlwaysOnTop(
+ ppapi::host::HostMessageContext* host_context,
+ bool on_top);
+ int32_t OnDrawGlyphs(ppapi::host::HostMessageContext* host_context,
+ ppapi::proxy::PPBFlash_DrawGlyphs_Params params);
+ int32_t OnNavigate(ppapi::host::HostMessageContext* host_context,
+ const ppapi::URLRequestInfoData& data,
+ const std::string& target,
+ bool from_user_action);
+ int32_t OnIsRectTopmost(ppapi::host::HostMessageContext* host_context,
+ const PP_Rect& rect);
+ int32_t OnInvokePrinting(ppapi::host::HostMessageContext* host_context);
+
+ // A stack of ReplyMessageContexts to track Navigate() calls which have not
+ // yet been replied to.
+ std::vector<ppapi::host::ReplyMessageContext> navigate_replies_;
+
+ content::RendererPpapiHost* host_;
+ base::WeakPtrFactory<PepperFlashRendererHostQt> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperFlashRendererHostQt);
+};
+
+} //QtWebEngineCore
+#endif // PEPPER_FLASH_RENDERER_HOST_QT_H
diff --git a/src/core/renderer/pepper/pepper_host_factory_qt.cpp b/src/core/renderer/pepper/pepper_host_factory_qt.cpp
new file mode 100644
index 000000000..61eeac9a0
--- /dev/null
+++ b/src/core/renderer/pepper/pepper_host_factory_qt.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "pepper_host_factory_qt.h"
+
+#include "build/build_config.h"
+#include "content/public/browser/browser_ppapi_host.h"
+#include "ppapi/host/message_filter_host.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/host/resource_host.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/shared_impl/ppapi_permissions.h"
+#include "pepper_flash_browser_host_qt.h"
+
+using ppapi::host::MessageFilterHost;
+using ppapi::host::ResourceHost;
+using ppapi::host::ResourceMessageFilter;
+
+namespace QtWebEngineCore {
+
+PepperHostFactoryQt::PepperHostFactoryQt(content::BrowserPpapiHost* host)
+ : host_(host)
+{
+}
+
+PepperHostFactoryQt::~PepperHostFactoryQt() {}
+
+scoped_ptr<ppapi::host::ResourceHost> PepperHostFactoryQt::CreateResourceHost(ppapi::host::PpapiHost* host,
+ PP_Resource resource,
+ PP_Instance instance,
+ const IPC::Message& message)
+{
+ DCHECK(host == host_->GetPpapiHost());
+
+
+ if (!host_->IsValidInstance(instance))
+ return scoped_ptr<ppapi::host::ResourceHost>();
+
+ if (host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_FLASH)
+ && message.type() == PpapiHostMsg_Flash_Create::ID)
+ return scoped_ptr<ppapi::host::ResourceHost>(
+ new PepperFlashBrowserHostQt(host_,
+ instance,
+ resource));
+
+ return scoped_ptr<ppapi::host::ResourceHost>();
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/renderer/pepper/pepper_host_factory_qt.h b/src/core/renderer/pepper/pepper_host_factory_qt.h
new file mode 100644
index 000000000..22bf87b1b
--- /dev/null
+++ b/src/core/renderer/pepper/pepper_host_factory_qt.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PEPPER_HOST_FACTORY_QT_H
+#define PEPPER_HOST_FACTORY_QT_H
+
+#include "base/compiler_specific.h"
+#include "ppapi/host/host_factory.h"
+#include "ppapi/host/resource_host.h"
+#include "ppapi/host/ppapi_host.h"
+
+namespace content {
+class BrowserPpapiHost;
+} // namespace content
+
+namespace QtWebEngineCore {
+
+class PepperHostFactoryQt final : public ppapi::host::HostFactory {
+public:
+ // Non-owning pointer to the filter must outlive this class.
+ explicit PepperHostFactoryQt(content::BrowserPpapiHost* host);
+ ~PepperHostFactoryQt() override;
+
+ virtual scoped_ptr<ppapi::host::ResourceHost> CreateResourceHost(
+ ppapi::host::PpapiHost* host,
+ PP_Resource resource,
+ PP_Instance instance,
+ const IPC::Message& message) override;
+private:
+ // Non-owning pointer.
+ content::BrowserPpapiHost* host_;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperHostFactoryQt);
+};
+} // namespace QtWebEngineCore
+
+#endif // PEPPER_HOST_FACTORY_QT_H
diff --git a/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp
new file mode 100644
index 000000000..51416d698
--- /dev/null
+++ b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "pepper_renderer_host_factory_qt.h"
+#include "pepper_flash_renderer_host_qt.h"
+#include "content/public/renderer/renderer_ppapi_host.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/host/resource_host.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/ppapi_message_utils.h"
+#include "ppapi/shared_impl/ppapi_permissions.h"
+
+
+namespace QtWebEngineCore {
+
+PepperRendererHostFactoryQt::PepperRendererHostFactoryQt(content::RendererPpapiHost* host)
+ : host_(host)
+{
+}
+
+PepperRendererHostFactoryQt::~PepperRendererHostFactoryQt()
+{
+}
+
+scoped_ptr<ppapi::host::ResourceHost> PepperRendererHostFactoryQt::CreateResourceHost(
+ ppapi::host::PpapiHost* host,
+ PP_Resource resource,
+ PP_Instance instance,
+ const IPC::Message& message)
+{
+ DCHECK_EQ(host_->GetPpapiHost(), host);
+
+ if (!host_->IsValidInstance(instance))
+ return scoped_ptr<ppapi::host::ResourceHost>();
+
+ if (host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_FLASH)
+ && message.type() == PpapiHostMsg_Flash_Create::ID)
+ return scoped_ptr<ppapi::host::ResourceHost>(
+ new PepperFlashRendererHostQt(host_,
+ instance,
+ resource));
+
+ return scoped_ptr<ppapi::host::ResourceHost>();
+}
+
+} // QtWebEngineCore
diff --git a/src/core/renderer/pepper/pepper_renderer_host_factory_qt.h b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.h
new file mode 100644
index 000000000..8631c1e03
--- /dev/null
+++ b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PEPPER_RENDERER_HOST_FACTORY_QT_H
+#define PEPPER_RENDERER_HOST_FACTORY_QT_H
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ppapi/host/host_factory.h"
+#include "content/public/renderer/render_frame_observer.h"
+
+
+namespace content {
+class RenderFrame;
+}
+
+namespace QtWebEngineCore {
+
+class PepperRendererHostFactoryQt : public ppapi::host::HostFactory {
+public:
+ explicit PepperRendererHostFactoryQt(content::RendererPpapiHost* host);
+ ~PepperRendererHostFactoryQt();
+
+ // HostFactory.
+ scoped_ptr<ppapi::host::ResourceHost> CreateResourceHost(
+ ppapi::host::PpapiHost* host,
+ PP_Resource resource,
+ PP_Instance instance,
+ const IPC::Message& message) override;
+
+private:
+ // Not owned by this object.
+ content::RendererPpapiHost* host_;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperRendererHostFactoryQt);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // PEPPER_RENDERER_HOST_FACTORY_QT_H
diff --git a/src/core/renderer/qt_render_frame_observer.cpp b/src/core/renderer/qt_render_frame_observer.cpp
new file mode 100644
index 000000000..5f06d1e4e
--- /dev/null
+++ b/src/core/renderer/qt_render_frame_observer.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qt_render_frame_observer.h"
+
+#include "content/public/renderer/renderer_ppapi_host.h"
+#include "ppapi/host/ppapi_host.h"
+
+#include "renderer/pepper/pepper_renderer_host_factory_qt.h"
+#include "renderer/pepper/pepper_flash_renderer_host_qt.h"
+
+namespace QtWebEngineCore {
+
+QtRenderFrameObserver::QtRenderFrameObserver(content::RenderFrame* render_frame)
+ : RenderFrameObserver(render_frame)
+{
+}
+
+QtRenderFrameObserver::~QtRenderFrameObserver()
+{
+}
+
+#if defined(ENABLE_PLUGINS)
+void QtRenderFrameObserver::DidCreatePepperPlugin(content::RendererPpapiHost* host)
+{
+ host->GetPpapiHost()->AddHostFactoryFilter(
+ scoped_ptr<ppapi::host::HostFactory>(
+ new PepperRendererHostFactoryQt(host)));
+}
+#endif
+
+} // namespace QtWebEngineCore
diff --git a/src/core/custom_url_scheme_handler.h b/src/core/renderer/qt_render_frame_observer.h
index 745f0eb4c..42f2b7464 100644
--- a/src/core/custom_url_scheme_handler.h
+++ b/src/core/renderer/qt_render_frame_observer.h
@@ -34,38 +34,33 @@
**
****************************************************************************/
-#ifndef CUSTOM_URL_SCHEME_HANDLER_H_
-#define CUSTOM_URL_SCHEME_HANDLER_H_
+#ifndef QT_RENDER_FRAME_OBSERVER_H
+#define QT_RENDER_FRAME_OBSERVER_H
-#include "qtwebenginecoreglobal.h"
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "content/public/renderer/render_frame_observer.h"
-#include <QtCore/QByteArray>
-#include <QtCore/QScopedPointer>
-QT_FORWARD_DECLARE_CLASS(QIODevice)
+namespace content {
+class RenderFrame;
+}
namespace QtWebEngineCore {
-class BrowserContextAdapter;
-class CustomProtocolHandler;
-class URLRequestCustomJobDelegate;
-
-class QWEBENGINE_EXPORT CustomUrlSchemeHandler {
+class QtRenderFrameObserver : public content::RenderFrameObserver {
public:
- explicit CustomUrlSchemeHandler(const QByteArray &);
- ~CustomUrlSchemeHandler();
-
- QByteArray scheme() const;
- void setScheme(const QByteArray &);
- CustomProtocolHandler *createProtocolHandler();
+ explicit QtRenderFrameObserver(content::RenderFrame* render_frame);
+ ~QtRenderFrameObserver();
- virtual bool handleJob(URLRequestCustomJobDelegate*) = 0;
+#if defined(ENABLE_PLUGINS)
+ void DidCreatePepperPlugin(content::RendererPpapiHost* host) override;
+#endif
private:
- QByteArray m_scheme;
+ DISALLOW_COPY_AND_ASSIGN(QtRenderFrameObserver);
};
+} // namespace QtWebEngineCore
-} // namespace
-
-#endif // CUSTOM_URL_SCHEME_HANDLER_H_
+#endif // QT_RENDER_FRAME_OBSERVER_H
diff --git a/src/core/renderer/qt_render_view_observer.cpp b/src/core/renderer/qt_render_view_observer.cpp
index 83534dadd..ba91e54ae 100644
--- a/src/core/renderer/qt_render_view_observer.cpp
+++ b/src/core/renderer/qt_render_view_observer.cpp
@@ -65,6 +65,11 @@ void QtRenderViewObserver::onFetchDocumentInnerText(quint64 requestId)
render_view()->GetWebView()->mainFrame()->contentAsText(std::numeric_limits<std::size_t>::max())));
}
+void QtRenderViewObserver::onSetBackgroundColor(quint32 color)
+{
+ render_view()->GetWebView()->setBaseBackgroundColor(color);
+}
+
void QtRenderViewObserver::OnFirstVisuallyNonEmptyLayout()
{
Send(new QtRenderViewObserverHost_DidFirstVisuallyNonEmptyLayout(routing_id()));
@@ -76,6 +81,7 @@ bool QtRenderViewObserver::OnMessageReceived(const IPC::Message& message)
IPC_BEGIN_MESSAGE_MAP(QtRenderViewObserver, message)
IPC_MESSAGE_HANDLER(QtRenderViewObserver_FetchDocumentMarkup, onFetchDocumentMarkup)
IPC_MESSAGE_HANDLER(QtRenderViewObserver_FetchDocumentInnerText, onFetchDocumentInnerText)
+ IPC_MESSAGE_HANDLER(QtRenderViewObserver_SetBackgroundColor, onSetBackgroundColor)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
diff --git a/src/core/renderer/qt_render_view_observer.h b/src/core/renderer/qt_render_view_observer.h
index cb77cd0c9..3f7829a92 100644
--- a/src/core/renderer/qt_render_view_observer.h
+++ b/src/core/renderer/qt_render_view_observer.h
@@ -47,6 +47,7 @@ public:
private:
void onFetchDocumentMarkup(quint64 requestId);
void onFetchDocumentInnerText(quint64 requestId);
+ void onSetBackgroundColor(quint32 color);
void OnFirstVisuallyNonEmptyLayout() Q_DECL_OVERRIDE;
diff --git a/src/core/resource_dispatcher_host_delegate_qt.cpp b/src/core/resource_dispatcher_host_delegate_qt.cpp
index faed58954..0213daa3a 100644
--- a/src/core/resource_dispatcher_host_delegate_qt.cpp
+++ b/src/core/resource_dispatcher_host_delegate_qt.cpp
@@ -46,22 +46,20 @@
#include "content/public/browser/resource_request_info.h"
#include "net/url_request/url_request.h"
+#include "authentication_dialog_controller.h"
+#include "authentication_dialog_controller_p.h"
#include "type_conversion.h"
#include "web_contents_view_qt.h"
namespace QtWebEngineCore {
ResourceDispatcherHostLoginDelegateQt::ResourceDispatcherHostLoginDelegateQt(net::AuthChallengeInfo *authInfo, net::URLRequest *request)
- : m_request(request)
+ : m_authInfo(authInfo)
+ , m_request(request)
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
content::ResourceRequestInfo::GetRenderFrameForRequest(request, &m_renderProcessId, &m_renderFrameId);
- m_url = toQt(request->url());
- m_realm = QString::fromStdString(authInfo->realm);
- m_isProxy = authInfo->is_proxy;
- m_host = QString::fromStdString(authInfo->challenger.ToString());
-
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(&ResourceDispatcherHostLoginDelegateQt::triggerDialog, this));
@@ -69,33 +67,49 @@ ResourceDispatcherHostLoginDelegateQt::ResourceDispatcherHostLoginDelegateQt(net
ResourceDispatcherHostLoginDelegateQt::~ResourceDispatcherHostLoginDelegateQt()
{
+ Q_ASSERT(m_dialogController.isNull());
// We must have called ClearLoginDelegateForRequest if we didn't receive an OnRequestCancelled.
Q_ASSERT(!m_request);
}
void ResourceDispatcherHostLoginDelegateQt::OnRequestCancelled()
{
- m_request = 0;
+ destroy();
+}
+
+QUrl ResourceDispatcherHostLoginDelegateQt::url() const
+{
+ return toQt(m_request->url());
+}
+
+QString ResourceDispatcherHostLoginDelegateQt::realm() const
+{
+ return QString::fromStdString(m_authInfo->realm);
+}
+
+QString ResourceDispatcherHostLoginDelegateQt::host() const
+{
+ return QString::fromStdString(m_authInfo->challenger.ToString());
+}
+
+bool ResourceDispatcherHostLoginDelegateQt::isProxy() const
+{
+ return m_authInfo->is_proxy;
}
void ResourceDispatcherHostLoginDelegateQt::triggerDialog()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- content::RenderViewHost* renderViewHost = content::RenderFrameHost::FromID(m_renderProcessId, m_renderFrameId)->GetRenderViewHost();
+ content::RenderFrameHost *renderFrameHost = content::RenderFrameHost::FromID(m_renderProcessId, m_renderFrameId);
+ if (!renderFrameHost)
+ return;
+ content::RenderViewHost *renderViewHost = renderFrameHost->GetRenderViewHost();
content::WebContentsImpl *webContents = static_cast<content::WebContentsImpl *>(content::WebContents::FromRenderViewHost(renderViewHost));
WebContentsAdapterClient *client = WebContentsViewQt::from(webContents->GetView())->client();
- // The widgets API will ask for credentials synchronouly, keep it simple for now.
- // We'll have to figure out a mechanism to keep a ref to the ResourceDispatcherHostLoginDelegateQt
- // to avoid crashing in the OnRequestCancelled case if we want to allow the credentials to
- // come back asynchronously in the QtQuick API.
- QString user, password;
- client->authenticationRequired(m_url , m_realm , m_isProxy , m_host, &user, &password);
-
- bool success = !user.isEmpty() || !password.isEmpty();
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
- base::Bind(&ResourceDispatcherHostLoginDelegateQt::sendAuthToRequester, this, success, user, password));
+ AuthenticationDialogControllerPrivate *dialogControllerData = new AuthenticationDialogControllerPrivate(this);
+ m_dialogController.reset(new AuthenticationDialogController(dialogControllerData));
+ client->authenticationRequired(m_dialogController);
}
void ResourceDispatcherHostLoginDelegateQt::sendAuthToRequester(bool success, const QString &user, const QString &password)
@@ -110,9 +124,44 @@ void ResourceDispatcherHostLoginDelegateQt::sendAuthToRequester(bool success, co
m_request->CancelAuth();
content::ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(m_request);
+ destroy();
+}
+
+void ResourceDispatcherHostLoginDelegateQt::destroy()
+{
+ m_dialogController.reset();
m_request = 0;
}
+static void LaunchURL(const GURL& url, int render_process_id, int render_view_id,
+ ui::PageTransition page_transition, bool is_main_frame)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ content::RenderViewHost *render_view_host = content::RenderViewHost::FromID(render_process_id, render_view_id);
+ if (!render_view_host)
+ return;
+ content::WebContents* webContents = content::WebContents::FromRenderViewHost(render_view_host);
+ if (!webContents)
+ return;
+ WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
+ contentsDelegate->launchExternalURL(toQt(url), page_transition, is_main_frame);
+}
+
+bool ResourceDispatcherHostDelegateQt::HandleExternalProtocol(const GURL& url, int child_id, int route_id,
+ bool is_main_frame, ui::PageTransition page_transition, bool has_user_gesture)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ // We don't want to launch external applications unless it is based on a user action
+ if (!has_user_gesture)
+ return false;
+
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&LaunchURL, url, child_id, route_id, page_transition, is_main_frame));
+ return true;
+}
+
content::ResourceDispatcherHostLoginDelegate *ResourceDispatcherHostDelegateQt::CreateLoginDelegate(net::AuthChallengeInfo *authInfo, net::URLRequest *request)
{
// ResourceDispatcherHostLoginDelegateQt is ref-counted and will be released after we called ClearLoginDelegateForRequest.
diff --git a/src/core/resource_dispatcher_host_delegate_qt.h b/src/core/resource_dispatcher_host_delegate_qt.h
index 2cba210d3..57eaa3bc5 100644
--- a/src/core/resource_dispatcher_host_delegate_qt.h
+++ b/src/core/resource_dispatcher_host_delegate_qt.h
@@ -44,6 +44,8 @@
namespace QtWebEngineCore {
+class AuthenticationDialogController;
+
class ResourceDispatcherHostLoginDelegateQt : public content::ResourceDispatcherHostLoginDelegate {
public:
ResourceDispatcherHostLoginDelegateQt(net::AuthChallengeInfo *authInfo, net::URLRequest *request);
@@ -52,9 +54,16 @@ public:
// ResourceDispatcherHostLoginDelegate implementation
virtual void OnRequestCancelled();
+ QUrl url() const;
+ QString realm() const;
+ QString host() const;
+ bool isProxy() const;
+
+ void sendAuthToRequester(bool success, const QString &user, const QString &password);
+
private:
void triggerDialog();
- void sendAuthToRequester(bool success, const QString &user, const QString &password);
+ void destroy();
QUrl m_url;
QString m_realm;
@@ -64,13 +73,22 @@ private:
int m_renderProcessId;
int m_renderFrameId;
+ net::AuthChallengeInfo *m_authInfo;
+
// The request that wants login data.
// Must only be accessed on the IO thread.
net::URLRequest *m_request;
+
+ // This member is used to keep authentication dialog controller alive until
+ // authorization is sent or cancelled.
+ QSharedPointer<AuthenticationDialogController> m_dialogController;
};
class ResourceDispatcherHostDelegateQt : public content::ResourceDispatcherHostDelegate {
public:
+ virtual bool HandleExternalProtocol(const GURL& url, int child_id, int route_id,
+ bool is_main_frame, ui::PageTransition page_transition, bool has_user_gesture) Q_DECL_OVERRIDE;
+
virtual content::ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(net::AuthChallengeInfo *authInfo, net::URLRequest *request) Q_DECL_OVERRIDE;
};
diff --git a/src/core/resources/resources.gyp b/src/core/resources/resources.gyp
index 4d653df12..6293cdf3b 100644
--- a/src/core/resources/resources.gyp
+++ b/src/core/resources/resources.gyp
@@ -15,7 +15,7 @@
},
'dependencies': [
'<(chromium_src_dir)/content/app/strings/content_strings.gyp:content_strings',
- '<(chromium_src_dir)/webkit/blink_resources.gyp:blink_resources',
+ '<(chromium_src_dir)/blink/public/blink_resources.gyp:blink_resources',
'<(chromium_src_dir)/content/browser/devtools/devtools_resources.gyp:devtools_resources',
'../chrome_qt.gyp:chrome_resources',
],
@@ -29,7 +29,7 @@
'variables': {
'pak_inputs': [
'<(SHARED_INTERMEDIATE_DIR)/net/net_resources.pak',
- '<(SHARED_INTERMEDIATE_DIR)/webkit/devtools_resources.pak',
+ '<(SHARED_INTERMEDIATE_DIR)/blink/devtools_resources.pak',
'<(SHARED_INTERMEDIATE_DIR)/content/content_resources.pak',
'<(SHARED_INTERMEDIATE_DIR)/blink/public/resources/blink_resources.pak',
'<(SHARED_INTERMEDIATE_DIR)/ui/resources/webui_resources.pak',
diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h
index 66fcd4dd0..9e5461888 100644
--- a/src/core/type_conversion.h
+++ b/src/core/type_conversion.h
@@ -41,15 +41,17 @@
#include <QDateTime>
#include <QDir>
#include <QMatrix4x4>
+#include <QNetworkCookie>
#include <QRect>
#include <QString>
#include <QUrl>
#include "base/files/file_path.h"
#include "base/time/time.h"
#include "content/public/common/file_chooser_file_info.h"
+#include "net/cookies/canonical_cookie.h"
#include "third_party/skia/include/utils/SkMatrix44.h"
#include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
#include "url/gurl.h"
namespace QtWebEngineCore {
@@ -92,6 +94,11 @@ inline QPoint toQt(const gfx::Point &point)
return QPoint(point.x(), point.y());
}
+inline gfx::Point toGfx(const QPoint& point)
+{
+ return gfx::Point(point.x(), point.y());
+}
+
inline QRect toQt(const gfx::Rect &rect)
{
return QRect(rect.x(), rect.y(), rect.width(), rect.height());
@@ -122,6 +129,11 @@ inline QColor toQt(const SkColor &c)
return QColor(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), SkColorGetA(c));
}
+inline SkColor toSk(const QColor &c)
+{
+ return c.rgba();
+}
+
inline QMatrix4x4 toQt(const SkMatrix44 &m)
{
QMatrix4x4 qtMatrix(
@@ -142,6 +154,18 @@ inline base::Time toTime(const QDateTime &dateTime) {
return base::Time::FromInternalValue(dateTime.toMSecsSinceEpoch());
}
+inline QNetworkCookie toQt(const net::CanonicalCookie & cookie)
+{
+ QNetworkCookie qCookie = QNetworkCookie(QByteArray::fromStdString(cookie.Name()), QByteArray::fromStdString(cookie.Value()));
+ qCookie.setDomain(toQt(cookie.Domain()));
+ if (!cookie.ExpiryDate().is_null())
+ qCookie.setExpirationDate(toQt(cookie.ExpiryDate()));
+ qCookie.setHttpOnly(cookie.IsHttpOnly());
+ qCookie.setPath(toQt(cookie.Path()));
+ qCookie.setSecure(cookie.IsSecure());
+ return qCookie;
+}
+
inline base::FilePath::StringType toFilePathString(const QString &str)
{
#if defined(OS_WIN)
diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp
index 10923e4cb..26e1dbea8 100644
--- a/src/core/url_request_context_getter_qt.cpp
+++ b/src/core/url_request_context_getter_qt.cpp
@@ -41,7 +41,6 @@
#include "base/threading/worker_pool.h"
#include "base/threading/sequenced_worker_pool.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/cookie_crypto_delegate.h"
#include "content/public/browser/cookie_store_factory.h"
#include "content/public/common/content_switches.h"
#include "net/base/cache_type.h"
@@ -67,12 +66,16 @@
#include "net/url_request/ftp_protocol_handler.h"
#include "net/ftp/ftp_network_layer.h"
+#include "api/qwebengineurlschemehandler.h"
#include "browser_context_adapter.h"
#include "custom_protocol_handler.h"
-#include "custom_url_scheme_handler.h"
+#include "cookie_monster_delegate_qt.h"
#include "content_client_qt.h"
#include "network_delegate_qt.h"
+#include "proxy_config_service_qt.h"
#include "qrc_protocol_handler_qt.h"
+#include "qwebenginecookiestoreclient.h"
+#include "qwebenginecookiestoreclient_p.h"
#include "type_conversion.h"
namespace QtWebEngineCore {
@@ -84,6 +87,7 @@ using content::BrowserThread;
URLRequestContextGetterQt::URLRequestContextGetterQt(BrowserContextAdapter *browserContext, content::ProtocolHandlerMap *protocolHandlers)
: m_ignoreCertificateErrors(false)
, m_browserContext(browserContext)
+ , m_cookieDelegate(new CookieMonsterDelegateQt())
{
std::swap(m_protocolHandlers, *protocolHandlers);
@@ -100,7 +104,7 @@ net::URLRequestContext *URLRequestContextGetterQt::GetURLRequestContext()
if (!m_urlRequestContext) {
m_urlRequestContext.reset(new net::URLRequestContext());
- m_networkDelegate.reset(new NetworkDelegateQt);
+ m_networkDelegate.reset(new NetworkDelegateQt(this));
m_urlRequestContext->set_network_delegate(m_networkDelegate.get());
generateStorage();
@@ -117,10 +121,10 @@ void URLRequestContextGetterQt::updateStorageSettings()
// We must create the proxy config service on the UI loop on Linux because it
// must synchronously run on the glib message loop. This will be passed to
// the URLRequestContextStorage on the IO thread in GetURLRequestContext().
- m_proxyConfigService = net::ProxyService::CreateSystemProxyConfigService(
+ m_proxyConfigService = new ProxyConfigServiceQt(net::ProxyService::CreateSystemProxyConfigService(
content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)
- );
+ ));
if (m_storage)
content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateStorage, this));
}
@@ -150,34 +154,27 @@ void URLRequestContextGetterQt::generateStorage()
generateCookieStore();
generateUserAgent();
- m_storage->set_channel_id_service(new net::ChannelIDService(
+ m_storage->set_channel_id_service(scoped_ptr<net::ChannelIDService>(new net::ChannelIDService(
new net::DefaultChannelIDStore(NULL),
- base::WorkerPool::GetTaskRunner(true)));
+ base::WorkerPool::GetTaskRunner(true))));
m_storage->set_cert_verifier(net::CertVerifier::CreateDefault());
scoped_ptr<net::HostResolver> host_resolver(net::HostResolver::CreateDefaultResolver(NULL));
// The System Proxy Resolver has issues on Windows with unconfigured network cards,
- // which is why we want to use the v8 one. However, V8ProxyResolver doesn't work reliably with
- // --single-process (See also the warnings in net/proxy/proxy_resolver_v8.h).
- base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(switches::kSingleProcess)) {
- m_storage->set_proxy_service(
- net::ProxyService::CreateUsingSystemProxyResolver(proxyConfigService, 0, NULL));
- } else {
- if (!m_dhcpProxyScriptFetcherFactory)
- m_dhcpProxyScriptFetcherFactory.reset(new net::DhcpProxyScriptFetcherFactory);
-
- net::ProxyResolverV8::EnsureIsolateCreated();
- m_storage->set_proxy_service(net::CreateProxyServiceUsingV8ProxyResolver(
- proxyConfigService,
- new net::ProxyScriptFetcherImpl(m_urlRequestContext.get()),
- m_dhcpProxyScriptFetcherFactory->Create(m_urlRequestContext.get()),
- host_resolver.get(),
- NULL /* NetLog */,
- m_networkDelegate.get()));
- }
+ // which is why we want to use the v8 one
+ if (!m_dhcpProxyScriptFetcherFactory)
+ m_dhcpProxyScriptFetcherFactory.reset(new net::DhcpProxyScriptFetcherFactory);
+
+ m_storage->set_proxy_service(net::CreateProxyServiceUsingV8ProxyResolver(
+ proxyConfigService,
+ new net::ProxyScriptFetcherImpl(m_urlRequestContext.get()),
+ m_dhcpProxyScriptFetcherFactory->Create(m_urlRequestContext.get()),
+ host_resolver.get(),
+ NULL /* NetLog */,
+ m_networkDelegate.get()));
+
m_storage->set_ssl_config_service(new net::SSLConfigServiceDefaults);
m_storage->set_transport_security_state(new net::TransportSecurityState());
@@ -206,6 +203,8 @@ void URLRequestContextGetterQt::generateCookieStore()
// Unset it first to get a chance to destroy and flush the old cookie store before before opening a new on possibly the same file.
m_storage->set_cookie_store(0);
+ m_cookieDelegate->setCookieMonster(0);
+ m_cookieDelegate->setClient(m_browserContext->cookieStoreClient());
net::CookieStore* cookieStore = 0;
switch (m_browserContext->persistentCookiesPolicy()) {
@@ -214,7 +213,8 @@ void URLRequestContextGetterQt::generateCookieStore()
content::CreateCookieStore(content::CookieStoreConfig(
base::FilePath(),
content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES,
- NULL, NULL)
+ NULL,
+ m_cookieDelegate.get())
);
break;
case BrowserContextAdapter::AllowPersistentCookies:
@@ -222,7 +222,8 @@ void URLRequestContextGetterQt::generateCookieStore()
content::CreateCookieStore(content::CookieStoreConfig(
toFilePath(m_browserContext->cookiesPath()),
content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES,
- NULL, NULL)
+ NULL,
+ m_cookieDelegate.get())
);
break;
case BrowserContextAdapter::ForcePersistentCookies:
@@ -230,11 +231,16 @@ void URLRequestContextGetterQt::generateCookieStore()
content::CreateCookieStore(content::CookieStoreConfig(
toFilePath(m_browserContext->cookiesPath()),
content::CookieStoreConfig::RESTORED_SESSION_COOKIES,
- NULL, NULL)
+ NULL,
+ m_cookieDelegate.get())
);
break;
}
m_storage->set_cookie_store(cookieStore);
+
+ net::CookieMonster * const cookieMonster = cookieStore->GetCookieMonster();
+ cookieMonster->SetCookieableSchemes(kCookieableSchemes, arraysize(kCookieableSchemes));
+ m_cookieDelegate->setCookieMonster(cookieMonster);
}
void URLRequestContextGetterQt::updateUserAgent()
@@ -243,13 +249,32 @@ void URLRequestContextGetterQt::updateUserAgent()
content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateUserAgent, this));
}
+class HttpUserAgentSettingsQt : public net::HttpUserAgentSettings
+{
+ const BrowserContextAdapter *m_browserContext;
+public:
+ HttpUserAgentSettingsQt(const BrowserContextAdapter *ctx)
+ : m_browserContext(ctx)
+ {
+ }
+
+ std::string GetAcceptLanguage() const Q_DECL_OVERRIDE
+ {
+ return m_browserContext->httpAcceptLanguage().toStdString();
+ }
+
+ std::string GetUserAgent() const Q_DECL_OVERRIDE
+ {
+ return m_browserContext->httpUserAgent().toStdString();
+ }
+};
+
void URLRequestContextGetterQt::generateUserAgent()
{
Q_ASSERT(m_urlRequestContext);
Q_ASSERT(m_storage);
- m_storage->set_http_user_agent_settings(
- new net::StaticHttpUserAgentSettings("en-us,en", m_browserContext->httpUserAgent().toStdString()));
+ m_storage->set_http_user_agent_settings(new HttpUserAgentSettingsQt(m_browserContext));
}
void URLRequestContextGetterQt::updateHttpCache()
@@ -311,11 +336,13 @@ void URLRequestContextGetterQt::generateJobFactory()
Q_ASSERT(!m_jobFactory);
m_jobFactory.reset(new net::URLRequestJobFactoryImpl());
- // Chromium has a few protocol handlers ready for us, only pick blob: and throw away the rest.
- content::ProtocolHandlerMap::iterator it = m_protocolHandlers.find(url::kBlobScheme);
- Q_ASSERT(it != m_protocolHandlers.end());
- m_jobFactory->SetProtocolHandler(it->first, it->second.release());
- m_protocolHandlers.clear();
+ {
+ // Chromium has a few protocol handlers ready for us, only pick blob: and throw away the rest.
+ content::ProtocolHandlerMap::iterator it = m_protocolHandlers.find(url::kBlobScheme);
+ Q_ASSERT(it != m_protocolHandlers.end());
+ m_jobFactory->SetProtocolHandler(it->first, it->second.release());
+ m_protocolHandlers.clear();
+ }
m_jobFactory->SetProtocolHandler(url::kDataScheme, new net::DataProtocolHandler());
m_jobFactory->SetProtocolHandler(url::kFileScheme, new net::FileProtocolHandler(
@@ -325,9 +352,10 @@ void URLRequestContextGetterQt::generateJobFactory()
m_jobFactory->SetProtocolHandler(url::kFtpScheme,
new net::FtpProtocolHandler(new net::FtpNetworkLayer(m_urlRequestContext->host_resolver())));
- Q_FOREACH (CustomUrlSchemeHandler* handler, m_browserContext->customUrlSchemeHandlers()) {
- m_jobFactory->SetProtocolHandler(handler->scheme().toStdString(), handler->createProtocolHandler());
- }
+ QHash<QByteArray, QWebEngineUrlSchemeHandler*>::const_iterator it = m_browserContext->customUrlSchemeHandlers().constBegin();
+ const QHash<QByteArray, QWebEngineUrlSchemeHandler*>::const_iterator end = m_browserContext->customUrlSchemeHandlers().constEnd();
+ for (; it != end; ++it)
+ m_jobFactory->SetProtocolHandler(it.key().toStdString(), new CustomProtocolHandler(it.value()));
m_urlRequestContext->set_job_factory(m_jobFactory.get());
}
diff --git a/src/core/url_request_context_getter_qt.h b/src/core/url_request_context_getter_qt.h
index 38cfd7957..c7a4366ec 100644
--- a/src/core/url_request_context_getter_qt.h
+++ b/src/core/url_request_context_getter_qt.h
@@ -49,12 +49,14 @@
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/proxy/dhcp_proxy_script_fetcher_factory.h"
+#include "cookie_monster_delegate_qt.h"
+#include "network_delegate_qt.h"
+
#include "qglobal.h"
#include <qatomic.h>
namespace net {
class MappedHostResolver;
-class NetworkDelegate;
class ProxyConfigService;
}
@@ -93,10 +95,12 @@ private:
QAtomicPointer<net::ProxyConfigService> m_proxyConfigService;
scoped_ptr<net::URLRequestContext> m_urlRequestContext;
- scoped_ptr<net::NetworkDelegate> m_networkDelegate;
+ scoped_ptr<NetworkDelegateQt> m_networkDelegate;
scoped_ptr<net::URLRequestContextStorage> m_storage;
scoped_ptr<net::URLRequestJobFactoryImpl> m_jobFactory;
scoped_ptr<net::DhcpProxyScriptFetcherFactory> m_dhcpProxyScriptFetcherFactory;
+ scoped_refptr<CookieMonsterDelegateQt> m_cookieDelegate;
+ friend class NetworkDelegateQt;
};
} // namespace QtWebEngineCore
diff --git a/src/core/url_request_custom_job.cpp b/src/core/url_request_custom_job.cpp
index afdcecdfe..0a81d04a1 100644
--- a/src/core/url_request_custom_job.cpp
+++ b/src/core/url_request_custom_job.cpp
@@ -37,7 +37,8 @@
#include "url_request_custom_job.h"
#include "url_request_custom_job_delegate.h"
-#include "custom_url_scheme_handler.h"
+#include "api/qwebengineurlrequestjob.h"
+#include "api/qwebengineurlschemehandler.h"
#include "type_conversion.h"
#include "content/public/browser/browser_thread.h"
@@ -53,7 +54,7 @@ using namespace net;
namespace QtWebEngineCore {
-URLRequestCustomJob::URLRequestCustomJob(URLRequest *request, NetworkDelegate *networkDelegate, CustomUrlSchemeHandler *schemeHandler)
+URLRequestCustomJob::URLRequestCustomJob(URLRequest *request, NetworkDelegate *networkDelegate, QWebEngineUrlSchemeHandler *schemeHandler)
: URLRequestJob(request, networkDelegate)
, m_device(0)
, m_schemeHandler(schemeHandler)
@@ -236,7 +237,8 @@ void URLRequestCustomJob::startAsync()
QMutexLocker lock(&m_mutex);
m_delegate = new URLRequestCustomJobDelegate(this);
lock.unlock();
- m_schemeHandler->handleJob(m_delegate);
+ QWebEngineUrlRequestJob *requestJob = new QWebEngineUrlRequestJob(m_delegate);
+ m_schemeHandler->requestStarted(requestJob);
}
} // namespace
diff --git a/src/core/url_request_custom_job.h b/src/core/url_request_custom_job.h
index 60a1d60b9..a994c467a 100644
--- a/src/core/url_request_custom_job.h
+++ b/src/core/url_request_custom_job.h
@@ -45,16 +45,16 @@
#include <QtCore/QPointer>
QT_FORWARD_DECLARE_CLASS(QIODevice)
+QT_FORWARD_DECLARE_CLASS(QWebEngineUrlSchemeHandler)
namespace QtWebEngineCore {
-class CustomUrlSchemeHandler;
class URLRequestCustomJobDelegate;
// A request job that handles reading custom URL schemes
class URLRequestCustomJob : public net::URLRequestJob {
public:
- URLRequestCustomJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate, CustomUrlSchemeHandler *schemeHandler);
+ URLRequestCustomJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate, QWebEngineUrlSchemeHandler *schemeHandler);
virtual void Start() Q_DECL_OVERRIDE;
virtual void Kill() Q_DECL_OVERRIDE;
virtual bool ReadRawData(net::IOBuffer *buf, int bufSize, int *bytesRead) Q_DECL_OVERRIDE;
@@ -81,7 +81,7 @@ private:
QMutex m_mutex;
QPointer<QIODevice> m_device;
QPointer<URLRequestCustomJobDelegate> m_delegate;
- CustomUrlSchemeHandler *m_schemeHandler;
+ QWebEngineUrlSchemeHandler *m_schemeHandler;
std::string m_mimeType;
std::string m_charset;
int m_error;
diff --git a/src/core/url_request_custom_job_delegate.cpp b/src/core/url_request_custom_job_delegate.cpp
index 8d344c862..0650242c8 100644
--- a/src/core/url_request_custom_job_delegate.cpp
+++ b/src/core/url_request_custom_job_delegate.cpp
@@ -58,6 +58,11 @@ QUrl URLRequestCustomJobDelegate::url() const
return toQt(m_job->request()->url());
}
+QByteArray URLRequestCustomJobDelegate::method() const
+{
+ return QByteArray::fromStdString(m_job->request()->method());
+}
+
void URLRequestCustomJobDelegate::setReply(const QByteArray &contentType, QIODevice *device)
{
m_job->setReplyMimeType(contentType.toStdString());
diff --git a/src/core/url_request_custom_job_delegate.h b/src/core/url_request_custom_job_delegate.h
index 6c1600592..5b6137820 100644
--- a/src/core/url_request_custom_job_delegate.h
+++ b/src/core/url_request_custom_job_delegate.h
@@ -63,6 +63,7 @@ public:
};
QUrl url() const;
+ QByteArray method() const;
void setReply(const QByteArray &contentType, QIODevice *device);
void redirect(const QUrl& url);
diff --git a/src/core/user_script.cpp b/src/core/user_script.cpp
index fb293c56a..179febc48 100644
--- a/src/core/user_script.cpp
+++ b/src/core/user_script.cpp
@@ -168,14 +168,3 @@ UserScriptData &UserScript::data() const
}
} // namespace QtWebEngineCore
-
-QT_BEGIN_NAMESPACE
-uint qHash(const QtWebEngineCore::UserScript &script, uint seed)
-{
- if (script.isNull())
- return 0;
- return qHash(script.sourceCode(), seed) ^ qHash(script.name(), seed)
- ^ (script.injectionPoint() | (script.runsOnSubFrames() << 4))
- ^ script.worldId();
-}
-QT_END_NAMESPACE
diff --git a/src/core/user_script.h b/src/core/user_script.h
index 7aeba9131..69c32c7ba 100644
--- a/src/core/user_script.h
+++ b/src/core/user_script.h
@@ -93,8 +93,4 @@ private:
} // namespace QtWebEngineCore
-QT_BEGIN_NAMESPACE
-uint qHash(const QtWebEngineCore::UserScript &, uint seed = 0);
-QT_END_NAMESPACE
-
#endif // USER_SCRIPT_H
diff --git a/src/core/user_script_controller_host.cpp b/src/core/user_script_controller_host.cpp
index 227a639b1..a0d3f6fed 100644
--- a/src/core/user_script_controller_host.cpp
+++ b/src/core/user_script_controller_host.cpp
@@ -52,9 +52,12 @@ namespace QtWebEngineCore {
class UserScriptControllerHost::WebContentsObserverHelper : public content::WebContentsObserver {
public:
WebContentsObserverHelper(UserScriptControllerHost *, content::WebContents *);
- virtual void AboutToNavigateRenderView(content::RenderViewHost* renderViewHost) Q_DECL_OVERRIDE;
- virtual void WebContentsDestroyed() Q_DECL_OVERRIDE;
+ // WebContentsObserver overrides:
+ void RenderViewCreated(content::RenderViewHost *renderViewHost) override;
+ void RenderViewHostChanged(content::RenderViewHost *oldHost, content::RenderViewHost *newHost) override;
+ void WebContentsDestroyed() override;
+
private:
UserScriptControllerHost *m_controllerHost;
};
@@ -65,13 +68,23 @@ UserScriptControllerHost::WebContentsObserverHelper::WebContentsObserverHelper(U
{
}
-void UserScriptControllerHost::WebContentsObserverHelper::AboutToNavigateRenderView(content::RenderViewHost *renderViewHost)
+void UserScriptControllerHost::WebContentsObserverHelper::RenderViewCreated(content::RenderViewHost *renderViewHost)
{
content::WebContents *contents = web_contents();
Q_FOREACH (const UserScript &script, m_controllerHost->m_perContentsScripts.value(contents))
renderViewHost->Send(new RenderViewObserverHelper_AddScript(renderViewHost->GetRoutingID(), script.data()));
}
+void UserScriptControllerHost::WebContentsObserverHelper::RenderViewHostChanged(content::RenderViewHost *oldHost,
+ content::RenderViewHost *newHost)
+{
+ oldHost->Send(new RenderViewObserverHelper_ClearScripts(oldHost->GetRoutingID()));
+
+ content::WebContents *contents = web_contents();
+ Q_FOREACH (const UserScript &script, m_controllerHost->m_perContentsScripts.value(contents))
+ newHost->Send(new RenderViewObserverHelper_AddScript(newHost->GetRoutingID(), script.data()));
+}
+
void UserScriptControllerHost::WebContentsObserverHelper::WebContentsDestroyed()
{
m_controllerHost->webContentsDestroyed(web_contents());
@@ -103,9 +116,11 @@ void UserScriptControllerHost::addUserScript(const UserScript &script, WebConten
return;
// Global scripts should be dispatched to all our render processes.
if (!adapter) {
- m_profileWideScripts.insert(script);
- Q_FOREACH (content::RenderProcessHost *renderer, m_observedProcesses)
- renderer->Send(new UserScriptController_AddScript(script.data()));
+ if (!m_profileWideScripts.contains(script)) {
+ m_profileWideScripts.append(script);
+ Q_FOREACH (content::RenderProcessHost *renderer, m_observedProcesses)
+ renderer->Send(new UserScriptController_AddScript(script.data()));
+ }
} else {
content::WebContents *contents = adapter->webContents();
ContentsScriptsMap::iterator it = m_perContentsScripts.find(contents);
@@ -113,11 +128,13 @@ void UserScriptControllerHost::addUserScript(const UserScript &script, WebConten
// We need to keep track of RenderView/RenderViewHost changes for a given contents
// in order to make sure the scripts stay in sync
new WebContentsObserverHelper(this, contents);
- it = m_perContentsScripts.insert(contents, (QSet<UserScript>() << script));
+ it = m_perContentsScripts.insert(contents, (QList<UserScript>() << script));
} else {
- QSet<UserScript> currentScripts = it.value();
- currentScripts.insert(script);
- m_perContentsScripts.insert(contents, currentScripts);
+ QList<UserScript> currentScripts = it.value();
+ if (!currentScripts.contains(script)) {
+ currentScripts.append(script);
+ m_perContentsScripts.insert(contents, currentScripts);
+ }
}
contents->Send(new RenderViewObserverHelper_AddScript(contents->GetRoutingID(), script.data()));
}
@@ -138,7 +155,8 @@ bool UserScriptControllerHost::removeUserScript(const UserScript &script, WebCon
if (script.isNull())
return false;
if (!adapter) {
- QSet<UserScript>::iterator it = m_profileWideScripts.find(script);
+ QList<UserScript>::iterator it
+ = std::find(m_profileWideScripts.begin(), m_profileWideScripts.end(), script);
if (it == m_profileWideScripts.end())
return false;
Q_FOREACH (content::RenderProcessHost *renderer, m_observedProcesses)
@@ -148,12 +166,12 @@ bool UserScriptControllerHost::removeUserScript(const UserScript &script, WebCon
content::WebContents *contents = adapter->webContents();
if (!m_perContentsScripts.contains(contents))
return false;
- QSet<UserScript> &set(m_perContentsScripts[contents]);
- QSet<UserScript>::iterator it = set.find(script);
- if (it == set.end())
+ QList<UserScript> &list(m_perContentsScripts[contents]);
+ QList<UserScript>::iterator it = std::find(list.begin(), list.end(), script);
+ if (it == list.end())
return false;
contents->Send(new RenderViewObserverHelper_RemoveScript(contents->GetRoutingID(), (*it).data()));
- set.erase(it);
+ list.erase(it);
}
return true;
}
@@ -171,7 +189,7 @@ void UserScriptControllerHost::clearAllScripts(WebContentsAdapter *adapter)
}
}
-const QSet<UserScript> UserScriptControllerHost::registeredScripts(WebContentsAdapter *adapter) const
+const QList<UserScript> UserScriptControllerHost::registeredScripts(WebContentsAdapter *adapter) const
{
if (!adapter)
return m_profileWideScripts;
diff --git a/src/core/user_script_controller_host.h b/src/core/user_script_controller_host.h
index 49c96b333..3884fb3b9 100644
--- a/src/core/user_script_controller_host.h
+++ b/src/core/user_script_controller_host.h
@@ -64,7 +64,7 @@ public:
bool removeUserScript(const UserScript &script, WebContentsAdapter *adapter);
void clearAllScripts(WebContentsAdapter *adapter);
void reserve(WebContentsAdapter *adapter, int count);
- const QSet<UserScript> registeredScripts(WebContentsAdapter *adapter) const;
+ const QList<UserScript> registeredScripts(WebContentsAdapter *adapter) const;
void renderProcessStartedWithHost(content::RenderProcessHost *renderer);
@@ -75,8 +75,8 @@ private:
void webContentsDestroyed(content::WebContents *);
- QSet<UserScript> m_profileWideScripts;
- typedef QHash<content::WebContents *, QSet<UserScript>> ContentsScriptsMap;
+ QList<UserScript> m_profileWideScripts;
+ typedef QHash<content::WebContents *, QList<UserScript>> ContentsScriptsMap;
ContentsScriptsMap m_perContentsScripts;
QSet<content::RenderProcessHost *> m_observedProcesses;
QScopedPointer<RenderProcessObserverHelper> m_renderProcessObserver;
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index e35319fdd..31ebb1244 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -46,6 +46,7 @@
#include "browser_context_qt.h"
#include "media_capture_devices_dispatcher.h"
#include "qt_render_view_observer_host.h"
+#include "qwebenginecallback_p.h"
#include "type_conversion.h"
#include "web_channel_ipc_transport_host.h"
#include "web_contents_adapter_client.h"
@@ -57,6 +58,8 @@
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/child_process_security_policy.h"
+#include "content/public/browser/devtools_agent_host.h"
+#include <content/public/browser/download_manager.h>
#include "content/public/browser/host_zoom_map.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_view_host.h"
@@ -66,7 +69,6 @@
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/web_preferences.h"
-#include "ui/shell_dialogs/selected_file_info.h"
#include "third_party/WebKit/public/web/WebFindOptions.h"
#include <QDir>
@@ -165,19 +167,6 @@ static void callbackOnEvaluateJS(WebContentsAdapterClient *adapterClient, quint6
adapterClient->didRunJavaScript(requestId, fromJSValue(result));
}
-static QStringList listRecursively(const QDir& dir) {
- QStringList ret;
- QFileInfoList infoList(dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot |QDir::Hidden));
- Q_FOREACH (const QFileInfo &fileInfo, infoList) {
- if (fileInfo.isDir()) {
- ret.append(fileInfo.absolutePath() + QStringLiteral("/.")); // Match chromium's behavior. See chrome/browser/file_select_helper.cc
- ret.append(listRecursively(QDir(fileInfo.absoluteFilePath())));
- } else
- ret.append(fileInfo.absoluteFilePath());
- }
- return ret;
-}
-
static content::WebContents *createBlankWebContents(WebContentsAdapterClient *adapterClient, content::BrowserContext *browserContext)
{
content::WebContents::CreateParams create_params(browserContext, NULL);
@@ -217,14 +206,11 @@ static void serializeNavigationHistory(const content::NavigationController &cont
output << entry->GetIsOverridingUserAgent();
output << static_cast<qint64>(entry->GetTimestamp().ToInternalValue());
output << entry->GetHttpStatusCode();
- // If you want to navigate a named frame in Chrome, you will first need to
- // add support for persisting it. It is currently only used for layout tests.
- CHECK(entry->GetFrameToNavigate().empty());
}
}
}
-static void deserializeNavigationHistory(QDataStream &input, int *currentIndex, std::vector<content::NavigationEntry*> *entries, content::BrowserContext *browserContext)
+static void deserializeNavigationHistory(QDataStream &input, int *currentIndex, ScopedVector<content::NavigationEntry> *entries, content::BrowserContext *browserContext)
{
int version;
input >> version;
@@ -265,13 +251,13 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex,
// If we couldn't unpack the entry successfully, abort everything.
if (input.status() != QDataStream::Ok) {
*currentIndex = -1;
- Q_FOREACH (content::NavigationEntry *entry, *entries)
+ for (content::NavigationEntry *entry : *entries)
delete entry;
entries->clear();
return;
}
- content::NavigationEntry *entry = content::NavigationController::CreateNavigationEntry(
+ scoped_ptr<content::NavigationEntry> entry = content::NavigationController::CreateNavigationEntry(
toGurl(virtualUrl),
content::Referrer(toGurl(referrerUrl), static_cast<blink::WebReferrerPolicy>(referrerPolicy)),
// Use a transition type of reload so that we don't incorrectly
@@ -290,7 +276,7 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex,
entry->SetIsOverridingUserAgent(isOverridingUserAgent);
entry->SetTimestamp(base::Time::FromInternalValue(timestamp));
entry->SetHttpStatusCode(httpStatusCode);
- entries->push_back(entry);
+ entries->push_back(entry.release());
}
}
@@ -323,7 +309,7 @@ WebContentsAdapterPrivate::WebContentsAdapterPrivate()
: engineContext(WebEngineContext::current())
, webChannel(0)
, adapterClient(0)
- , nextRequestId(1)
+ , nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd)
, lastFindRequestId(0)
{
}
@@ -337,7 +323,7 @@ WebContentsAdapterPrivate::~WebContentsAdapterPrivate()
QExplicitlySharedDataPointer<WebContentsAdapter> WebContentsAdapter::createFromSerializedNavigationHistory(QDataStream &input, WebContentsAdapterClient *adapterClient)
{
int currentIndex;
- std::vector<content::NavigationEntry*> entries;
+ ScopedVector<content::NavigationEntry> entries;
deserializeNavigationHistory(input, &currentIndex, &entries, adapterClient->browserContextAdapter()->browserContext());
if (currentIndex == -1)
@@ -394,6 +380,7 @@ void WebContentsAdapter::initialize(WebContentsAdapterClient *adapterClient)
const int qtCursorFlashTime = QGuiApplication::styleHints()->cursorFlashTime();
rendererPrefs->caret_blink_interval = 0.5 * static_cast<double>(qtCursorFlashTime) / 1000;
rendererPrefs->user_agent_override = d->browserContextAdapter->httpUserAgent().toStdString();
+ rendererPrefs->accept_languages = d->browserContextAdapter->httpAcceptLanguageWithoutQualities().toStdString();
d->webContents->GetRenderViewHost()->SyncRendererPrefs();
// Create and attach observers to the WebContents.
@@ -411,7 +398,7 @@ void WebContentsAdapter::initialize(WebContentsAdapterClient *adapterClient)
content::RenderViewHost *rvh = d->webContents->GetRenderViewHost();
Q_ASSERT(rvh);
if (!rvh->IsRenderViewLive())
- static_cast<content::WebContentsImpl*>(d->webContents.get())->CreateRenderViewForRenderManager(rvh, MSG_ROUTING_NONE, MSG_ROUTING_NONE, true);
+ static_cast<content::WebContentsImpl*>(d->webContents.get())->CreateRenderViewForRenderManager(rvh, MSG_ROUTING_NONE, MSG_ROUTING_NONE, content::FrameReplicationState(), true);
}
void WebContentsAdapter::reattachRWHV()
@@ -497,7 +484,9 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT
params.base_url_for_data_url = toGurl(baseUrl);
params.virtual_url_for_data_url = baseUrl.isEmpty() ? GURL(url::kAboutBlankURL) : toGurl(baseUrl);
params.can_load_local_resources = true;
+ params.transition_type = ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_API);
d->webContents->GetController().LoadURLWithParams(params);
+ d->webContents->Focus();
}
QUrl WebContentsAdapter::activeUrl() const
@@ -587,6 +576,12 @@ void WebContentsAdapter::selectAll()
d->webContents->SelectAll();
}
+void WebContentsAdapter::requestClose()
+{
+ Q_D(WebContentsAdapter);
+ d->webContents->DispatchBeforeUnload(false);
+}
+
void WebContentsAdapter::navigateToIndex(int offset)
{
Q_D(WebContentsAdapter);
@@ -774,6 +769,66 @@ void WebContentsAdapter::updateWebPreferences(const content::WebPreferences & we
d->webContents->GetRenderViewHost()->UpdateWebkitPreferences(webPreferences);
}
+void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileName)
+{
+ content::BrowserContext *bctx = webContents()->GetBrowserContext();
+ content::DownloadManager *dlm = content::BrowserContext::GetDownloadManager(bctx);
+ if (!dlm)
+ return;
+
+ scoped_ptr<content::DownloadUrlParameters> params(
+ content::DownloadUrlParameters::FromWebContents(webContents(), toGurl(url)));
+ params->set_suggested_name(toString16(suggestedFileName));
+ dlm->DownloadUrl(params.Pass());
+}
+
+void WebContentsAdapter::copyImageAt(const QPoint &location)
+{
+ Q_D(WebContentsAdapter);
+ d->webContents->GetRenderViewHost()->CopyImageAt(location.x(), location.y());
+}
+
+ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerNoAction, blink::WebMediaPlayerAction::Unknown)
+ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerPlay, blink::WebMediaPlayerAction::Play)
+ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerMute, blink::WebMediaPlayerAction::Mute)
+ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerLoop, blink::WebMediaPlayerAction::Loop)
+ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerControls, blink::WebMediaPlayerAction::Controls)
+
+void WebContentsAdapter::executeMediaPlayerActionAt(const QPoint &location, MediaPlayerAction action, bool enable)
+{
+ Q_D(WebContentsAdapter);
+ blink::WebMediaPlayerAction blinkAction((blink::WebMediaPlayerAction::Type)action, enable);
+ d->webContents->GetRenderViewHost()->ExecuteMediaPlayerActionAtLocation(toGfx(location), blinkAction);
+}
+
+void WebContentsAdapter::inspectElementAt(const QPoint &location)
+{
+ Q_D(WebContentsAdapter);
+ if (content::DevToolsAgentHost::HasFor(d->webContents.get())) {
+ content::DevToolsAgentHost::GetOrCreateFor(d->webContents.get())->InspectElement(location.x(), location.y());
+ }
+}
+
+bool WebContentsAdapter::hasInspector() const
+{
+ const Q_D(WebContentsAdapter);
+ if (content::DevToolsAgentHost::HasFor(d->webContents.get()))
+ return content::DevToolsAgentHost::GetOrCreateFor(d->webContents.get())->IsAttached();
+ return false;
+}
+
+void WebContentsAdapter::exitFullScreen()
+{
+ Q_D(WebContentsAdapter);
+ d->webContents->ExitFullscreen();
+}
+
+void WebContentsAdapter::changedFullScreen()
+{
+ Q_D(WebContentsAdapter);
+ d->webContents->NotifyFullscreenChanged();
+}
+
void WebContentsAdapter::wasShown()
{
Q_D(WebContentsAdapter);
@@ -795,7 +850,7 @@ void WebContentsAdapter::grantMediaAccessPermission(const QUrl &securityOrigin,
void WebContentsAdapter::runGeolocationRequestCallback(const QUrl &securityOrigin, bool allowed)
{
Q_D(WebContentsAdapter);
- d->webContentsDelegate->geolocationPermissionReply(securityOrigin, allowed);
+ d->browserContextAdapter->permissionRequestReply(securityOrigin, BrowserContextAdapter::GeolocationPermission, allowed);
}
void WebContentsAdapter::grantMouseLockPermission(bool granted)
@@ -822,21 +877,11 @@ void WebContentsAdapter::dpiScaleChanged()
impl->NotifyScreenInfoChanged();
}
-ASSERT_ENUMS_MATCH(WebContentsAdapterClient::Open, content::FileChooserParams::Open)
-ASSERT_ENUMS_MATCH(WebContentsAdapterClient::OpenMultiple, content::FileChooserParams::OpenMultiple)
-ASSERT_ENUMS_MATCH(WebContentsAdapterClient::UploadFolder, content::FileChooserParams::UploadFolder)
-ASSERT_ENUMS_MATCH(WebContentsAdapterClient::Save, content::FileChooserParams::Save)
-
-void WebContentsAdapter::filesSelectedInChooser(const QStringList &fileList, WebContentsAdapterClient::FileChooserMode mode)
+void WebContentsAdapter::backgroundColorChanged()
{
Q_D(WebContentsAdapter);
- content::RenderViewHost *rvh = d->webContents->GetRenderViewHost();
- Q_ASSERT(rvh);
- QStringList files(fileList);
- if (mode == WebContentsAdapterClient::UploadFolder && !fileList.isEmpty()
- && QFileInfo(fileList.first()).isDir()) // Enumerate the directory
- files = listRecursively(QDir(fileList.first()));
- rvh->FilesSelectedInChooser(toVector<content::FileChooserFileInfo>(files), static_cast<content::FileChooserParams::Mode>(mode));
+ if (content::RenderWidgetHostView *rwhv = d->webContents->GetRenderWidgetHostView())
+ rwhv->SetBackgroundColor(toSk(d->adapterClient->backgroundColor()));
}
content::WebContents *WebContentsAdapter::webContents() const
@@ -869,4 +914,36 @@ void WebContentsAdapter::setWebChannel(QWebChannel *channel)
channel->connectTo(d->webChannelTransport.get());
}
+WebContentsAdapterClient::RenderProcessTerminationStatus
+WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) {
+ auto status = WebContentsAdapterClient::RenderProcessTerminationStatus(-1);
+ switch (terminationStatus) {
+ case base::TERMINATION_STATUS_NORMAL_TERMINATION:
+ status = WebContentsAdapterClient::NormalTerminationStatus;
+ break;
+ case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
+ status = WebContentsAdapterClient::AbnormalTerminationStatus;
+ break;
+ case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
+#if defined(OS_CHROMEOS)
+ case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM:
+#endif
+ status = WebContentsAdapterClient::KilledTerminationStatus;
+ break;
+ case base::TERMINATION_STATUS_PROCESS_CRASHED:
+#if defined(OS_ANDROID)
+ case base::TERMINATION_STATUS_OOM_PROTECTED:
+#endif
+ status = WebContentsAdapterClient::CrashedTerminationStatus;
+ break;
+ case base::TERMINATION_STATUS_STILL_RUNNING:
+ case base::TERMINATION_STATUS_MAX_ENUM:
+ // should be unreachable since Chromium asserts status != TERMINATION_STATUS_STILL_RUNNING
+ // before calling this method
+ break;
+ }
+
+ return status;
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 5ea55c1b8..ce033bdb4 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -104,7 +104,6 @@ public:
void serializeNavigationHistory(QDataStream &output);
void setZoomFactor(qreal);
qreal currentZoomFactor() const;
- void filesSelectedInChooser(const QStringList &fileList, WebContentsAdapterClient::FileChooserMode);
void runJavaScript(const QString &javaScript);
quint64 runJavaScriptCallbackResult(const QString &javaScript);
quint64 fetchDocumentMarkup();
@@ -112,6 +111,25 @@ public:
quint64 findText(const QString &subString, bool caseSensitively, bool findBackward);
void stopFinding();
void updateWebPreferences(const content::WebPreferences &webPreferences);
+ void download(const QUrl &url, const QString &suggestedFileName);
+
+ // Must match blink::WebMediaPlayerAction::Type.
+ enum MediaPlayerAction {
+ MediaPlayerNoAction,
+ MediaPlayerPlay,
+ MediaPlayerMute,
+ MediaPlayerLoop,
+ MediaPlayerControls,
+ MediaPlayerTypeLast = MediaPlayerControls
+ };
+ void copyImageAt(const QPoint &location);
+ void executeMediaPlayerActionAt(const QPoint &location, MediaPlayerAction action, bool enable);
+
+ void inspectElementAt(const QPoint &location);
+ bool hasInspector() const;
+ void exitFullScreen();
+ void requestClose();
+ void changedFullScreen();
void wasShown();
void wasHidden();
@@ -120,6 +138,7 @@ public:
void grantMouseLockPermission(bool granted);
void dpiScaleChanged();
+ void backgroundColorChanged();
QAccessibleInterface *browserAccessible();
BrowserContextQt* browserContext();
BrowserContextAdapter* browserContextAdapter();
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 3ed3ab9ab..f2a05c575 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -52,7 +52,9 @@ QT_FORWARD_DECLARE_CLASS(CertificateErrorController)
namespace QtWebEngineCore {
+class AuthenticationDialogController;
class BrowserContextAdapter;
+class FilePickerController;
class JavaScriptDialogController;
class RenderWidgetHostViewQt;
class RenderWidgetHostViewQtDelegate;
@@ -65,10 +67,55 @@ class WebEngineSettings;
class WebEngineContextMenuData {
public:
+ WebEngineContextMenuData()
+ : mediaType(MediaTypeNone)
+ , hasImageContent(false)
+ , mediaFlags(0)
+ {
+ }
+
+ // Must match blink::WebContextMenuData::MediaType:
+ enum MediaType {
+ // No special node is in context.
+ MediaTypeNone,
+ // An image node is selected.
+ MediaTypeImage,
+ // A video node is selected.
+ MediaTypeVideo,
+ // An audio node is selected.
+ MediaTypeAudio,
+ // A canvas node is selected.
+ MediaTypeCanvas,
+ // A file node is selected.
+ MediaTypeFile,
+ // A plugin node is selected.
+ MediaTypePlugin,
+ MediaTypeLast = MediaTypePlugin
+ };
+ // Must match blink::WebContextMenuData::MediaFlags:
+ enum MediaFlags {
+ MediaNone = 0x0,
+ MediaInError = 0x1,
+ MediaPaused = 0x2,
+ MediaMuted = 0x4,
+ MediaLoop = 0x8,
+ MediaCanSave = 0x10,
+ MediaHasAudio = 0x20,
+ MediaCanToggleControls = 0x40,
+ MediaControls = 0x80,
+ MediaCanPrint = 0x100,
+ MediaCanRotate = 0x200,
+ };
+
QPoint pos;
QUrl linkUrl;
QString linkText;
QString selectedText;
+ QUrl mediaUrl;
+ MediaType mediaType;
+ bool hasImageContent;
+ uint mediaFlags;
+ QString suggestedFileName;
// Some likely candidates for future additions as we add support for the related actions:
// bool isImageBlocked;
// bool isEditable;
@@ -100,18 +147,11 @@ public:
AlertDialog,
ConfirmDialog,
PromptDialog,
+ UnloadDialog,
// Leave room for potential new specs
InternalAuthorizationDialog = 0x10,
};
- // Must match the ones in file_chooser_params.h
- enum FileChooserMode {
- Open,
- OpenMultiple,
- UploadFolder,
- Save
- };
-
enum NavigationRequestAction {
AcceptRequest,
// Make room in the valid range of the enum for extra actions exposed in Experimental.
@@ -119,7 +159,7 @@ public:
};
enum NavigationType {
- LinkClickedNavigation,
+ LinkNavigation,
TypedNavigation,
FormSubmittedNavigation,
BackForwardNavigation,
@@ -133,6 +173,13 @@ public:
Error
};
+ enum RenderProcessTerminationStatus {
+ NormalTerminationStatus = 0,
+ AbnormalTerminationStatus,
+ CrashedTerminationStatus,
+ KilledTerminationStatus
+ };
+
enum MediaRequestFlag {
MediaNone = 0,
MediaAudioCapture = 0x01,
@@ -152,6 +199,7 @@ public:
virtual void selectionChanged() = 0;
virtual QRectF viewportRect() const = 0;
virtual qreal dpiScale() const = 0;
+ virtual QColor backgroundColor() const = 0;
virtual void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) = 0;
virtual void loadCommitted() = 0;
virtual void loadVisuallyCommitted() = 0;
@@ -160,12 +208,13 @@ public:
virtual void unhandledKeyEvent(QKeyEvent *event) = 0;
virtual void adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect & initialGeometry) = 0;
virtual void close() = 0;
+ virtual void windowCloseRejected() = 0;
virtual bool contextMenuRequested(const WebEngineContextMenuData&) = 0;
virtual void navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) = 0;
- virtual void requestFullScreen(bool) = 0;
- virtual bool isFullScreen() const = 0;
+ virtual void requestFullScreenMode(const QUrl &origin, bool fullscreen) = 0;
+ virtual bool isFullScreenMode() const = 0;
virtual void javascriptDialog(QSharedPointer<JavaScriptDialogController>) = 0;
- virtual void runFileChooser(FileChooserMode, const QString &defaultFileName, const QStringList &acceptedMimeTypes) = 0;
+ virtual void runFileChooser(FilePickerController *controller) = 0;
virtual void didRunJavaScript(quint64 requestId, const QVariant& result) = 0;
virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) = 0;
virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) = 0;
@@ -177,7 +226,7 @@ public:
virtual QObject *accessibilityParentObject() = 0;
#endif // QT_NO_ACCESSIBILITY
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) = 0;
- virtual void authenticationRequired(const QUrl &requestUrl, const QString &realm, bool isProxy, const QString &challengingHost, QString *outUser, QString *outPassword) = 0;
+ virtual void authenticationRequired(QSharedPointer<AuthenticationDialogController>) = 0;
virtual void runGeolocationPermissionRequest(const QUrl &securityOrigin) = 0;
virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) = 0;
virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) = 0;
@@ -185,6 +234,8 @@ public:
virtual void showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText) = 0;
virtual void hideValidationMessage() = 0;
virtual void moveValidationMessage(const QRect &anchor) = 0;
+ RenderProcessTerminationStatus renderProcessExitStatus(int);
+ virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) = 0;
virtual void allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) = 0;
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index c16c76f75..1f789161a 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -41,7 +41,9 @@
#include "web_contents_delegate_qt.h"
#include "browser_context_adapter.h"
+#include "file_picker_controller.h"
#include "media_capture_devices_dispatcher.h"
+#include "network_delegate_qt.h"
#include "type_conversion.h"
#include "web_contents_adapter_client.h"
#include "web_contents_adapter_p.h"
@@ -63,6 +65,8 @@
#include "content/public/common/web_preferences.h"
#include "ui/events/latency_info.h"
+#include <QDesktopServices>
+
namespace QtWebEngineCore {
// Maps the LogSeverity defines in base/logging.h to the web engines message levels.
@@ -107,7 +111,7 @@ content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents
return target;
}
-void WebContentsDelegateQt::NavigationStateChanged(const content::WebContents* source, content::InvalidateTypes changed_flags)
+void WebContentsDelegateQt::NavigationStateChanged(content::WebContents* source, content::InvalidateTypes changed_flags)
{
if (changed_flags & content::INVALIDATE_TYPE_URL)
m_viewClient->urlChanged(toQt(source->GetVisibleURL()));
@@ -126,7 +130,7 @@ void WebContentsDelegateQt::AddNewContents(content::WebContents* source, content
void WebContentsDelegateQt::CloseContents(content::WebContents *source)
{
m_viewClient->close();
- GetJavaScriptDialogManager()->CancelActiveAndPendingDialogs(source);
+ GetJavaScriptDialogManager(source)->CancelActiveAndPendingDialogs(source);
}
void WebContentsDelegateQt::LoadProgressChanged(content::WebContents* source, double progress)
@@ -176,13 +180,14 @@ void WebContentsDelegateQt::DidCommitProvisionalLoadForFrame(content::RenderFram
m_viewClient->loadCommitted();
}
-void WebContentsDelegateQt::DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description)
+void WebContentsDelegateQt::DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description, bool was_ignored_by_handler)
{
- DidFailLoad(render_frame_host, validated_url, error_code, error_description);
+ DidFailLoad(render_frame_host, validated_url, error_code, error_description, was_ignored_by_handler);
}
-void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description)
+void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description, bool was_ignored_by_handler)
{
+ Q_UNUSED(was_ignored_by_handler);
if (m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID()) || render_frame_host->GetParent())
return;
@@ -233,36 +238,44 @@ void WebContentsDelegateQt::DidUpdateFaviconURL(const std::vector<content::Favic
}
}
-content::JavaScriptDialogManager *WebContentsDelegateQt::GetJavaScriptDialogManager()
+content::JavaScriptDialogManager *WebContentsDelegateQt::GetJavaScriptDialogManager(content::WebContents *)
{
return JavaScriptDialogManagerQt::GetInstance();
}
-void WebContentsDelegateQt::ToggleFullscreenModeForTab(content::WebContents* web_contents, bool enter_fullscreen)
+void WebContentsDelegateQt::EnterFullscreenModeForTab(content::WebContents *web_contents, const GURL& origin)
{
- if (m_viewClient->isFullScreen() != enter_fullscreen) {
- m_viewClient->requestFullScreen(enter_fullscreen);
- web_contents->GetRenderViewHost()->WasResized();
- }
+ Q_UNUSED(web_contents);
+ if (!m_viewClient->isFullScreenMode())
+ m_viewClient->requestFullScreenMode(toQt(origin), true);
+}
+
+void WebContentsDelegateQt::ExitFullscreenModeForTab(content::WebContents *web_contents)
+{
+ if (m_viewClient->isFullScreenMode())
+ m_viewClient->requestFullScreenMode(toQt(web_contents->GetLastCommittedURL().GetOrigin()), false);
}
bool WebContentsDelegateQt::IsFullscreenForTabOrPending(const content::WebContents* web_contents) const
{
- return m_viewClient->isFullScreen();
+ Q_UNUSED(web_contents);
+ return m_viewClient->isFullScreenMode();
}
-ASSERT_ENUMS_MATCH(WebContentsAdapterClient::Open, content::FileChooserParams::Open)
-ASSERT_ENUMS_MATCH(WebContentsAdapterClient::Save, content::FileChooserParams::Save)
+ASSERT_ENUMS_MATCH(FilePickerController::Open, content::FileChooserParams::Open)
+ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, content::FileChooserParams::OpenMultiple)
+ASSERT_ENUMS_MATCH(FilePickerController::UploadFolder, content::FileChooserParams::UploadFolder)
+ASSERT_ENUMS_MATCH(FilePickerController::Save, content::FileChooserParams::Save)
void WebContentsDelegateQt::RunFileChooser(content::WebContents *web_contents, const content::FileChooserParams &params)
{
- Q_UNUSED(web_contents)
QStringList acceptedMimeTypes;
acceptedMimeTypes.reserve(params.accept_types.size());
for (std::vector<base::string16>::const_iterator it = params.accept_types.begin(); it < params.accept_types.end(); ++it)
acceptedMimeTypes.append(toQt(*it));
- m_viewClient->runFileChooser(static_cast<WebContentsAdapterClient::FileChooserMode>(params.mode), toQt(params.default_file_name.value()), acceptedMimeTypes);
+ FilePickerController *controller = new FilePickerController(static_cast<FilePickerController::FileChooserMode>(params.mode), web_contents, toQt(params.default_file_name.value()), acceptedMimeTypes);
+ m_viewClient->runFileChooser(controller);
}
bool WebContentsDelegateQt::AddMessageToConsole(content::WebContents *source, int32 level, const base::string16 &message, int32 line_no, const base::string16 &source_id)
@@ -339,28 +352,21 @@ void WebContentsDelegateQt::allowCertificateError(const QSharedPointer<Certifica
m_viewClient->allowCertificateError(errorController);
}
-void WebContentsDelegateQt::requestGeolocationPermission(const GURL &requestingFrameOrigin, const base::Callback<void (bool)> &resultCallback)
+void WebContentsDelegateQt::requestGeolocationPermission(const QUrl &requestingOrigin)
{
- QUrl url = toQt(requestingFrameOrigin);
- bool newRequest = !m_geolocationPermissionRequests.contains(url);
- m_geolocationPermissionRequests[url] = resultCallback;
- if (newRequest)
- m_viewClient->runGeolocationPermissionRequest(url);
+ m_viewClient->runGeolocationPermissionRequest(requestingOrigin);
}
-void WebContentsDelegateQt::cancelGeolocationPermissionRequest(const GURL &requestingFrameOrigin)
-{
- m_geolocationPermissionRequests.remove(toQt(requestingFrameOrigin));
- // FIXME: Tell the API layer to cancel the permission request?
-}
+extern int pageTransitionToNavigationType(ui::PageTransition transition);
-void WebContentsDelegateQt::geolocationPermissionReply(const QUrl &origin, bool permission)
+void WebContentsDelegateQt::launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame)
{
- auto it = m_geolocationPermissionRequests.find(origin);
- if (it != m_geolocationPermissionRequests.end()) {
- (*it).Run(permission);
- m_geolocationPermissionRequests.erase(it);
- }
+ int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
+ m_viewClient->navigationRequested(pageTransitionToNavigationType(page_transition), url, navigationRequestAction, is_main_frame);
+#ifndef QT_NO_DESKTOPSERVICES
+ if (navigationRequestAction == WebContentsAdapterClient::AcceptRequest)
+ QDesktopServices::openUrl(url);
+#endif
}
void WebContentsDelegateQt::ShowValidationMessage(content::WebContents *web_contents, const gfx::Rect &anchor_in_root_view, const base::string16 &main_text, const base::string16 &sub_text)
@@ -381,4 +387,13 @@ void WebContentsDelegateQt::MoveValidationMessage(content::WebContents *web_cont
m_viewClient->moveValidationMessage(toQt(anchor_in_root_view));
}
+void WebContentsDelegateQt::BeforeUnloadFired(content::WebContents *tab, bool proceed, bool *proceed_to_fire_unload)
+{
+ Q_UNUSED(tab);
+ Q_ASSERT(proceed_to_fire_unload);
+ *proceed_to_fire_unload = proceed;
+ if (!proceed)
+ m_viewClient->windowCloseRejected();
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 41acf7c84..abdf75fe5 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -39,6 +39,7 @@
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
+#include "content/public/common/permission_status.mojom.h"
#include "base/callback.h"
@@ -72,13 +73,14 @@ public:
// WebContentsDelegate overrides
virtual content::WebContents *OpenURLFromTab(content::WebContents *source, const content::OpenURLParams &params) Q_DECL_OVERRIDE;
- virtual void NavigationStateChanged(const content::WebContents* source, content::InvalidateTypes changed_flags) Q_DECL_OVERRIDE;
+ virtual void NavigationStateChanged(content::WebContents* source, content::InvalidateTypes changed_flags) Q_DECL_OVERRIDE;
virtual void AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture, bool* was_blocked) Q_DECL_OVERRIDE;
virtual void CloseContents(content::WebContents *source) Q_DECL_OVERRIDE;
virtual void LoadProgressChanged(content::WebContents* source, double progress) Q_DECL_OVERRIDE;
virtual void HandleKeyboardEvent(content::WebContents *source, const content::NativeWebKeyboardEvent &event) Q_DECL_OVERRIDE;
- virtual content::JavaScriptDialogManager *GetJavaScriptDialogManager() Q_DECL_OVERRIDE;
- virtual void ToggleFullscreenModeForTab(content::WebContents* web_contents, bool enter_fullscreen) Q_DECL_OVERRIDE;
+ virtual content::JavaScriptDialogManager *GetJavaScriptDialogManager(content::WebContents *source) Q_DECL_OVERRIDE;
+ virtual void EnterFullscreenModeForTab(content::WebContents* web_contents, const GURL& origin) Q_DECL_OVERRIDE;
+ virtual void ExitFullscreenModeForTab(content::WebContents*) Q_DECL_OVERRIDE;
virtual bool IsFullscreenForTabOrPending(const content::WebContents* web_contents) const Q_DECL_OVERRIDE;
virtual void RunFileChooser(content::WebContents *, const content::FileChooserParams &params) Q_DECL_OVERRIDE;
virtual bool AddMessageToConsole(content::WebContents* source, int32 level, const base::string16& message, int32 line_no, const base::string16& source_id) Q_DECL_OVERRIDE;
@@ -89,28 +91,28 @@ public:
virtual void ShowValidationMessage(content::WebContents *web_contents, const gfx::Rect &anchor_in_root_view, const base::string16 &main_text, const base::string16 &sub_text) Q_DECL_OVERRIDE;
virtual void HideValidationMessage(content::WebContents *web_contents) Q_DECL_OVERRIDE;
virtual void MoveValidationMessage(content::WebContents *web_contents, const gfx::Rect &anchor_in_root_view) Q_DECL_OVERRIDE;
+ void BeforeUnloadFired(content::WebContents* tab, bool proceed, bool* proceed_to_fire_unload) Q_DECL_OVERRIDE;
// WebContentsObserver overrides
virtual void RenderFrameDeleted(content::RenderFrameHost *render_frame_host) Q_DECL_OVERRIDE;
virtual void DidStartProvisionalLoadForFrame(content::RenderFrameHost *render_frame_host, const GURL &validated_url, bool is_error_page, bool is_iframe_srcdoc) Q_DECL_OVERRIDE;
virtual void DidCommitProvisionalLoadForFrame(content::RenderFrameHost *render_frame_host, const GURL &url, ui::PageTransition transition_type) Q_DECL_OVERRIDE;
- virtual void DidFailProvisionalLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url, int error_code, const base::string16 &error_description) Q_DECL_OVERRIDE;
- virtual void DidFailLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url, int error_code, const base::string16 &error_description) Q_DECL_OVERRIDE;
+ virtual void DidFailProvisionalLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url,
+ int error_code, const base::string16 &error_description, bool was_ignored_by_handler) Q_DECL_OVERRIDE;
+ virtual void DidFailLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url,
+ int error_code, const base::string16 &error_description, bool was_ignored_by_handler) Q_DECL_OVERRIDE;
virtual void DidFinishLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url) Q_DECL_OVERRIDE;
virtual void DidUpdateFaviconURL(const std::vector<content::FaviconURL> &candidates) Q_DECL_OVERRIDE;
virtual void DidNavigateAnyFrame(content::RenderFrameHost *render_frame_host, const content::LoadCommittedDetails &details, const content::FrameNavigateParams &params) Q_DECL_OVERRIDE;
void overrideWebPreferences(content::WebContents *, content::WebPreferences*);
void allowCertificateError(const QSharedPointer<CertificateErrorController> &) ;
- void requestGeolocationPermission(const GURL &requestingFrameOrigin, const base::Callback<void (bool)> &resultCallback);
- void cancelGeolocationPermissionRequest(const GURL &requestingFrameOrigin);
- void geolocationPermissionReply(const QUrl&, bool permission);
+ void requestGeolocationPermission(const QUrl &requestingOrigin);
+ void launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame);
private:
WebContentsAdapter *createWindow(content::WebContents *new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture);
- QHash<QUrl, base::Callback<void (bool)> > m_geolocationPermissionRequests;
-
WebContentsAdapterClient *m_viewClient;
QString m_lastSearchedString;
int m_lastReceivedFindReply;
diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index af0c1fe38..67addacd5 100644
--- a/src/core/web_contents_view_qt.cpp
+++ b/src/core/web_contents_view_qt.cpp
@@ -53,8 +53,10 @@ void WebContentsViewQt::initialize(WebContentsAdapterClient* client)
m_factoryClient = client;
// Check if a RWHV was created before the initialization.
- if (m_webContents->GetRenderWidgetHostView())
- static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView())->setAdapterClient(client);
+ if (auto rwhv = static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView())) {
+ rwhv->setAdapterClient(client);
+ rwhv->SetBackgroundColor(toSk(client->backgroundColor()));
+ }
}
content::RenderWidgetHostViewBase* WebContentsViewQt::CreateViewForWidget(content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack)
@@ -82,6 +84,14 @@ content::RenderWidgetHostViewBase* WebContentsViewQt::CreateViewForPopupWidget(c
return view;
}
+void WebContentsViewQt::RenderViewCreated(content::RenderViewHost* host)
+{
+ // The render process is done creating the RenderView and it's ready to be routed
+ // messages at this point.
+ if (m_client)
+ host->GetView()->SetBackgroundColor(toSk(m_client->backgroundColor()));
+}
+
void WebContentsViewQt::CreateView(const gfx::Size& initial_size, gfx::NativeView context)
{
// This is passed through content::WebContents::CreateParams::context either as the native view's client
@@ -103,6 +113,8 @@ void WebContentsViewQt::GetContainerBounds(gfx::Rect* out) const
void WebContentsViewQt::Focus()
{
+ if (content::RenderWidgetHostView *rwhv = m_webContents->GetRenderWidgetHostView())
+ rwhv->Focus();
m_client->focusContainer();
}
@@ -111,6 +123,26 @@ void WebContentsViewQt::SetInitialFocus()
Focus();
}
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeNone, blink::WebContextMenuData::MediaTypeNone)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeImage, blink::WebContextMenuData::MediaTypeImage)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeVideo, blink::WebContextMenuData::MediaTypeVideo)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeAudio, blink::WebContextMenuData::MediaTypeAudio)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeCanvas, blink::WebContextMenuData::MediaTypeCanvas)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeFile, blink::WebContextMenuData::MediaTypeFile)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypePlugin, blink::WebContextMenuData::MediaTypePlugin)
+
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaNone, blink::WebContextMenuData::MediaNone)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaInError, blink::WebContextMenuData::MediaInError)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaPaused, blink::WebContextMenuData::MediaPaused)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaMuted, blink::WebContextMenuData::MediaMuted)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaLoop, blink::WebContextMenuData::MediaLoop)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanSave, blink::WebContextMenuData::MediaCanSave)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaHasAudio, blink::WebContextMenuData::MediaHasAudio)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanToggleControls, blink::WebContextMenuData::MediaCanToggleControls)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaControls, blink::WebContextMenuData::MediaControls)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanPrint, blink::WebContextMenuData::MediaCanPrint)
+ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanRotate, blink::WebContextMenuData::MediaCanRotate)
+
static WebEngineContextMenuData fromParams(const content::ContextMenuParams &params)
{
WebEngineContextMenuData ret;
@@ -118,6 +150,11 @@ static WebEngineContextMenuData fromParams(const content::ContextMenuParams &par
ret.linkUrl = toQt(params.link_url);
ret.linkText = toQt(params.link_text.data());
ret.selectedText = toQt(params.selection_text.data());
+ ret.mediaUrl = toQt(params.src_url);
+ ret.mediaType = (WebEngineContextMenuData::MediaType)params.media_type;
+ ret.hasImageContent = params.has_image_contents;
+ ret.mediaFlags = params.media_flags;
+ ret.suggestedFileName = toQt(params.suggested_filename.data());
return ret;
}
diff --git a/src/core/web_contents_view_qt.h b/src/core/web_contents_view_qt.h
index 896955f7d..cbbca2371 100644
--- a/src/core/web_contents_view_qt.h
+++ b/src/core/web_contents_view_qt.h
@@ -43,8 +43,9 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
-#include "web_contents_adapter_client.h"
+#include "qtwebenginecoreglobal_p.h"
#include "render_widget_host_view_qt.h"
+#include "web_contents_adapter_client.h"
#include "web_contents_delegate_qt.h"
#include "web_engine_context.h"
@@ -75,7 +76,7 @@ public:
virtual void SetPageTitle(const base::string16& title) Q_DECL_OVERRIDE { }
- virtual void RenderViewCreated(content::RenderViewHost* host) Q_DECL_OVERRIDE { QT_NOT_YET_IMPLEMENTED }
+ virtual void RenderViewCreated(content::RenderViewHost* host) Q_DECL_OVERRIDE;
virtual void RenderViewSwappedIn(content::RenderViewHost* host) Q_DECL_OVERRIDE { QT_NOT_YET_IMPLEMENTED }
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 8bc047321..4e4159cef 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -153,6 +153,7 @@ void WebEngineContext::destroy()
// Flush the UI message loop before quitting.
while (delegate->DoWork()) { }
GLContextHelper::destroy();
+ m_devtools.reset(0);
m_runLoop->AfterRun();
// Force to destroy RenderProcessHostImpl by destroying BrowserMainRunner.
@@ -202,34 +203,35 @@ WebEngineContext::WebEngineContext()
Q_FOREACH (const QString& arg, QCoreApplication::arguments())
args << arg.toUtf8();
+ bool useEmbeddedSwitches = args.removeAll("--enable-embedded-switches");
+#if defined(QTWEBENGINE_EMBEDDED_SWITCHES)
+ useEmbeddedSwitches = !args.removeAll("--disable-embedded-switches");
+#endif
+
QVector<const char*> argv(args.size());
for (int i = 0; i < args.size(); ++i)
argv[i] = args[i].constData();
- CommandLine::Init(argv.size(), argv.constData());
+ base::CommandLine::Init(argv.size(), argv.constData());
- CommandLine* parsedCommandLine = CommandLine::ForCurrentProcess();
+ base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess();
parsedCommandLine->AppendSwitchPath(switches::kBrowserSubprocessPath, WebEngineLibraryInfo::getPath(content::CHILD_PROCESS_EXE));
parsedCommandLine->AppendSwitch(switches::kNoSandbox);
- parsedCommandLine->AppendSwitch(switches::kDisablePlugins);
parsedCommandLine->AppendSwitch(switches::kEnableDelegatedRenderer);
parsedCommandLine->AppendSwitch(switches::kEnableThreadedCompositing);
parsedCommandLine->AppendSwitch(switches::kInProcessGPU);
-#if defined(QTWEBENGINE_MOBILE_SWITCHES)
- // Inspired by the Android port's default switches
- parsedCommandLine->AppendSwitch(switches::kEnableOverlayScrollbar);
- parsedCommandLine->AppendSwitch(switches::kEnablePinch);
- parsedCommandLine->AppendSwitch(switches::kEnableViewport);
- parsedCommandLine->AppendSwitch(switches::kEnableViewportMeta);
- parsedCommandLine->AppendSwitch(switches::kMainFrameResizesAreOrientationChanges);
- parsedCommandLine->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
- parsedCommandLine->AppendSwitch(switches::kDisableGpuShaderDiskCache);
- parsedCommandLine->AppendSwitch(switches::kDisable2dCanvasAntialiasing);
- parsedCommandLine->AppendSwitch(switches::kEnableImplSidePainting);
- parsedCommandLine->AppendSwitch(cc::switches::kDisableCompositedAntialiasing);
-
- parsedCommandLine->AppendSwitchASCII(switches::kProfilerTiming, switches::kProfilerTimingDisabledValue);
-#endif
+ if (useEmbeddedSwitches) {
+ // Inspired by the Android port's default switches
+ parsedCommandLine->AppendSwitch(switches::kEnableOverlayScrollbar);
+ parsedCommandLine->AppendSwitch(switches::kEnablePinch);
+ parsedCommandLine->AppendSwitch(switches::kEnableViewport);
+ parsedCommandLine->AppendSwitch(switches::kMainFrameResizesAreOrientationChanges);
+ parsedCommandLine->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
+ parsedCommandLine->AppendSwitch(switches::kDisableGpuShaderDiskCache);
+ parsedCommandLine->AppendSwitch(switches::kDisable2dCanvasAntialiasing);
+ parsedCommandLine->AppendSwitch(cc::switches::kDisableCompositedAntialiasing);
+ parsedCommandLine->AppendSwitchASCII(switches::kProfilerTiming, switches::kProfilerTimingDisabledValue);
+ }
GLContextHelper::initialize();
@@ -260,13 +262,13 @@ WebEngineContext::WebEngineContext()
contentMainParams.sandbox_info = &sandbox_info;
#endif
m_contentRunner->Initialize(contentMainParams);
- m_browserRunner->Initialize(content::MainFunctionParams(*CommandLine::ForCurrentProcess()));
+ m_browserRunner->Initialize(content::MainFunctionParams(*base::CommandLine::ForCurrentProcess()));
// Once the MessageLoop has been created, attach a top-level RunLoop.
m_runLoop.reset(new base::RunLoop);
m_runLoop->BeforeRun();
- m_devtools.reset(new DevToolsHttpHandlerDelegateQt);
+ m_devtools = createDevToolsHttpHandler();
// Force the initialization of MediaCaptureDevicesDispatcher on the UI
// thread to avoid a thread check assertion in its constructor when it
// first gets referenced on the IO thread.
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index dea54ef8a..8f034f18f 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -41,6 +41,8 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "components/devtools_http_handler/devtools_http_handler.h"
#include <QExplicitlySharedDataPointer>
@@ -59,7 +61,6 @@ namespace QtWebEngineCore {
class BrowserContextAdapter;
class ContentMainDelegateQt;
-class DevToolsHttpHandlerDelegateQt;
class SurfaceFactoryQt;
} // namespace
@@ -84,7 +85,7 @@ private:
scoped_ptr<content::BrowserMainRunner> m_browserRunner;
QObject* m_globalQObject;
QExplicitlySharedDataPointer<QtWebEngineCore::BrowserContextAdapter> m_defaultBrowserContext;
- scoped_ptr<QtWebEngineCore::DevToolsHttpHandlerDelegateQt> m_devtools;
+ scoped_ptr<devtools_http_handler::DevToolsHttpHandler> m_devtools;
};
#endif // WEB_ENGINE_CONTEXT_H
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index 980e9a39a..bc030d8f7 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -162,7 +162,6 @@ QString pluginsPath()
if (!initialized) {
initialized = true;
-
const QStringList directories = QCoreApplication::libraryPaths();
Q_FOREACH (const QString &dir, directories) {
const QString candidate = dir % "/" % QLatin1String("qtwebengine");
@@ -173,7 +172,6 @@ QString pluginsPath()
}
if (pluginsPath.isEmpty()) {
- qWarning("Qt WebEngine Plugins directory not found. Trying fallback directory... Plugins as for example video codecs MAY NOT work.");
pluginsPath = fallbackDir();
}
}
@@ -276,7 +274,7 @@ base::string16 WebEngineLibraryInfo::getApplicationName()
std::string WebEngineLibraryInfo::getApplicationLocale()
{
- CommandLine *parsedCommandLine = CommandLine::ForCurrentProcess();
+ base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
if (!parsedCommandLine->HasSwitch(switches::kLang))
return QLocale().bcp47Name().toStdString();
diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index 74c60b778..19558980b 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -213,6 +213,8 @@ void WebEngineSettings::initDefaults(bool offTheRecord)
m_attributes.insert(HyperlinkAuditingEnabled, false);
m_attributes.insert(ScrollAnimatorEnabled, false);
m_attributes.insert(ErrorPageEnabled, true);
+ m_attributes.insert(PluginsEnabled, false);
+ m_attributes.insert(FullScreenSupportEnabled, false);
// Default fonts
QFont defaultFont;
@@ -277,6 +279,8 @@ void WebEngineSettings::applySettingsToWebPreferences(content::WebPreferences *p
prefs->hyperlink_auditing_enabled = testAttribute(HyperlinkAuditingEnabled);
prefs->enable_scroll_animator = testAttribute(ScrollAnimatorEnabled);
prefs->enable_error_page = testAttribute(ErrorPageEnabled);
+ prefs->plugins_enabled = testAttribute(PluginsEnabled);
+ prefs->fullscreen_supported = testAttribute(FullScreenSupportEnabled);
// Fonts settings.
prefs->standard_font_family_map[content::kCommonScript] = toString16(fontFamily(StandardFont));
diff --git a/src/core/web_engine_settings.h b/src/core/web_engine_settings.h
index e9d8010a8..29ef079b7 100644
--- a/src/core/web_engine_settings.h
+++ b/src/core/web_engine_settings.h
@@ -71,6 +71,8 @@ public:
HyperlinkAuditingEnabled,
ScrollAnimatorEnabled,
ErrorPageEnabled,
+ PluginsEnabled,
+ FullScreenSupportEnabled,
};
// Must match the values from the public API in qwebenginesettings.h.
diff --git a/src/core/yuv_video_node.cpp b/src/core/yuv_video_node.cpp
index 23528c8ec..815ea7d51 100644
--- a/src/core/yuv_video_node.cpp
+++ b/src/core/yuv_video_node.cpp
@@ -61,12 +61,16 @@ protected:
"attribute highp vec4 a_position;\n"
"attribute mediump vec2 a_texCoord;\n"
"uniform highp mat4 matrix;\n"
- "varying mediump vec2 v_texCoord;\n"
- "uniform mediump vec2 texScale;\n"
- "uniform mediump vec2 texOffset;\n"
+ "varying mediump vec2 v_yaTexCoord;\n"
+ "varying mediump vec2 v_uvTexCoord;\n"
+ "uniform mediump vec2 yaTexScale;\n"
+ "uniform mediump vec2 yaTexOffset;\n"
+ "uniform mediump vec2 uvTexScale;\n"
+ "uniform mediump vec2 uvTexOffset;\n"
"void main() {\n"
" gl_Position = matrix * a_position;\n"
- " v_texCoord = a_texCoord * texScale + texOffset;\n"
+ " v_yaTexCoord = a_texCoord * yaTexScale + yaTexOffset;\n"
+ " v_uvTexCoord = a_texCoord * uvTexScale + uvTexOffset;\n"
"}";
return shader;
}
@@ -74,19 +78,26 @@ protected:
virtual const char *fragmentShader() const Q_DECL_OVERRIDE {
// Keep in sync with cc::FragmentShaderYUVVideo
static const char *shader =
- "varying mediump vec2 v_texCoord;\n"
+ "varying mediump vec2 v_yaTexCoord;\n"
+ "varying mediump vec2 v_uvTexCoord;\n"
"uniform sampler2D y_texture;\n"
"uniform sampler2D u_texture;\n"
"uniform sampler2D v_texture;\n"
- "uniform lowp float alpha;\n"
- "uniform lowp vec3 yuv_adj;\n"
- "uniform lowp mat3 yuv_matrix;\n"
+ "uniform mediump float alpha;\n"
+ "uniform mediump vec3 yuv_adj;\n"
+ "uniform mediump mat3 yuv_matrix;\n"
+ "uniform mediump vec4 ya_clamp_rect;\n"
+ "uniform mediump vec4 uv_clamp_rect;\n"
"void main() {\n"
- " lowp float y_raw = texture2D(y_texture, v_texCoord).x;\n"
- " lowp float u_unsigned = texture2D(u_texture, v_texCoord).x;\n"
- " lowp float v_unsigned = texture2D(v_texture, v_texCoord).x;\n"
- " lowp vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;\n"
- " lowp vec3 rgb = yuv_matrix * yuv;\n"
+ " mediump vec2 ya_clamped =\n"
+ " max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));\n"
+ " mediump float y_raw = texture2D(y_texture, ya_clamped).x;\n"
+ " mediump vec2 uv_clamped =\n"
+ " max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));\n"
+ " mediump float u_unsigned = texture2D(u_texture, uv_clamped).x;\n"
+ " mediump float v_unsigned = texture2D(v_texture, uv_clamped).x;\n"
+ " mediump vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;\n"
+ " mediump vec3 rgb = yuv_matrix * yuv;\n"
" gl_FragColor = vec4(rgb, 1.0) * alpha;\n"
"}";
return shader;
@@ -94,8 +105,12 @@ protected:
virtual void initialize() Q_DECL_OVERRIDE {
m_id_matrix = program()->uniformLocation("matrix");
- m_id_texScale = program()->uniformLocation("texScale");
- m_id_texOffset = program()->uniformLocation("texOffset");
+ m_id_yaTexScale = program()->uniformLocation("yaTexScale");
+ m_id_uvTexScale = program()->uniformLocation("uvTexScale");
+ m_id_yaTexOffset = program()->uniformLocation("yaTexOffset");
+ m_id_uvTexOffset = program()->uniformLocation("uvTexOffset");
+ m_id_yaClampRect = program()->uniformLocation("ya_clamp_rect");
+ m_id_uvClampRect = program()->uniformLocation("uv_clamp_rect");
m_id_yTexture = program()->uniformLocation("y_texture");
m_id_uTexture = program()->uniformLocation("u_texture");
m_id_vTexture = program()->uniformLocation("v_texture");
@@ -105,8 +120,12 @@ protected:
}
int m_id_matrix;
- int m_id_texScale;
- int m_id_texOffset;
+ int m_id_yaTexScale;
+ int m_id_uvTexScale;
+ int m_id_yaTexOffset;
+ int m_id_uvTexOffset;
+ int m_id_yaClampRect;
+ int m_id_uvClampRect;
int m_id_yTexture;
int m_id_uTexture;
int m_id_vTexture;
@@ -123,21 +142,28 @@ protected:
virtual const char *fragmentShader() const Q_DECL_OVERRIDE {
// Keep in sync with cc::FragmentShaderYUVAVideo
static const char *shader =
- "varying mediump vec2 v_texCoord;\n"
+ "varying mediump vec2 v_yaTexCoord;\n"
+ "varying mediump vec2 v_uvTexCoord;\n"
"uniform sampler2D y_texture;\n"
"uniform sampler2D u_texture;\n"
"uniform sampler2D v_texture;\n"
"uniform sampler2D a_texture;\n"
- "uniform lowp float alpha;\n"
- "uniform lowp vec3 yuv_adj;\n"
- "uniform lowp mat3 yuv_matrix;\n"
+ "uniform mediump float alpha;\n"
+ "uniform mediump vec3 yuv_adj;\n"
+ "uniform mediump mat3 yuv_matrix;\n"
+ "uniform mediump vec4 ya_clamp_rect;\n"
+ "uniform mediump vec4 uv_clamp_rect;\n"
"void main() {\n"
- " lowp float y_raw = texture2D(y_texture, v_texCoord).x;\n"
- " lowp float u_unsigned = texture2D(u_texture, v_texCoord).x;\n"
- " lowp float v_unsigned = texture2D(v_texture, v_texCoord).x;\n"
- " lowp float a_raw = texture2D(a_texture, v_texCoord).x;\n"
- " lowp vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;\n"
- " lowp vec3 rgb = yuv_matrix * yuv;\n"
+ " mediump vec2 ya_clamped =\n"
+ " max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));\n"
+ " mediump float y_raw = texture2D(y_texture, ya_clamped).x;\n"
+ " mediump vec2 uv_clamped =\n"
+ " max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));\n"
+ " mediump float u_unsigned = texture2D(u_texture, uv_clamped).x;\n"
+ " mediump float v_unsigned = texture2D(v_texture, uv_clamped).x;\n"
+ " mediump float a_raw = texture2D(a_texture, ya_clamped).x;\n"
+ " mediump vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;\n"
+ " mediump vec3 rgb = yuv_matrix * yuv;\n"
" gl_FragColor = vec4(rgb, 1.0) * (alpha * a_raw);\n"
"}";
return shader;
@@ -156,6 +182,8 @@ void YUVVideoMaterialShader::updateState(const RenderState &state, QSGMaterial *
{
Q_UNUSED(oldMaterial);
+ // Keep logic in sync with logic in GLRenderer::DrawYUVVideoQuad:
+
YUVVideoMaterial *mat = static_cast<YUVVideoMaterial *>(newMaterial);
program()->setUniformValue(m_id_yTexture, 0);
program()->setUniformValue(m_id_uTexture, 1);
@@ -170,18 +198,47 @@ void YUVVideoMaterialShader::updateState(const RenderState &state, QSGMaterial *
glFuncs.glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit
mat->m_yTexture->bind();
- program()->setUniformValue(m_id_texOffset, mat->m_texCoordRect.topLeft());
- program()->setUniformValue(m_id_texScale, mat->m_texCoordRect.size());
+ const QSizeF yaSizeScale(1.0f / mat->m_yaTexSize.width(), 1.0f / mat->m_yaTexSize.height());
+ const QSizeF uvSizeScale(1.0f / mat->m_uvTexSize.width(), 1.0f / mat->m_uvTexSize.height());
+
+ const QPointF yaTexOffset(mat->m_yaTexCoordRect.left() * yaSizeScale.width(), mat->m_yaTexCoordRect.top() * yaSizeScale.height());
+ const QPointF uvTexOffset(mat->m_uvTexCoordRect.left() * uvSizeScale.width(), mat->m_uvTexCoordRect.top() * uvSizeScale.height());
+ const QSizeF yaTexScale(mat->m_yaTexCoordRect.width() * yaSizeScale.width(), mat->m_yaTexCoordRect.height() * yaSizeScale.height());
+ const QSizeF uvTexScale(mat->m_uvTexCoordRect.width() * uvSizeScale.width(), mat->m_uvTexCoordRect.height() * uvSizeScale.height());
+ program()->setUniformValue(m_id_yaTexOffset, yaTexOffset);
+ program()->setUniformValue(m_id_uvTexOffset, uvTexOffset);
+ program()->setUniformValue(m_id_yaTexScale, yaTexScale);
+ program()->setUniformValue(m_id_uvTexScale, uvTexScale);
+ QRectF yaClampRect(yaTexOffset, yaTexScale);
+ QRectF uvClampRect(uvTexOffset, uvTexScale);
+ yaClampRect = yaClampRect.marginsRemoved(QMarginsF(yaSizeScale.width() * 0.5f, yaSizeScale.height() * 0.5f,
+ yaSizeScale.width() * 0.5f, yaSizeScale.height() * 0.5f));
+ uvClampRect = uvClampRect.marginsRemoved(QMarginsF(uvSizeScale.width() * 0.5f, uvSizeScale.height() * 0.5f,
+ uvSizeScale.width() * 0.5f, uvSizeScale.height() * 0.5f));
+
+ const QVector4D yaClampV(yaClampRect.left(), yaClampRect.top(), yaClampRect.right(), yaClampRect.bottom());
+ const QVector4D uvClampV(uvClampRect.left(), uvClampRect.top(), uvClampRect.right(), uvClampRect.bottom());
+ program()->setUniformValue(m_id_yaClampRect, yaClampV);
+ program()->setUniformValue(m_id_uvClampRect, uvClampV);
// These values are magic numbers that are used in the transformation from YUV
// to RGB color values. They are taken from the following webpage:
// http://www.fourcc.org/fccyvrgb.php
- const float yuv_to_rgb[9] = {
+ const float yuv_to_rgb_rec601[9] = {
1.164f, 0.0f, 1.596f,
1.164f, -.391f, -.813f,
1.164f, 2.018f, 0.0f,
};
- const QMatrix3x3 yuvMatrix(yuv_to_rgb);
+ const float yuv_to_rgb_rec709[9] = {
+ 1.164f, 0.0f, 1.793f,
+ 1.164f, -0.213f, -0.533f,
+ 1.164f, 2.112f, 0.0f,
+ };
+ const float yuv_to_rgb_jpeg[9] = {
+ 1.f, 0.0f, 1.402f,
+ 1.f, -.34414f, -.71414f,
+ 1.f, 1.772f, 0.0f,
+ };
// These values map to 16, 128, and 128 respectively, and are computed
// as a fraction over 256 (e.g. 16 / 256 = 0.0625).
@@ -189,9 +246,35 @@ void YUVVideoMaterialShader::updateState(const RenderState &state, QSGMaterial *
// Y - 16 : Gives 16 values of head and footroom for overshooting
// U - 128 : Turns unsigned U into signed U [-128,127]
// V - 128 : Turns unsigned V into signed V [-128,127]
- const QVector3D yuvAdjust(-0.0625f, -0.5f, -0.5f);
- program()->setUniformValue(m_id_yuvMatrix, yuvMatrix);
- program()->setUniformValue(m_id_yuvAdjust, yuvAdjust);
+ const float yuv_adjust_constrained[3] = {
+ -0.0625f, -0.5f, -0.5f,
+ };
+
+ // Same as above, but without the head and footroom.
+ const float yuv_adjust_full[3] = {
+ 0.0f, -0.5f, -0.5f,
+ };
+
+ const float *yuv_to_rgb = 0;
+ const float *yuv_adjust = 0;
+
+ switch (mat->m_colorSpace) {
+ case YUVVideoMaterial::REC_601:
+ yuv_to_rgb = yuv_to_rgb_rec601;
+ yuv_adjust = yuv_adjust_constrained;
+ break;
+ case YUVVideoMaterial::REC_709:
+ yuv_to_rgb = yuv_to_rgb_rec709;
+ yuv_adjust = yuv_adjust_constrained;
+ break;
+ case YUVVideoMaterial::JPEG:
+ yuv_to_rgb = yuv_to_rgb_jpeg;
+ yuv_adjust = yuv_adjust_full;
+ break;
+ }
+
+ program()->setUniformValue(m_id_yuvMatrix, QMatrix3x3(yuv_to_rgb));
+ program()->setUniformValue(m_id_yuvAdjust, QVector3D(yuv_adjust[0], yuv_adjust[1], yuv_adjust[2]));
if (state.isOpacityDirty())
program()->setUniformValue(m_id_opacity, state.opacity());
@@ -217,11 +300,17 @@ void YUVAVideoMaterialShader::updateState(const RenderState &state, QSGMaterial
}
-YUVVideoMaterial::YUVVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, const QRectF &texCoordRect)
+YUVVideoMaterial::YUVVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture,
+ const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
+ YUVVideoMaterial::ColorSpace colorspace)
: m_yTexture(yTexture)
, m_uTexture(uTexture)
, m_vTexture(vTexture)
- , m_texCoordRect(texCoordRect)
+ , m_yaTexCoordRect(yaTexCoordRect)
+ , m_uvTexCoordRect(uvTexCoordRect)
+ , m_yaTexSize(yaTexSize)
+ , m_uvTexSize(uvTexSize)
+ , m_colorSpace(colorspace)
{
}
@@ -240,8 +329,10 @@ int YUVVideoMaterial::compare(const QSGMaterial *other) const
return m_vTexture->textureId() - m->m_vTexture->textureId();
}
-YUVAVideoMaterial::YUVAVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture, const QRectF &texCoordRect)
- : YUVVideoMaterial(yTexture, uTexture, vTexture, texCoordRect)
+YUVAVideoMaterial::YUVAVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture,
+ const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
+ YUVVideoMaterial::ColorSpace colorspace)
+ : YUVVideoMaterial(yTexture, uTexture, vTexture, yaTexCoordRect, uvTexCoordRect, yaTexSize, uvTexSize, colorspace)
, m_aTexture(aTexture)
{
setFlag(Blending, aTexture);
@@ -260,15 +351,17 @@ int YUVAVideoMaterial::compare(const QSGMaterial *other) const
return (m_aTexture ? m_aTexture->textureId() : 0) - (m->m_aTexture ? m->m_aTexture->textureId() : 0);
}
-YUVVideoNode::YUVVideoNode(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture, const QRectF &texCoordRect)
+YUVVideoNode::YUVVideoNode(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture,
+ const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
+ YUVVideoMaterial::ColorSpace colorspace)
: m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
{
setGeometry(&m_geometry);
setFlag(QSGNode::OwnsMaterial);
if (aTexture)
- m_material = new YUVAVideoMaterial(yTexture, uTexture, vTexture, aTexture, texCoordRect);
+ m_material = new YUVAVideoMaterial(yTexture, uTexture, vTexture, aTexture, yaTexCoordRect, uvTexCoordRect, yaTexSize, uvTexSize, colorspace);
else
- m_material = new YUVVideoMaterial(yTexture, uTexture, vTexture, texCoordRect);
+ m_material = new YUVVideoMaterial(yTexture, uTexture, vTexture, yaTexCoordRect, uvTexCoordRect, yaTexSize, uvTexSize, colorspace);
setMaterial(m_material);
}
diff --git a/src/core/yuv_video_node.h b/src/core/yuv_video_node.h
index f96df56ce..457c2c7fe 100644
--- a/src/core/yuv_video_node.h
+++ b/src/core/yuv_video_node.h
@@ -50,7 +50,14 @@ QT_END_NAMESPACE
class YUVVideoMaterial : public QSGMaterial
{
public:
- YUVVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, const QRectF &texCoordRect);
+ enum ColorSpace {
+ REC_601, // SDTV standard with restricted "studio swing" color range.
+ REC_709, // HDTV standard with restricted "studio swing" color range.
+ JPEG // Full color range [0, 255] JPEG color space.
+ };
+ YUVVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture,
+ const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
+ ColorSpace colorspace);
virtual QSGMaterialType *type() const Q_DECL_OVERRIDE {
static QSGMaterialType theType;
@@ -63,13 +70,20 @@ public:
QSGTexture *m_yTexture;
QSGTexture *m_uTexture;
QSGTexture *m_vTexture;
- QRectF m_texCoordRect;
+ QRectF m_yaTexCoordRect;
+ QRectF m_uvTexCoordRect;
+ QSizeF m_yaTexSize;
+ QSizeF m_uvTexSize;
+ ColorSpace m_colorSpace;
+
};
class YUVAVideoMaterial : public YUVVideoMaterial
{
public:
- YUVAVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture, const QRectF &texCoordRect);
+ YUVAVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture,
+ const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
+ ColorSpace colorspace);
virtual QSGMaterialType *type() const Q_DECL_OVERRIDE{
static QSGMaterialType theType;
@@ -85,7 +99,9 @@ public:
class YUVVideoNode : public QSGGeometryNode
{
public:
- YUVVideoNode(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture, const QRectF &texCoordRect);
+ YUVVideoNode(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture,
+ const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
+ YUVVideoMaterial::ColorSpace colorspace);
void setRect(const QRectF &rect);
private:
diff --git a/src/process/process.pro b/src/process/process.pro
index 5526b0f1c..ee859a05c 100644
--- a/src/process/process.pro
+++ b/src/process/process.pro
@@ -9,23 +9,7 @@ contains(QT_CONFIG, qt_framework) {
# Deploy the QtWebEngineProcess app bundle into the QtWebEngineCore framework.
DESTDIR = $$MODULE_BASE_OUTDIR/lib/QtWebEngineCore.framework/Versions/5/Helpers
- # FIXME: We can remove those steps in Qt 5.5 once @rpath works
- # "QT += webenginecore" would pull all dependencies that we'd also need to update
- # with install_name_tool on OSX, but we only need access to the private
- # QtWebEngine::processMain. qtAddModule will take care of finding where
- # the library is without pulling additional librarie.
- QT = core
- qtAddModule(webenginecore, LIBS)
- CONFIG -= link_prl
- QMAKE_POST_LINK = \
- "xcrun install_name_tool -change " \
- "`xcrun otool -X -L $(TARGET) | grep QtWebEngineCore | cut -d ' ' -f 1` " \
- "@executable_path/../../../../QtWebEngineCore " \
- "$(TARGET); " \
- "xcrun install_name_tool -change " \
- "`xcrun otool -X -L $(TARGET) | grep QtCore | cut -d ' ' -f 1` " \
- "@executable_path/../../../../../../../QtCore.framework/QtCore " \
- "$(TARGET) "
+ QT += webenginecore
} else {
CONFIG -= app_bundle
win32: DESTDIR = $$MODULE_BASE_OUTDIR/bin
diff --git a/src/webengine/api/qquickwebenginedownloaditem.cpp b/src/webengine/api/qquickwebenginedownloaditem.cpp
index e04cff2c4..da47388ee 100644
--- a/src/webengine/api/qquickwebenginedownloaditem.cpp
+++ b/src/webengine/api/qquickwebenginedownloaditem.cpp
@@ -227,7 +227,7 @@ qint64 QQuickWebEngineDownloadItem::receivedBytes() const
The download path can only be set in the \c WebEngineProfile.onDownloadRequested
handler before the download is accepted.
- \sa WebEngineProfile::downloadRequested(WebEngineDownloadItem download), WebEngineDownloadItem::accept()
+ \sa WebEngineProfile::downloadRequested(), accept()
*/
QString QQuickWebEngineDownloadItem::path() const
diff --git a/src/webengine/api/qquickwebenginehistory.cpp b/src/webengine/api/qquickwebenginehistory.cpp
index 9a737fbbe..175b52248 100644
--- a/src/webengine/api/qquickwebenginehistory.cpp
+++ b/src/webengine/api/qquickwebenginehistory.cpp
@@ -118,6 +118,26 @@ int QQuickWebEngineForwardHistoryListModelPrivate::offsetForIndex(int index) con
return index + 1;
}
+/*!
+ \qmltype WebEngineHistoryListModel
+ \instantiates QQuickWebEngineHistoryListModel
+ \inqmlmodule QtWebEngine 1.1
+ \since QtWebEngine 1.1
+
+ \brief A data model that represents the history of a web engine page.
+
+ The WebEngineHistoryListModel type exposes the \e title, \e url, and \e offset roles. The
+ \e title and \e url specify the title and URL of the visited page. The \e offset specifies
+ the position of the page in respect to the current page (0). A positive number indicates that
+ the page was visited after the current page, whereas a negative number indicates that the page
+ was visited before the current page.
+
+ This type is uncreatable, but it can be accessed by using the
+ \l{WebEngineView::navigationHistory}{WebEngineView.navigationHistory} property.
+
+ \sa WebEngineHistory
+*/
+
QQuickWebEngineHistoryListModel::QQuickWebEngineHistoryListModel()
: QAbstractListModel()
{
@@ -185,6 +205,67 @@ QQuickWebEngineHistoryPrivate::~QQuickWebEngineHistoryPrivate()
{
}
+/*!
+ \qmltype WebEngineHistory
+ \instantiates QQuickWebEngineHistory
+ \inqmlmodule QtWebEngine 1.1
+ \since QtWebEngine 1.1
+
+ \brief Provides data models that represent the history of a web engine page.
+
+ The WebEngineHistory type can be accessed by using the
+ \l{WebEngineView::navigationHistory}{WebEngineView.navigationHistory} property.
+
+ The WebEngineHistory type providess the following WebEngineHistoryListModel data model objects:
+
+ \list
+ \li \c backItems, which contains the URLs of visited pages.
+ \li \c forwardItems, which contains the URLs of the pages that were visited after visiting
+ the current page.
+ \li \c items, which contains the URLs of the back and forward items, as well as the URL of
+ the current page.
+ \endlist
+
+ The easiest way to use these models is to use them in a ListView as illustrated by the
+ following code snippet:
+
+ \code
+ ListView {
+ id: historyItemsList
+ anchors.fill: parent
+ model: webEngineView.navigationHistory.items
+ delegate:
+ Text {
+ color: "black"
+ text: model.title + " - " + model.url + " (" + model.offset + ")"
+ }
+ }
+ \endcode
+
+ The ListView shows the content of the corresponding model. The delegate is responsible for the
+ format of the list items. The appearance of each item of the list in the delegate can be defined
+ separately (it is not web engine specific).
+
+ The model roles \e title and \e url specify the title and URL of the visited page. The \e offset
+ role specifies the position of the page in respect to the current page (0). A positive number
+ indicates that the page was visited after the current page, whereas a negative number indicates
+ that the page was visited before the current page.
+
+ The data models can also be used to create a menu, as illustrated by the following code
+ snippet:
+
+ \quotefromfile webengine/quicknanobrowser/browserwindow.qml
+ \skipto ToolBar
+ \printuntil onObjectRemoved
+ \printuntil }
+ \printuntil }
+ \printuntil }
+
+ For the complete example, see \l{WebEngine Quick Nano Browser}.
+
+ \sa WebEngineHistoryListModel
+*/
+
QQuickWebEngineHistory::QQuickWebEngineHistory(QQuickWebEngineViewPrivate *view)
: d_ptr(new QQuickWebEngineHistoryPrivate(view))
{
@@ -194,6 +275,13 @@ QQuickWebEngineHistory::~QQuickWebEngineHistory()
{
}
+/*!
+ \qmlproperty QQuickWebEngineHistoryListModel WebEngineHistory::items
+ \readonly
+ \since QtWebEngine 1.1
+
+ URLs of back items, forward items, and the current item in the history.
+*/
QQuickWebEngineHistoryListModel *QQuickWebEngineHistory::items() const
{
Q_D(const QQuickWebEngineHistory);
@@ -202,6 +290,13 @@ QQuickWebEngineHistoryListModel *QQuickWebEngineHistory::items() const
return d->m_navigationModel.data();
}
+/*!
+ \qmlproperty QQuickWebEngineHistoryListModel WebEngineHistory::backItems
+ \readonly
+ \since QtWebEngine 1.1
+
+ URLs of visited pages.
+*/
QQuickWebEngineHistoryListModel *QQuickWebEngineHistory::backItems() const
{
Q_D(const QQuickWebEngineHistory);
@@ -210,6 +305,13 @@ QQuickWebEngineHistoryListModel *QQuickWebEngineHistory::backItems() const
return d->m_backNavigationModel.data();
}
+/*!
+ \qmlproperty QQuickWebEngineHistoryListModel WebEngineHistory::forwardItems
+ \readonly
+ \since QtWebEngine 1.1
+
+ URLs of the pages that were visited after visiting the current page.
+*/
QQuickWebEngineHistoryListModel *QQuickWebEngineHistory::forwardItems() const
{
Q_D(const QQuickWebEngineHistory);
diff --git a/src/webengine/api/qquickwebenginenewviewrequest.cpp b/src/webengine/api/qquickwebenginenewviewrequest.cpp
index f66a44e5f..6e20c0a46 100644
--- a/src/webengine/api/qquickwebenginenewviewrequest.cpp
+++ b/src/webengine/api/qquickwebenginenewviewrequest.cpp
@@ -89,7 +89,7 @@ bool QQuickWebEngineNewViewRequest::isUserInitiated() const
*/
void QQuickWebEngineNewViewRequest::openIn(QQuickWebEngineView *view)
{
- if (!m_adapter) {
+ if (!m_adapter && !m_requestedUrl.isValid()) {
qWarning("Trying to open an empty request, it was either already used or was invalidated."
"\nYou must complete the request synchronously within the newViewRequested signal handler."
" If a view hasn't been adopted before returning, the request will be invalidated.");
@@ -100,6 +100,9 @@ void QQuickWebEngineNewViewRequest::openIn(QQuickWebEngineView *view)
qWarning("Trying to open a WebEngineNewViewRequest in an invalid WebEngineView.");
return;
}
- view->d_func()->adoptWebContents(m_adapter.data());
+ if (m_adapter)
+ view->d_func()->adoptWebContents(m_adapter.data());
+ else
+ view->setUrl(m_requestedUrl);
m_adapter.reset();
}
diff --git a/src/webengine/api/qquickwebenginenewviewrequest_p.h b/src/webengine/api/qquickwebenginenewviewrequest_p.h
index f9fac13e9..b408812ba 100644
--- a/src/webengine/api/qquickwebenginenewviewrequest_p.h
+++ b/src/webengine/api/qquickwebenginenewviewrequest_p.h
@@ -73,6 +73,8 @@ private:
QQuickWebEngineView::NewViewDestination m_destination;
bool m_isUserInitiated;
QExplicitlySharedDataPointer<QtWebEngineCore::WebContentsAdapter> m_adapter;
+ QUrl m_requestedUrl;
+ friend class QQuickWebEngineView;
friend class QQuickWebEngineViewPrivate;
};
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index 68884f967..a678fe5fa 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -40,6 +40,7 @@
#include "qquickwebenginedownloaditem_p_p.h"
#include "qquickwebengineprofile_p_p.h"
#include "qquickwebenginesettings_p.h"
+#include "qwebenginecookiestoreclient.h"
#include <QQmlEngine>
@@ -56,6 +57,9 @@ QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(BrowserContextAdapt
{
m_browserContextRef->addClient(this);
m_settings->d_ptr->initDefaults(browserContext->isOffTheRecord());
+ // Fullscreen API was implemented before the supported setting, so we must
+ // make it default true to avoid change in default API behavior.
+ m_settings->d_ptr->setAttribute(QtWebEngineCore::WebEngineSettings::FullScreenSupportEnabled, true);
}
QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate()
@@ -131,10 +135,11 @@ void QQuickWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info
\instantiates QQuickWebEngineProfile
\inqmlmodule QtWebEngine 1.1
\since QtWebEngine 1.1
- \brief Contains common settings for multiple web engine views.
+ \brief Contains settings, scripts, and visited links common to multiple web engine views.
- Contains settings and history shared by all the web engine views that belong
- to the profile.
+ WebEngineProfile contains settings, scripts, and the list of visited links shared by all
+ views that belong to the profile. As such, profiles can be used to isolate views
+ from each other. A typical use case is a dedicated profile for a 'private browsing' mode.
Each web engine view has an associated profile. Views that do not have a specific profile set
share a common default one.
@@ -384,6 +389,28 @@ void QQuickWebEngineProfile::setHttpCacheMaximumSize(int maximumSize)
emit httpCacheMaximumSizeChanged();
}
+/*!
+ \qmlproperty QString WebEngineProfile::httpAcceptLanguage
+
+ The value of the Accept-Language HTTP request-header field.
+
+ \since QtWebEngine 1.2
+*/
+QString QQuickWebEngineProfile::httpAcceptLanguage() const
+{
+ Q_D(const QQuickWebEngineProfile);
+ return d->browserContext()->httpAcceptLanguage();
+}
+
+void QQuickWebEngineProfile::setHttpAcceptLanguage(const QString &httpAcceptLanguage)
+{
+ Q_D(QQuickWebEngineProfile);
+ if (d->browserContext()->httpAcceptLanguage() == httpAcceptLanguage)
+ return;
+ d->browserContext()->setHttpAcceptLanguage(httpAcceptLanguage);
+ emit httpAcceptLanguageChanged();
+}
+
QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile()
{
static QQuickWebEngineProfile *profile = new QQuickWebEngineProfile(
@@ -392,6 +419,12 @@ QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile()
return profile;
}
+QWebEngineCookieStoreClient *QQuickWebEngineProfile::cookieStoreClient() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return d->browserContext()->cookieStoreClient();
+}
+
QQuickWebEngineSettings *QQuickWebEngineProfile::settings() const
{
const Q_D(QQuickWebEngineProfile);
diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h
index 323721bd0..b4e0d173c 100644
--- a/src/webengine/api/qquickwebengineprofile_p.h
+++ b/src/webengine/api/qquickwebengineprofile_p.h
@@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE
class QQuickWebEngineDownloadItem;
class QQuickWebEngineProfilePrivate;
class QQuickWebEngineSettings;
+class QWebEngineCookieStoreClient;
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineProfile : public QObject {
Q_OBJECT
@@ -74,6 +75,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineProfile : public QObject {
Q_PROPERTY(QString cachePath READ cachePath WRITE setCachePath NOTIFY cachePathChanged FINAL)
Q_PROPERTY(QString httpUserAgent READ httpUserAgent WRITE setHttpUserAgent NOTIFY httpUserAgentChanged FINAL)
Q_PROPERTY(HttpCacheType httpCacheType READ httpCacheType WRITE setHttpCacheType NOTIFY httpCacheTypeChanged FINAL)
+ Q_PROPERTY(QString httpAcceptLanguage READ httpAcceptLanguage WRITE setHttpAcceptLanguage NOTIFY httpAcceptLanguageChanged FINAL REVISION 1)
Q_PROPERTY(PersistentCookiesPolicy persistentCookiesPolicy READ persistentCookiesPolicy WRITE setPersistentCookiesPolicy NOTIFY persistentCookiesPolicyChanged FINAL)
Q_PROPERTY(int httpCacheMaximumSize READ httpCacheMaximumSize WRITE setHttpCacheMaximumSize NOTIFY httpCacheMaximumSizeChanged FINAL)
public:
@@ -115,8 +117,13 @@ public:
int httpCacheMaximumSize() const;
void setHttpCacheMaximumSize(int maxSize);
+ QString httpAcceptLanguage() const;
+ void setHttpAcceptLanguage(const QString &httpAcceptLanguage);
+
static QQuickWebEngineProfile *defaultProfile();
+ Q_REVISION(1) Q_INVOKABLE QWebEngineCookieStoreClient *cookieStoreClient() const;
+
signals:
void storageNameChanged();
void offTheRecordChanged();
@@ -126,6 +133,7 @@ signals:
void httpCacheTypeChanged();
void persistentCookiesPolicyChanged();
void httpCacheMaximumSizeChanged();
+ Q_REVISION(1) void httpAcceptLanguageChanged();
void downloadRequested(QQuickWebEngineDownloadItem *download);
void downloadFinished(QQuickWebEngineDownloadItem *download);
diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp
index 248713543..8f2e1bcf2 100644
--- a/src/webengine/api/qquickwebenginesettings.cpp
+++ b/src/webengine/api/qquickwebenginesettings.cpp
@@ -54,13 +54,15 @@ QQuickWebEngineSettings::QQuickWebEngineSettings(QQuickWebEngineSettings *parent
\instantiates QQuickWebEngineSettings
\inqmlmodule QtWebEngine
\since QtWebEngine 1.1
- \brief WebEngineSettings allows configuration of browser properties and attributes.
+ \brief Allows configuration of browser properties and attributes.
- WebEngineSettings allows configuration of browser properties and generic attributes, such as
- JavaScript support, focus behavior, and access to remote content.
-
- Each WebEngineView can have individual settings.
+ The WebEngineSettings type can be used to configure browser properties and generic
+ attributes, such as JavaScript support, focus behavior, and access to remote content. This type
+ is uncreatable, but the default settings for all web engine views can be accessed by using
+ the \l [QML] {WebEngine::settings}{WebEngine.settings} property.
+ Each web engine view can have individual settings that can be accessed by using the
+ \l{WebEngineView::settings}{WebEngineView.settings} property.
*/
@@ -206,6 +208,31 @@ bool QQuickWebEngineSettings::errorPageEnabled() const
}
/*!
+ \qmlproperty bool WebEngineSettings::pluginsEnabled
+
+ Enables support for Pepper plugins, such as the Flash player.
+
+ Disabled by default.
+*/
+bool QQuickWebEngineSettings::pluginsEnabled() const
+{
+ return d_ptr->testAttribute(WebEngineSettings::PluginsEnabled);
+}
+
+/*!
+ \qmlproperty bool WebEngineSettings::fullscreenSupportEnabled
+ \since QtWebEngine 1.2
+
+ Tells the web engine whether fullscreen is supported in this application or not.
+
+ Enabled by default.
+*/
+bool QQuickWebEngineSettings::fullScreenSupportEnabled() const
+{
+ return d_ptr->testAttribute(WebEngineSettings::FullScreenSupportEnabled);
+}
+
+/*!
\qmlproperty QString WebEngineSettings::defaultTextEncoding
Sets the default encoding. The value must be a string describing an encoding such as "utf-8" or
@@ -309,6 +336,22 @@ void QQuickWebEngineSettings::setErrorPageEnabled(bool on)
Q_EMIT errorPageEnabledChanged();
}
+void QQuickWebEngineSettings::setPluginsEnabled(bool on)
+{
+ bool wasOn = d_ptr->testAttribute(WebEngineSettings::PluginsEnabled);
+ d_ptr->setAttribute(WebEngineSettings::PluginsEnabled, on);
+ if (wasOn != on)
+ Q_EMIT pluginsEnabledChanged();
+}
+
+void QQuickWebEngineSettings::setFullScreenSupportEnabled(bool on)
+{
+ bool wasOn = d_ptr->testAttribute(WebEngineSettings::FullScreenSupportEnabled);
+ d_ptr->setAttribute(WebEngineSettings::FullScreenSupportEnabled, on);
+ if (wasOn != on)
+ Q_EMIT fullScreenSupportEnabledChanged();
+}
+
void QQuickWebEngineSettings::setDefaultTextEncoding(QString encoding)
{
const QString oldDefaultTextEncoding = d_ptr->defaultTextEncoding();
diff --git a/src/webengine/api/qquickwebenginesettings_p.h b/src/webengine/api/qquickwebenginesettings_p.h
index 213505078..030762ed3 100644
--- a/src/webengine/api/qquickwebenginesettings_p.h
+++ b/src/webengine/api/qquickwebenginesettings_p.h
@@ -71,6 +71,9 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject {
Q_PROPERTY(bool localContentCanAccessFileUrls READ localContentCanAccessFileUrls WRITE setLocalContentCanAccessFileUrls NOTIFY localContentCanAccessFileUrlsChanged)
Q_PROPERTY(bool hyperlinkAuditingEnabled READ hyperlinkAuditingEnabled WRITE setHyperlinkAuditingEnabled NOTIFY hyperlinkAuditingEnabledChanged)
Q_PROPERTY(bool errorPageEnabled READ errorPageEnabled WRITE setErrorPageEnabled NOTIFY errorPageEnabledChanged)
+ Q_PROPERTY(bool pluginsEnabled READ pluginsEnabled WRITE setPluginsEnabled NOTIFY pluginsEnabledChanged)
+ // FIXME(QTBUG-40043): Mark fullScreenSupportEnabled with REVISION 1
+ Q_PROPERTY(bool fullScreenSupportEnabled READ fullScreenSupportEnabled WRITE setFullScreenSupportEnabled NOTIFY fullScreenSupportEnabledChanged)
Q_PROPERTY(QString defaultTextEncoding READ defaultTextEncoding WRITE setDefaultTextEncoding NOTIFY defaultTextEncodingChanged)
public:
@@ -87,6 +90,8 @@ public:
bool localContentCanAccessFileUrls() const;
bool hyperlinkAuditingEnabled() const;
bool errorPageEnabled() const;
+ bool pluginsEnabled() const;
+ bool fullScreenSupportEnabled() const;
QString defaultTextEncoding() const;
void setAutoLoadImages(bool on);
@@ -100,6 +105,8 @@ public:
void setLocalContentCanAccessFileUrls(bool on);
void setHyperlinkAuditingEnabled(bool on);
void setErrorPageEnabled(bool on);
+ void setPluginsEnabled(bool on);
+ void setFullScreenSupportEnabled(bool on);
void setDefaultTextEncoding(QString encoding);
signals:
@@ -114,6 +121,9 @@ signals:
void localContentCanAccessFileUrlsChanged();
void hyperlinkAuditingEnabledChanged();
void errorPageEnabledChanged();
+ void pluginsEnabledChanged();
+ // FIXME(QTBUG-40043): Mark fullScreenSupportEnabledChanged with Q_REVISION(1)
+ void fullScreenSupportEnabledChanged();
void defaultTextEncodingChanged();
private:
diff --git a/src/webengine/api/qquickwebenginesingleton.cpp b/src/webengine/api/qquickwebenginesingleton.cpp
index 3f0c8cb65..7ff974eb4 100644
--- a/src/webengine/api/qquickwebenginesingleton.cpp
+++ b/src/webengine/api/qquickwebenginesingleton.cpp
@@ -41,11 +41,47 @@
QT_BEGIN_NAMESPACE
+/*!
+ \qmltype WebEngine
+ \instantiates QQuickWebEngineSingleton
+ \inqmlmodule QtWebEngine 1.1
+ \since QtWebEngine 1.1
+ \brief Provides access to the default settings and profiles shared by all web engine views.
+
+ The WebEngine singleton type provides access to the default profile and the default settings
+ shared by all web engine views. It can be used to change settings globally, as illustrated by
+ the following code snippet:
+
+ \code
+ Component.onCompleted: {
+ WebEngine.settings.javaScriptEnabled = true;
+ }
+ \endcode
+*/
+
+/*!
+ \qmlproperty WebEngineSettings WebEngine::settings
+ \readonly
+ \since QtWebEngine 1.1
+
+ Default settings for all web engine views.
+
+ \sa WebEngineSettings
+*/
QQuickWebEngineSettings *QQuickWebEngineSingleton::settings() const
{
return defaultProfile()->settings();
}
+/*!
+ \qmlproperty WebEngineProfile WebEngine::defaultProfile
+ \readonly
+ \since QtWebEngine 1.1
+
+ Default profile for all web engine views.
+
+ \sa WebEngineProfile
+*/
QQuickWebEngineProfile *QQuickWebEngineSingleton::defaultProfile() const
{
return QQuickWebEngineProfile::defaultProfile();
diff --git a/src/webengine/api/qquickwebenginetestsupport_p.h b/src/webengine/api/qquickwebenginetestsupport_p.h
index 8d52dfa7c..d4b50ac2d 100644
--- a/src/webengine/api/qquickwebenginetestsupport_p.h
+++ b/src/webengine/api/qquickwebenginetestsupport_p.h
@@ -78,6 +78,10 @@ public:
QQuickWebEngineTestSupport();
QQuickWebEngineErrorPage *errorPage() const;
+Q_SIGNALS:
+ void validationMessageShown(const QString &mainText, const QString &subText);
+ void windowCloseRejected();
+
private:
QScopedPointer<QQuickWebEngineErrorPage> m_errorPage;
};
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 6c3452a6a..52245e147 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -37,8 +37,10 @@
#include "qquickwebengineview_p.h"
#include "qquickwebengineview_p_p.h"
+#include "authentication_dialog_controller.h"
#include "browser_context_adapter.h"
#include "certificate_error_controller.h"
+#include "file_picker_controller.h"
#include "javascript_dialog_controller.h"
#include "qquickwebenginehistory_p.h"
#include "qquickwebenginecertificateerror_p.h"
@@ -63,7 +65,9 @@
#include "web_engine_settings.h"
#include "web_engine_visited_links_manager.h"
+#include <QClipboard>
#include <QGuiApplication>
+#include <QMimeData>
#include <QQmlComponent>
#include <QQmlContext>
#include <QQmlEngine>
@@ -102,8 +106,10 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
, loadProgress(0)
, m_isFullScreen(false)
, isLoading(false)
+ , m_activeFocusOnPress(true)
, devicePixelRatio(QGuiApplication::primaryScreen()->devicePixelRatio())
, m_dpiScale(1.0)
+ , m_backgroundColor(Qt::white)
{
// The gold standard for mobile web content is 160 dpi, and the devicePixelRatio expected
// is the (possibly quantized) ratio of device dpi to 160 dpi.
@@ -175,31 +181,101 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu
if (!menu)
return false;
+ contextMenuData = data;
+
// Populate our menu
MenuItemHandler *item = 0;
+ if (!data.linkText.isEmpty() && data.linkUrl.isValid()) {
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::OpenLinkInThisWindow); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Follow Link"));
+ }
+
if (data.selectedText.isEmpty()) {
item = new MenuItemHandler(menu);
QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::goBack);
- ui()->addMenuItem(item, QObject::tr("Back"), QStringLiteral("go-previous"), q->canGoBack());
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Back"), QStringLiteral("go-previous"), q->canGoBack());
item = new MenuItemHandler(menu);
QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::goForward);
- ui()->addMenuItem(item, QObject::tr("Forward"), QStringLiteral("go-next"), q->canGoForward());
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Forward"), QStringLiteral("go-next"), q->canGoForward());
item = new MenuItemHandler(menu);
QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::reload);
- ui()->addMenuItem(item, QObject::tr("Reload"), QStringLiteral("view-refresh"));
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Reload"), QStringLiteral("view-refresh"));
} else {
- item = new CopyMenuItem(menu, data.selectedText);
- ui()->addMenuItem(item, QObject::tr("Copy..."));
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::Copy); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy"));
}
- if (!data.linkText.isEmpty() && data.linkUrl.isValid()) {
- item = new NavigateMenuItem(menu, adapter, data.linkUrl);
- ui()->addMenuItem(item, QObject::tr("Navigate to..."));
- item = new CopyMenuItem(menu, data.linkUrl.toString());
- ui()->addMenuItem(item, QObject::tr("Copy link address"));
+ if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) {
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyLinkToClipboard); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Link URL"));
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadLinkToDisk); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Link"));
+ }
+ if (contextMenuData.mediaUrl.isValid()) {
+ switch (contextMenuData.mediaType) {
+ case WebEngineContextMenuData::MediaTypeImage:
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageUrlToClipboard); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image URL"));
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageToClipboard); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image"));
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadImageToDisk); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Image"));
+ break;
+ case WebEngineContextMenuData::MediaTypeCanvas:
+ Q_UNREACHABLE(); // mediaUrl is invalid for canvases
+ break;
+ case WebEngineContextMenuData::MediaTypeAudio:
+ case WebEngineContextMenuData::MediaTypeVideo:
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyMediaUrlToClipboard); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Media URL"));
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadMediaToDisk); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Media"));
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaPlayPause); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Play/Pause"));
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaLoop); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Looping"));
+ if (contextMenuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) {
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaMute); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Mute"));
+ }
+ if (contextMenuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) {
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaControls); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Media Controls"));
+ }
+ break;
+ default:
+ break;
+ }
+ } else if (contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas) {
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageToClipboard); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image"));
+ }
+ if (adapter->hasInspector()) {
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::InspectElement); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Inspect Element"));
+ }
+ if (isFullScreenMode()) {
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ExitFullScreen); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Exit Full Screen Mode"));
}
// FIXME: expose the context menu data as an attached property to make this more useful
@@ -251,9 +327,9 @@ void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url
Q_EMIT q->featurePermissionRequested(url, QQuickWebEngineView::Geolocation);
}
-void QQuickWebEngineViewPrivate::runFileChooser(FileChooserMode mode, const QString &defaultFileName, const QStringList &acceptedMimeTypes)
+void QQuickWebEngineViewPrivate::runFileChooser(FilePickerController* controller)
{
- ui()->showFilePicker(mode, defaultFileName, acceptedMimeTypes, adapter);
+ ui()->showFilePicker(controller);
}
void QQuickWebEngineViewPrivate::passOnFocus(bool reverse)
@@ -310,6 +386,11 @@ qreal QQuickWebEngineViewPrivate::dpiScale() const
return m_dpiScale;
}
+QColor QQuickWebEngineViewPrivate::backgroundColor() const
+{
+ return m_backgroundColor;
+}
+
void QQuickWebEngineViewPrivate::loadStarted(const QUrl &provisionalUrl, bool isErrorPage)
{
Q_Q(QQuickWebEngineView);
@@ -423,17 +504,26 @@ void QQuickWebEngineViewPrivate::adoptNewWindow(WebContentsAdapter *newWebConten
void QQuickWebEngineViewPrivate::close()
{
- // Not implemented yet.
+ Q_Q(QQuickWebEngineView);
+ emit q->windowCloseRequested();
}
-void QQuickWebEngineViewPrivate::requestFullScreen(bool fullScreen)
+void QQuickWebEngineViewPrivate::windowCloseRejected()
+{
+#ifdef ENABLE_QML_TESTSUPPORT_API
+ if (m_testSupport)
+ Q_EMIT m_testSupport->windowCloseRejected();
+#endif
+}
+
+void QQuickWebEngineViewPrivate::requestFullScreenMode(const QUrl &origin, bool fullscreen)
{
Q_Q(QQuickWebEngineView);
- QQuickWebEngineFullScreenRequest request(this, fullScreen);
+ QQuickWebEngineFullScreenRequest request(this, origin, fullscreen);
Q_EMIT q->fullScreenRequested(request);
}
-bool QQuickWebEngineViewPrivate::isFullScreen() const
+bool QQuickWebEngineViewPrivate::isFullScreenMode() const
{
return m_isFullScreen;
}
@@ -444,6 +534,11 @@ void QQuickWebEngineViewPrivate::javaScriptConsoleMessage(JavaScriptConsoleMessa
Q_EMIT q->javaScriptConsoleMessage(static_cast<QQuickWebEngineView::JavaScriptConsoleMessageLevel>(level), message, lineNumber, sourceID);
}
+void QQuickWebEngineViewPrivate::authenticationRequired(QSharedPointer<AuthenticationDialogController> controller)
+{
+ ui()->showDialog(controller);
+}
+
void QQuickWebEngineViewPrivate::runMediaAccessPermissionRequest(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags requestFlags)
{
Q_Q(QQuickWebEngineView);
@@ -581,7 +676,7 @@ QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent)
Q_D(QQuickWebEngineView);
d->e->q_ptr = d->q_ptr = this;
this->setActiveFocusOnTab(true);
- this->setFlag(QQuickItem::ItemIsFocusScope);
+ this->setFlags(QQuickItem::ItemIsFocusScope | QQuickItem::ItemAcceptsInputMethod);
#ifndef QT_NO_ACCESSIBILITY
QQuickAccessibleAttached *accessible = QQuickAccessibleAttached::qmlAttachedProperties(this);
@@ -754,8 +849,23 @@ void QQuickWebEngineView::setTestSupport(QQuickWebEngineTestSupport *testSupport
Q_D(QQuickWebEngineView);
d->m_testSupport = testSupport;
}
+
#endif
+/*!
+ * \qmlproperty bool WebEngineView::activeFocusOnPress
+ * \since QtWebEngine 1.2
+ *
+ * This property specifies whether the view should gain active focus when pressed.
+ * The default value is true.
+ *
+ */
+bool QQuickWebEngineView::activeFocusOnPress() const
+{
+ Q_D(const QQuickWebEngineView);
+ return d->m_activeFocusOnPress;
+}
+
void QQuickWebEngineViewPrivate::didRunJavaScript(quint64 requestId, const QVariant &result)
{
Q_Q(QQuickWebEngineView);
@@ -774,6 +884,11 @@ void QQuickWebEngineViewPrivate::didFindText(quint64 requestId, int matchCount)
}
void QQuickWebEngineViewPrivate::showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText)
{
+#ifdef ENABLE_QML_TESTSUPPORT_API
+ if (m_testSupport)
+ Q_EMIT m_testSupport->validationMessageShown(mainText, subText);
+#endif
+
ui()->showMessageBubble(anchor, mainText, subText);
}
@@ -787,6 +902,14 @@ void QQuickWebEngineViewPrivate::moveValidationMessage(const QRect &anchor)
ui()->moveMessageBubble(anchor);
}
+void QQuickWebEngineViewPrivate::renderProcessTerminated(
+ RenderProcessTerminationStatus terminationStatus, int exitCode)
+{
+ Q_Q(QQuickWebEngineView);
+ Q_EMIT q->renderProcessTerminated(static_cast<QQuickWebEngineView::RenderProcessTerminationStatus>(
+ renderProcessExitStatus(terminationStatus)), exitCode);
+}
+
bool QQuickWebEngineView::isLoading() const
{
Q_D(const QQuickWebEngineView);
@@ -849,6 +972,34 @@ qreal QQuickWebEngineView::zoomFactor() const
return d->adapter->currentZoomFactor();
}
+/*!
+ \qmlproperty bool WebEngineView::backgroundColor
+ \since QtWebEngine 1.2
+
+ Sets this property to change the color of the WebEngineView's background,
+ behing the document's body. You can set it to "transparent" or to a translucent
+ color to see through the document, or you can set this color to match your
+ web content in an hybrid app to prevent the white flashes that may appear
+ during loading.
+
+ The default value is white.
+*/
+QColor QQuickWebEngineView::backgroundColor() const
+{
+ Q_D(const QQuickWebEngineView);
+ return d->m_backgroundColor;
+}
+
+void QQuickWebEngineView::setBackgroundColor(const QColor &color)
+{
+ Q_D(QQuickWebEngineView);
+ if (color == d->m_backgroundColor)
+ return;
+ d->m_backgroundColor = color;
+ d->ensureContentsAdapter();
+ d->adapter->backgroundColorChanged();
+ emit backgroundColorChanged();
+}
bool QQuickWebEngineView::isFullScreen() const
{
@@ -943,6 +1094,16 @@ void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQu
}
}
+void QQuickWebEngineView::setActiveFocusOnPress(bool arg)
+{
+ Q_D(QQuickWebEngineView);
+ if (d->m_activeFocusOnPress == arg)
+ return;
+
+ d->m_activeFocusOnPress = arg;
+ emit activeFocusOnPressChanged(arg);
+}
+
void QQuickWebEngineView::goBackOrForward(int offset)
{
Q_D(QQuickWebEngineView);
@@ -988,6 +1149,171 @@ void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &va
QQuickItem::itemChange(change, value);
}
+void QQuickWebEngineView::triggerWebAction(WebAction action)
+{
+ Q_D(QQuickWebEngineView);
+ switch (action) {
+ case Back:
+ d->adapter->navigateToOffset(-1);
+ break;
+ case Forward:
+ d->adapter->navigateToOffset(1);
+ break;
+ case Stop:
+ d->adapter->stop();
+ break;
+ case Reload:
+ d->adapter->reload();
+ break;
+ case ReloadAndBypassCache:
+ d->adapter->reloadAndBypassCache();
+ break;
+ case Cut:
+ d->adapter->cut();
+ break;
+ case Copy:
+ d->adapter->copy();
+ break;
+ case Paste:
+ d->adapter->paste();
+ break;
+ case Undo:
+ d->adapter->undo();
+ break;
+ case Redo:
+ d->adapter->redo();
+ break;
+ case SelectAll:
+ d->adapter->selectAll();
+ break;
+ case PasteAndMatchStyle:
+ d->adapter->pasteAndMatchStyle();
+ break;
+ case OpenLinkInThisWindow:
+ if (d->contextMenuData.linkUrl.isValid())
+ setUrl(d->contextMenuData.linkUrl);
+ break;
+ case OpenLinkInNewWindow:
+ if (d->contextMenuData.linkUrl.isValid()) {
+ QQuickWebEngineNewViewRequest request;
+ request.m_requestedUrl = d->contextMenuData.linkUrl;
+ request.m_isUserInitiated = true;
+ request.m_destination = NewViewInWindow;
+ Q_EMIT newViewRequested(&request);
+ }
+ break;
+ case OpenLinkInNewTab:
+ if (d->contextMenuData.linkUrl.isValid()) {
+ QQuickWebEngineNewViewRequest request;
+ request.m_requestedUrl = d->contextMenuData.linkUrl;
+ request.m_isUserInitiated = true;
+ request.m_destination = NewViewInBackgroundTab;
+ Q_EMIT newViewRequested(&request);
+ }
+ break;
+ case CopyLinkToClipboard:
+ if (d->contextMenuData.linkUrl.isValid()) {
+ QString urlString = d->contextMenuData.linkUrl.toString(QUrl::FullyEncoded);
+ QString title = d->contextMenuData.linkText.toHtmlEscaped();
+ QMimeData *data = new QMimeData();
+ data->setText(urlString);
+ QString html = QStringLiteral("<a href=\"") + urlString + QStringLiteral("\">") + title + QStringLiteral("</a>");
+ data->setHtml(html);
+ data->setUrls(QList<QUrl>() << d->contextMenuData.linkUrl);
+ qApp->clipboard()->setMimeData(data);
+ }
+ break;
+ case DownloadLinkToDisk:
+ if (d->contextMenuData.linkUrl.isValid())
+ d->adapter->download(d->contextMenuData.linkUrl, d->contextMenuData.suggestedFileName);
+ break;
+ case CopyImageToClipboard:
+ if (d->contextMenuData.hasImageContent &&
+ (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeImage ||
+ d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas))
+ {
+ d->adapter->copyImageAt(d->contextMenuData.pos);
+ }
+ break;
+ case CopyImageUrlToClipboard:
+ if (d->contextMenuData.mediaUrl.isValid() && d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeImage) {
+ QString urlString = d->contextMenuData.mediaUrl.toString(QUrl::FullyEncoded);
+ QString title = d->contextMenuData.linkText;
+ if (!title.isEmpty())
+ title = QStringLiteral(" alt=\"%1\"").arg(title.toHtmlEscaped());
+ QMimeData *data = new QMimeData();
+ data->setText(urlString);
+ QString html = QStringLiteral("<img src=\"") + urlString + QStringLiteral("\"") + title + QStringLiteral("></img>");
+ data->setHtml(html);
+ data->setUrls(QList<QUrl>() << d->contextMenuData.mediaUrl);
+ qApp->clipboard()->setMimeData(data);
+ }
+ break;
+ case DownloadImageToDisk:
+ case DownloadMediaToDisk:
+ if (d->contextMenuData.mediaUrl.isValid())
+ d->adapter->download(d->contextMenuData.mediaUrl, d->contextMenuData.suggestedFileName);
+ break;
+ case CopyMediaUrlToClipboard:
+ if (d->contextMenuData.mediaUrl.isValid() &&
+ (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeAudio ||
+ d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeVideo))
+ {
+ QString urlString = d->contextMenuData.mediaUrl.toString(QUrl::FullyEncoded);
+ QMimeData *data = new QMimeData();
+ data->setText(urlString);
+ if (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeAudio)
+ data->setHtml(QStringLiteral("<audio src=\"") + urlString + QStringLiteral("\"></audio>"));
+ else
+ data->setHtml(QStringLiteral("<video src=\"") + urlString + QStringLiteral("\"></video>"));
+ data->setUrls(QList<QUrl>() << d->contextMenuData.mediaUrl);
+ qApp->clipboard()->setMimeData(data);
+ }
+ break;
+ case ToggleMediaControls:
+ if (d->contextMenuData.mediaUrl.isValid() && d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) {
+ bool enable = !(d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaControls);
+ d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerControls, enable);
+ }
+ break;
+ case ToggleMediaLoop:
+ if (d->contextMenuData.mediaUrl.isValid() &&
+ (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeAudio ||
+ d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeVideo))
+ {
+ bool enable = !(d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaLoop);
+ d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerLoop, enable);
+ }
+ break;
+ case ToggleMediaPlayPause:
+ if (d->contextMenuData.mediaUrl.isValid() &&
+ (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeAudio ||
+ d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeVideo))
+ {
+ bool enable = (d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaPaused);
+ d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerPlay, enable);
+ }
+ break;
+ case ToggleMediaMute:
+ if (d->contextMenuData.mediaUrl.isValid() && d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) {
+ bool enable = (d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaMuted);
+ d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerMute, enable);
+ }
+ break;
+ case InspectElement:
+ d->adapter->inspectElementAt(d->contextMenuData.pos);
+ break;
+ case ExitFullScreen:
+ d->adapter->exitFullScreen();
+ break;
+ case RequestClose:
+ d->adapter->requestClose();
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+}
+
void QQuickWebEngineViewPrivate::userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script)
{
Q_ASSERT(p && p->data);
@@ -1036,8 +1362,9 @@ QQuickWebEngineFullScreenRequest::QQuickWebEngineFullScreenRequest()
{
}
-QQuickWebEngineFullScreenRequest::QQuickWebEngineFullScreenRequest(QQuickWebEngineViewPrivate *viewPrivate, bool toggleOn)
+QQuickWebEngineFullScreenRequest::QQuickWebEngineFullScreenRequest(QQuickWebEngineViewPrivate *viewPrivate, const QUrl &origin, bool toggleOn)
: viewPrivate(viewPrivate)
+ , m_origin(origin)
, m_toggleOn(toggleOn)
{
}
@@ -1046,10 +1373,18 @@ void QQuickWebEngineFullScreenRequest::accept()
{
if (viewPrivate && viewPrivate->m_isFullScreen != m_toggleOn) {
viewPrivate->m_isFullScreen = m_toggleOn;
+ viewPrivate->adapter->changedFullScreen();
Q_EMIT viewPrivate->q_ptr->isFullScreenChanged();
}
}
+void QQuickWebEngineFullScreenRequest::reject()
+{
+ if (viewPrivate) {
+ viewPrivate->adapter->changedFullScreen();
+ }
+}
+
QQuickWebEngineViewExperimental::QQuickWebEngineViewExperimental(QQuickWebEngineViewPrivate *viewPrivate)
: q_ptr(0)
, d_ptr(viewPrivate)
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index f85bf64ad..ddc656a58 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -71,19 +71,25 @@ class QQuickWebEngineTestSupport;
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineFullScreenRequest {
Q_GADGET
+ Q_PROPERTY(QUrl origin READ origin)
Q_PROPERTY(bool toggleOn READ toggleOn)
public:
QQuickWebEngineFullScreenRequest();
- QQuickWebEngineFullScreenRequest(QQuickWebEngineViewPrivate *viewPrivate, bool toggleOn);
+ QQuickWebEngineFullScreenRequest(QQuickWebEngineViewPrivate *viewPrivate, const QUrl &origin, bool toggleOn);
Q_INVOKABLE void accept();
- bool toggleOn() { return m_toggleOn; }
+ Q_INVOKABLE void reject();
+ QUrl origin() const { return m_origin; }
+ bool toggleOn() const { return m_toggleOn; }
private:
QQuickWebEngineViewPrivate *viewPrivate;
- bool m_toggleOn;
+ const QUrl m_origin;
+ const bool m_toggleOn;
};
+#define LATEST_WEBENGINEVIEW_REVISION 2
+
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
Q_OBJECT
Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
@@ -100,6 +106,8 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
Q_PROPERTY(QQuickWebEngineHistory *navigationHistory READ navigationHistory CONSTANT FINAL REVISION 1)
Q_PROPERTY(QQmlWebChannel *webChannel READ webChannel WRITE setWebChannel NOTIFY webChannelChanged REVISION 1)
Q_PROPERTY(QQmlListProperty<QQuickWebEngineScript> userScripts READ userScripts FINAL REVISION 1)
+ Q_PROPERTY(bool activeFocusOnPress READ activeFocusOnPress WRITE setActiveFocusOnPress NOTIFY activeFocusOnPressChanged REVISION 2)
+ Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged REVISION 2)
#ifdef ENABLE_QML_TESTSUPPORT_API
Q_PROPERTY(QQuickWebEngineTestSupport *testSupport READ testSupport WRITE setTestSupport FINAL)
@@ -112,7 +120,9 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
Q_ENUMS(NewViewDestination);
Q_ENUMS(Feature);
Q_ENUMS(JavaScriptConsoleMessageLevel);
+ Q_ENUMS(RenderProcessTerminationStatus);
Q_FLAGS(FindFlags);
+ Q_ENUMS(WebAction);
public:
QQuickWebEngineView(QQuickItem *parent = 0);
@@ -129,6 +139,8 @@ public:
bool isFullScreen() const;
qreal zoomFactor() const;
void setZoomFactor(qreal arg);
+ QColor backgroundColor() const;
+ void setBackgroundColor(const QColor &color);
QQuickWebEngineViewExperimental *experimental() const;
@@ -181,6 +193,48 @@ public:
Geolocation
};
+ enum WebAction {
+ NoWebAction = - 1,
+ Back,
+ Forward,
+ Stop,
+ Reload,
+
+ Cut,
+ Copy,
+ Paste,
+
+ Undo,
+ Redo,
+ SelectAll,
+ ReloadAndBypassCache,
+
+ PasteAndMatchStyle,
+
+ OpenLinkInThisWindow,
+ OpenLinkInNewWindow,
+ OpenLinkInNewTab,
+ CopyLinkToClipboard,
+ DownloadLinkToDisk,
+
+ CopyImageToClipboard,
+ CopyImageUrlToClipboard,
+ DownloadImageToDisk,
+
+ CopyMediaUrlToClipboard,
+ ToggleMediaControls,
+ ToggleMediaLoop,
+ ToggleMediaPlayPause,
+ ToggleMediaMute,
+ DownloadMediaToDisk,
+
+ InspectElement,
+ ExitFullScreen,
+ RequestClose,
+
+ WebActionCount
+ };
+
// must match WebContentsAdapterClient::JavaScriptConsoleMessageLevel
enum JavaScriptConsoleMessageLevel {
InfoMessageLevel = 0,
@@ -188,6 +242,14 @@ public:
ErrorMessageLevel
};
+ // must match WebContentsAdapterClient::RenderProcessTerminationStatus
+ enum RenderProcessTerminationStatus {
+ NormalTerminationStatus = 0,
+ AbnormalTerminationStatus,
+ CrashedTerminationStatus,
+ KilledTerminationStatus
+ };
+
enum FindFlag {
FindBackward = 1,
FindCaseSensitively = 2,
@@ -211,6 +273,8 @@ public:
void setTestSupport(QQuickWebEngineTestSupport *testSupport);
#endif
+ bool activeFocusOnPress() const;
+
public Q_SLOTS:
void runJavaScript(const QString&, const QJSValue & = QJSValue());
void loadHtml(const QString &html, const QUrl &baseUrl = QUrl());
@@ -223,6 +287,8 @@ public Q_SLOTS:
Q_REVISION(1) void findText(const QString &subString, FindFlags options = 0, const QJSValue &callback = QJSValue());
Q_REVISION(1) void fullScreenCancelled();
Q_REVISION(1) void grantFeaturePermission(const QUrl &securityOrigin, Feature, bool granted);
+ Q_REVISION(2) void setActiveFocusOnPress(bool arg);
+ Q_REVISION(2) void triggerWebAction(WebAction action);
Q_SIGNALS:
void titleChanged();
@@ -241,7 +307,10 @@ Q_SIGNALS:
Q_REVISION(1) void zoomFactorChanged(qreal arg);
Q_REVISION(1) void profileChanged();
Q_REVISION(1) void webChannelChanged();
-
+ Q_REVISION(2) void activeFocusOnPressChanged(bool);
+ Q_REVISION(2) void backgroundColorChanged();
+ Q_REVISION(2) void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode);
+ Q_REVISION(2) void windowCloseRequested();
protected:
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 60aa0d9f4..c2210850f 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -134,6 +134,7 @@ public:
virtual void selectionChanged() Q_DECL_OVERRIDE { }
virtual QRectF viewportRect() const Q_DECL_OVERRIDE;
virtual qreal dpiScale() const Q_DECL_OVERRIDE;
+ virtual QColor backgroundColor() const Q_DECL_OVERRIDE;
virtual void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) Q_DECL_OVERRIDE;
virtual void loadCommitted() Q_DECL_OVERRIDE;
virtual void loadVisuallyCommitted() Q_DECL_OVERRIDE;
@@ -142,19 +143,20 @@ public:
virtual void unhandledKeyEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
virtual void adoptNewWindow(QtWebEngineCore::WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &) Q_DECL_OVERRIDE;
virtual void close() Q_DECL_OVERRIDE;
- virtual void requestFullScreen(bool) Q_DECL_OVERRIDE;
- virtual bool isFullScreen() const Q_DECL_OVERRIDE;
+ virtual void windowCloseRejected() Q_DECL_OVERRIDE;
+ virtual void requestFullScreenMode(const QUrl &origin, bool fullscreen) Q_DECL_OVERRIDE;
+ virtual bool isFullScreenMode() const Q_DECL_OVERRIDE;
virtual bool contextMenuRequested(const QtWebEngineCore::WebEngineContextMenuData &) Q_DECL_OVERRIDE;
virtual void navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) Q_DECL_OVERRIDE;
virtual void javascriptDialog(QSharedPointer<QtWebEngineCore::JavaScriptDialogController>) Q_DECL_OVERRIDE;
- virtual void runFileChooser(FileChooserMode, const QString &defaultFileName, const QStringList &acceptedMimeTypes) Q_DECL_OVERRIDE;
+ virtual void runFileChooser(QtWebEngineCore::FilePickerController *controller) Q_DECL_OVERRIDE;
virtual void didRunJavaScript(quint64, const QVariant&) Q_DECL_OVERRIDE;
virtual void didFetchDocumentMarkup(quint64, const QString&) Q_DECL_OVERRIDE { }
virtual void didFetchDocumentInnerText(quint64, const QString&) Q_DECL_OVERRIDE { }
virtual void didFindText(quint64, int) Q_DECL_OVERRIDE;
virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE;
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
- virtual void authenticationRequired(const QUrl&, const QString&, bool, const QString&, QString*, QString*) Q_DECL_OVERRIDE { }
+ virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE;
virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) Q_DECL_OVERRIDE;
virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) Q_DECL_OVERRIDE;
#ifndef QT_NO_ACCESSIBILITY
@@ -166,6 +168,8 @@ public:
virtual void showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText) Q_DECL_OVERRIDE;
virtual void hideValidationMessage() Q_DECL_OVERRIDE;
virtual void moveValidationMessage(const QRect &anchor) Q_DECL_OVERRIDE;
+ virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus,
+ int exitCode) Q_DECL_OVERRIDE;
virtual QtWebEngineCore::BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE;
@@ -190,11 +194,13 @@ public:
QQuickWebEngineTestSupport *m_testSupport;
#endif
QQmlComponent *contextMenuExtraItems;
+ QtWebEngineCore::WebEngineContextMenuData contextMenuData;
QUrl explicitUrl;
QUrl icon;
int loadProgress;
bool m_isFullScreen;
bool isLoading;
+ bool m_activeFocusOnPress;
qreal devicePixelRatio;
QMap<quint64, QJSValue> m_callbacks;
QList<QSharedPointer<CertificateErrorController> > m_certificateErrorControllers;
@@ -203,6 +209,7 @@ private:
QScopedPointer<QtWebEngineCore::UIDelegatesManager> m_uIDelegatesManager;
QList<QQuickWebEngineScript *> m_userScripts;
qreal m_dpiScale;
+ QColor m_backgroundColor;
};
#ifndef QT_NO_ACCESSIBILITY
diff --git a/src/webengine/api/qtwebengineglobal.cpp b/src/webengine/api/qtwebengineglobal.cpp
index 1c67e710e..07561be6e 100644
--- a/src/webengine/api/qtwebengineglobal.cpp
+++ b/src/webengine/api/qtwebengineglobal.cpp
@@ -47,6 +47,17 @@ Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
namespace QtWebEngine {
+/*!
+ \namespace QtWebEngine
+ \inmodule QtWebEngine
+ \ingroup qtwebengine-namespaces
+ \keyword QtWebEngine Namespace
+
+ \brief Helper functions for the Qt WebEngine (Qt Quick) module
+
+ The \l[CPP]{QtWebEngine} namespace is part of the Qt WebEngine module.
+*/
+
static QOpenGLContext *shareContext;
static void deleteShareContext()
@@ -59,6 +70,16 @@ static void deleteShareContext()
// QtWebEngine::initialize was introduced first and meant to be called
// after the QGuiApplication creation, when AA_ShareOpenGLContexts fills
// the same need but the flag has to be set earlier.
+
+/*!
+ \fn QtWebEngine::initialize()
+
+ Sets up an OpenGL Context that can be shared between processes. This has to be done after
+ QGuiApplication is created, but before a Qt Quick window is created.
+
+ This has the same effect as passing Qt::AA_ShareOpenGLContexts to the QGuiApplication
+ constructor.
+*/
void initialize()
{
#ifdef Q_OS_WIN32
@@ -71,11 +92,11 @@ void initialize()
QCoreApplication *app = QCoreApplication::instance();
if (!app) {
- qFatal("QWebEngine(Widgets)::initialize() must be called after the construction of the application object.");
+ qFatal("QtWebEngine::initialize() must be called after the construction of the application object.");
return;
}
if (app->thread() != QThread::currentThread()) {
- qFatal("QWebEngine(Widgets)::initialize() must be called from the Qt gui thread.");
+ qFatal("QtWebEngine::initialize() must be called from the Qt gui thread.");
return;
}
@@ -86,6 +107,9 @@ void initialize()
shareContext->create();
qAddPostRoutine(deleteShareContext);
qt_gl_set_global_share_context(shareContext);
+
+ // Classes like QOpenGLWidget check for the attribute
+ app->setAttribute(Qt::AA_ShareOpenGLContexts);
}
} // namespace QtWebEngine
diff --git a/src/webengine/doc/images/qtwebengine-architecture.png b/src/webengine/doc/images/qtwebengine-architecture.png
new file mode 100644
index 000000000..37ca2da16
--- /dev/null
+++ b/src/webengine/doc/images/qtwebengine-architecture.png
Binary files differ
diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf
index ad6898440..01485dc56 100644
--- a/src/webengine/doc/qtwebengine.qdocconf
+++ b/src/webengine/doc/qtwebengine.qdocconf
@@ -4,7 +4,7 @@ project = QtWebEngine
description = Qt WebEngine Reference Documentation
version = $QT_VERSION
-examplesinstallpath = webengine
+examplesinstallpath = qtwebengine
qhp.projects = QtWebEngine
@@ -17,23 +17,54 @@ qhp.QtWebEngine.indexRoot =
qhp.QtWebEngine.filterAttributes = qtwebengine $QT_VERSION qtrefdoc
qhp.QtWebEngine.customFilters.Qt.name = QtWebEngine $QT_VERSION
qhp.QtWebEngine.customFilters.Qt.filterAttributes = qtwebengine $QT_VERSION
-qhp.QtWebEngine.subprojects = qmltypes examples
+
+qhp.QtWebEngine.subprojects = classes qmltypes examples
+
+qhp.QtWebEngine.subprojects.classes.title = C++ Classes
+qhp.QtWebEngine.subprojects.classes.indexTitle = Qt WebEngine C++ Classes
+qhp.QtWebEngine.subprojects.classes.selectors = class doc:headerfile
+qhp.QtWebEngine.subprojects.classes.sortPages = true
+
qhp.QtWebEngine.subprojects.qmltypes.title = QML Types
qhp.QtWebEngine.subprojects.qmltypes.indexTitle = Qt WebEngine QML Types
-qhp.QtWebEngine.subprojects.qmltypes.selectors = qmlclass
+qhp.QtWebEngine.subprojects.qmltypes.selectors = qmltype
qhp.QtWebEngine.subprojects.qmltypes.sortPages = true
+
qhp.QtWebEngine.subprojects.examples.title = Examples
qhp.QtWebEngine.subprojects.examples.indexTitle = Qt WebEngine Examples
-qhp.QtWebEngine.subprojects.examples.selectors = fake:example
+qhp.QtWebEngine.subprojects.examples.selectors = doc:example
qhp.QtWebEngine.subprojects.examples.sortPages = true
tagfile = ../../../doc/qtwebengine/qtwebengine.tags
-depends += qtcore qtgui qtquick qtquickcontrols qtdoc
+depends += qtcore \
+ qtgui \
+ qtqml \
+ qtquick \
+ qtquickcontrols \
+ qtdoc \
+ qtwebchannel \
+ qtwidgets
+
+headerdirs += .. \
+ ../../core \
+ ../../webenginewidgets
-headerdirs += . ../api
-sourcedirs += . ../api
-exampledirs += ../../../examples/webengine .
+sourcedirs += .. \
+ ../../core/ \
+ ../../webenginewidgets \
+
+exampledirs += . \
+ ../../../examples \
+ snippets \
+ ../../core/doc/snippets \
+ ../../webenginewidgets/doc/snippets
+
+
+imagedirs += images
navigation.landingpage = "Qt WebEngine"
+navigation.cppclassespage = "Qt WebEngine C++ Classes"
navigation.qmltypespage = "Qt WebEngine QML Types"
+
+Cpp.ignoretokens += Q_WEBENGINE_EXPORT QWEBENGINEWIDGETS_EXPORT
diff --git a/src/webengine/doc/src/external-resources.qdoc b/src/webengine/doc/src/external-resources.qdoc
new file mode 100644
index 000000000..34a66291e
--- /dev/null
+++ b/src/webengine/doc/src/external-resources.qdoc
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \externalpage http://www.chromium.org
+ \title Chromium Project
+*/
+
+/*!
+ \externalpage https://developers.google.com/web/tools/chrome-devtools
+ \title Chrome DevTools
+*/
+
+/*
+ This prevents autolinking of each occurrence of 'WebEngine'
+ To link to the WebEngine QML type, use explicit linking:
+ \l [QML] WebEngine
+ \sa {QtWebEngine::}{WebEngine}
+*/
+/*!
+ \externalpage nolink
+ \title WebEngine
+ \internal
+*/
diff --git a/src/webengine/doc/src/qtwebengine-devtools.qdoc b/src/webengine/doc/src/qtwebengine-devtools.qdoc
new file mode 100644
index 000000000..ee87214e1
--- /dev/null
+++ b/src/webengine/doc/src/qtwebengine-devtools.qdoc
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page qtwebengine-devtools.html
+ \title Qt WebEngine Web Developer Tools
+
+ The Qt WebEngine module provides web developer tools that make it easy
+ to inspect and debug layout and performance issues of any web content.
+
+ The developer tools are accessed as a local web page using a Chromium or
+ Qt WebEngine based browser, such as the Chrome browser.
+
+ To activate the developer tools, start an application that uses Qt
+ WebEngine with the command-line arguments:
+
+ \badcode
+ --remote-debugging-port=<port_number>
+ \endcode
+
+ Where \c <port_number> refers to a local network port. The web developer
+ tools can then be accessed by launching a browser at the address
+ \c http://localhost:<port_number>.
+
+ Alternatively, the environment variable QTWEBENGINE_REMOTE_DEBUGGING
+ can be set. It can be set as either just a port working similarly to
+ \c --remote-debugging-port or given both a host address and a port. The
+ latter can be used to control which network interface to export the
+ interface on, so that you can access the developer tools from a remote
+ device.
+
+ For a detailed explanation of the capabilities of developer tools, see the
+ \l {Chrome DevTools} page.
+*/
diff --git a/src/webengine/doc/src/qtwebengine.qdoc b/src/webengine/doc/src/qtwebengine-examples.qdoc
index e381178f6..ec49577e4 100644
--- a/src/webengine/doc/src/qtwebengine.qdoc
+++ b/src/webengine/doc/src/qtwebengine-examples.qdoc
@@ -24,22 +24,6 @@
*/
/*!
- \qmlmodule QtWebEngine 1.1
- \title Qt WebEngine QML Types
- \brief Provides QML types for rendering web content within a QML application
-
- The QML types can be imported into your application using the following
- import statement in your .qml file:
-
- \code
- import QtQuick 2.0
- import QtWebEngine 1.1
- \endcode
-
- \sa {Qt WebEngine Examples}
-*/
-
-/*!
\group webengine-examples
\title Qt WebEngine Examples
\brief Examples demonstrating the Qt WebEngine usage
@@ -49,5 +33,6 @@
from displaying Web pages within a QML user interface to an implementation of
a basic function Web browser.
- \sa {Qt WebEngine QML Types}
+ For widget-based applications, Qt provides an integrated Web browser component based on
+ Chromium, the popular open source browser engine.
*/
diff --git a/src/webengine/doc/src/qtwebengine-index.qdoc b/src/webengine/doc/src/qtwebengine-index.qdoc
new file mode 100644
index 000000000..e67bd43fd
--- /dev/null
+++ b/src/webengine/doc/src/qtwebengine-index.qdoc
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page qtwebengine-index.html
+ \title Qt WebEngine
+ \ingroup modules
+
+ \brief Provides functionality for rendering regions of dynamic web content.
+
+ \e {Qt WebEngine} provides functionality for rendering regions of dynamic web content.
+
+ The functionality in Qt WebEngine is divided into the following modules:
+
+ \annotatedlist qtwebengine-modules
+
+ For Qt Quick applications, Qt WebEngine provides the following QML modules:
+
+ \annotatedlist qtwebengine-qmlmodules
+
+ \section1 Getting Started
+
+ To include the definitions of the Qt WebEngineCore and Qt WebEngineWidgets modules' classes, use
+ the following directives:
+
+ \badcode
+ #include <QtWebEngineCore>
+ #include <QtWebEngineWidgets>
+ \endcode
+
+ To import the Qt WebEngine module's QML types, add the following import statement to your .qml
+ file:
+
+ \badcode
+ import QtWebEngine 1.2
+ \endcode
+
+ To link against the modules, add QT variables to your qmake .pro file:
+
+ \badcode
+ QT += webengine webenginecore webenginewidgets
+ \endcode
+
+ \section1 Articles and Guides
+
+ \list
+ \li \l{Qt WebEngine Overview}
+ \li \l{Qt WebEngine Platform Notes}
+ \li \l{Qt WebEngine Web Developer Tools}
+ \li \l{Porting from Qt WebKit to Qt WebEngine}
+ \endlist
+
+ \section1 Examples
+
+ \list
+ \li \l{Qt WebEngine Examples}
+ \li \l{Qt WebEngine Widgets Examples}
+ \endlist
+
+ \section1 API References
+
+ \list
+ \li \l{Qt WebEngine C++ Classes}
+ \li \l{Qt WebEngine QML Types}
+ \endlist
+*/
diff --git a/src/webengine/doc/src/qtwebengine-modules.qdoc b/src/webengine/doc/src/qtwebengine-modules.qdoc
new file mode 100644
index 000000000..8530f5d01
--- /dev/null
+++ b/src/webengine/doc/src/qtwebengine-modules.qdoc
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page qtwebengine-modules.html
+ \title Qt WebEngine C++ Classes
+ \brief Provides functionality for rendering regions of dynamic web content.
+
+ \e {Qt WebEngine} provides functionality for rendering regions of dynamic web content.
+
+ \section1 Namespaces
+ \annotatedlist qtwebengine-namespaces
+
+ \section1 Classes
+
+ \section2 Qt WebEngineCore Module
+ \generatelist {classesbymodule QtWebEngineCore}
+
+ \section2 Qt WebEngineWidgets Module
+ \generatelist {classesbymodule QtWebEngineWidgets}
+*/
diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc
new file mode 100644
index 000000000..fa30892d3
--- /dev/null
+++ b/src/webengine/doc/src/qtwebengine-overview.qdoc
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page qtwebengine-overview.html
+ \title Qt WebEngine Overview
+
+ The Qt WebEngine module provides a web browser engine that makes it easy to embed content from
+ the World Wide Web into your Qt application on platforms that do not have a native web engine.
+ The web engine is not intended to function as a \e {Web Runtime}; to display web content in a
+ QML application by using APIs native to the platform, use the \l{Qt WebView} module, instead.
+
+ Qt WebEngine provides C++ classes and QML types for rendering HTML, XHTML, and SVG documents,
+ styled using Cascading Style Sheets (CSS) and scripted with JavaScript. HTML documents can be
+ made fully editable by the user through the use of the \c{contenteditable} attribute on HTML
+ elements.
+
+ Qt WebEngine supercedes the \l{http://doc.qt.io/archives/qt-5.3/qtwebkit-index.html}{Qt WebKit}
+ module, which is based on the
+ WebKit project, but has not been actively synchronized with the upstream WebKit code since
+ Qt 5.2 and has been deprecated in Qt 5.5. For tips on how to change a Qt WebKit widgets
+ application to use Qt WebEngine widgets, see \l{Porting from Qt WebKit to Qt WebEngine}. For new
+ applications, we recommend using Qt Quick and the WebEngineView QML type.
+
+ \section1 Qt WebEngine Architecture
+
+ \image qtwebengine-architecture.png
+
+ The functionality in Qt WebEngine is divided into the following modules:
+
+ \list
+ \li \l{Qt WebEngine Widgets}, which provides a web browser engine and C++ classes to render
+ web content and to interact with it
+ \li \l{Qt WebEngine}, which provides QML types for rendering web content within a QML
+ application
+ \li \l{Qt WebEngine Core}, which provides common API used by Qt WebEngine and
+ Qt WebEngine Widgets
+ \endlist
+
+ The Qt WebEngine core is based on the \l {Chromium Project}. Chromium provides its own network
+ and painting engines and is developed tightly together with its dependent modules, and
+ therefore Qt WebEngine provides better and more reliable support for the latest HTML5
+ specification than Qt WebKit. However, Qt WebEngine is thus heavier than Qt WebKit and does
+ not provide direct access to the network stack and the HTML document through C++ APIs.
+
+ Chromium is tightly integrated to the \l{Qt Quick Scene Graph}{Qt Quick scene graph}, which is
+ based on OpenGL ES 2.0 or OpenGL 2.0 for its rendering. This provides you with one-pass
+ compositing of web content and all the Qt Quick UI. The integration to Chromium is transparent
+ to developers, who just work with Qt and JavaScript.
+
+ To expose QObjects to JavaScript, developers can use the \l {Qt WebChannel} module.
+
+ \section1 Embedding Web Content into Widget Based Applications
+
+ Use the QWebEngineView class to display web pages in the simplest way. Because it is a widget,
+ you can embed QWebEngineView into your forms and use its convenience functions to download and
+ display web sites.
+
+ \code
+ QWebEngineView *view = new QWebEngineView(parent);
+ view->load(QUrl("http://www.qt.io/"));
+ view->show();
+ \endcode
+
+ An instance of QWebEngineView has one QWebEnginePage. QWebEnginePage provides access to the
+ page's navigation history and the ability to run JavaScript code in the context of the page's
+ main frame and enables customization of handlers for specific events like showing custom
+ authentication dialogs.
+
+ \section1 Embedding Web Content into Qt Quick Applications
+
+ The WebEngineView QML type allows QML applications to render regions of dynamic web content. A
+ \e{WebEngineView} type may share the screen with other QML types or encompass the full screen
+ as specified within the QML application.
+
+ An application can load pages into the WebEngineView, using either an URL or HTML string, and
+ navigate within session history. By default, links to different pages load within the same
+ WebEngineView object, but web sites may request them to be opened as a new tab, window, or
+ dialog.
+
+ The following sample QML application loads a web page and responds to session history context:
+
+ \qml
+ import QtQuick 2.1
+ import QtQuick.Controls 1.1
+ import QtWebEngine 1.1
+
+ ApplicationWindow {
+ width: 1280
+ height: 720
+ visible: true
+ WebEngineView {
+ id: webview
+ url: "http://www.qt.io"
+ anchors.fill: parent
+ }
+ }
+ \endqml
+
+ \section1 Using WebEngine Core
+
+ Qt WebEngine Core provides an API shared by Qt WebEngine and Qt WebEngine Widgets for handling
+ URL requests issued for the networking stack of Chromium and for accessing its HTTP cookies.
+
+ Implementing the QWebEngineUrlRequestInterceptor interface and installing the interceptor on a
+ profile enables intercepting, blocking, and modifying URL requests (QWebEngineUrlRequestInfo)
+ before they reach the networking stack of Chromium.
+
+ A QWebEngineUrlSchemeHandler can be registered for a profile to add support for custom URL
+ schemes. Requests for the scheme are then issued to QWebEngineUrlSchemeHandler::requestStarted()
+ as QWebEngineUrlRequestJob objects.
+
+ The QWebEngineCookieStoreClient class provides functions for accessing HTTP cookies of Chromium.
+ The functions can be used to synchronize cookies with QNetworkAccessManager, as well as to set,
+ delete, and intercept cookies during navigation.
+
+ \section1 License Information
+
+ Qt WebEngine module is a snapshot of the integration of Chromium into Qt.
+
+ Qt Commercial Edition licensees that wish to distribute applications that
+ use the Qt WebEngine module need to be aware of their obligations under the
+ GNU Library General Public License (LGPLv2).
+
+ Developers using the Open Source Edition can choose to redistribute
+ the module under the GNU LGPLv3 or GPLv2 and up.
+
+ \legalese
+
+ Chromium is licensed under the following license:
+
+ Copyright (c) 2013 The Chromium Authors. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Google Inc. nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ \endlegalese
+*/
diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
new file mode 100644
index 000000000..fdaa4f861
--- /dev/null
+++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page qtwebengine-platform-notes.html
+ \title Qt WebEngine Platform Notes
+
+ \brief Contains information about issues that are specific to the Qt WebEngine module.
+
+ \section1 Building Qt WebEngine from Source
+
+ The requirements for building Qt 5 modules from source are listed separately for each supported
+ platform:
+
+ \list
+ \li \l{Qt for Windows - Requirements}
+ \li \l{Qt for X11 Requirements}
+ \li \l{Qt for OS X - Requirements}
+ \endlist
+
+ In addition, the following tools are required for building the \l {Qt WebEngine} module:
+
+ \list
+ \li Windows: Visual Studio 2013 or Visual Studio 2015
+ \li Linux: Clang or GCC version 4.7 or later
+ \li OS X: Xcode version 5.1 or later
+ \endlist
+*/
diff --git a/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc
new file mode 100644
index 000000000..e098071b3
--- /dev/null
+++ b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc
@@ -0,0 +1,39 @@
+/*
+ Copyright (C) 2015 The Qt Company Ltd.
+ Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*!
+ \qmlmodule QtWebEngine 1.1
+ \title Qt WebEngine QML Types
+ \brief Provides QML types for rendering web content within a QML application
+ \ingroup qtwebengine-qmlmodules
+
+ The QML types can be imported into your application using the following import statements in
+ your .qml file:
+
+ \badcode
+ import QtQuick 2.0
+ import QtWebEngine 1.1
+ \endcode
+*/
diff --git a/src/webengine/doc/src/qquickwebengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview.qdoc
index 212d9010a..f230ba261 100644
--- a/src/webengine/doc/src/qquickwebengineview_lgpl.qdoc
+++ b/src/webengine/doc/src/webengineview.qdoc
@@ -24,54 +24,6 @@
// by its LGPL license.
/*!
- \page qtwebengine-index.html
- \title Qt WebEngine
-
- The Qt WebEngine module provides the WebEngineView API which allows QML applications
- to render regions of dynamic web content. A \e{WebEngineView} component may share
- the screen with other QML components or encompass the full screen as
- specified within the QML application.
-
- It allows an application to load pages into the WebEngineView, either by URL or with
- an HTML string, and navigate within session history. By default,
- links to different pages load within the same WebEngineView, but web sites may
- request them to be opened as a new tab, window or dialog.
-
- The following sample QML application loads a web page, responds to session
- history context.
-
- \code
- import QtQuick 2.1
- import QtQuick.Controls 1.1
- import QtWebEngine 1.1
-
- ApplicationWindow {
- width: 1280
- height: 720
- visible: true
- WebEngineView {
- id: webview
- url: "http://www.qt-project.org"
- anchors.fill: parent
- }
- }
- \endcode
-
- \section1 API References
-
- \list
- \li \l{Qt WebEngine QML Types}{QML Types}
- \endlist
-
- \section1 Examples
-
- There are several Qt WebEngine examples located in the
- \l{Qt WebEngine Examples} page.
-
-*/
-
-
-/*!
\qmltype WebEngineView
\instantiates QQuickWebEngineView
\inqmlmodule QtWebEngine 1.1
@@ -85,7 +37,7 @@
Go backward within the browser's session history, if possible.
This function is equivalent to the \c{window.history.back()} DOM method.
- \sa WebEngineView::canGoBack
+ \sa canGoBack
*/
/*!
@@ -103,7 +55,7 @@
pages in the current session history. If offset is negative, it goes
back. If the offset is invalid, the page is not changed.
- \sa WebEngineView::goBack, WebEngineView::goForward
+ \sa goBack(), goForward()
*/
/*!
@@ -118,32 +70,33 @@
Reloads the current page. This function is equivalent to the
\c{window.location.reload()} DOM method.
- \sa WebEngineView::reloadAndBypassCache
+ \sa reloadAndBypassCache()
*/
/*!
\qmlmethod void WebEngineView::reloadAndBypassCache()
+ \since QtWebEngine 1.1
Reloads the current page, ignoring any cached content.
- \sa WebEngineView::reload
+ \sa reload()
*/
/*!
\qmlproperty url WebEngineView::url
- The location of the currently displaying HTML page. This writable
+ The location of the currently displayed HTML page. This writable
property offers the main interface to load a page into a web view.
It functions the same as the \c{window.location} DOM property.
- \sa WebEngineView::loadHtml()
+ \sa loadHtml()
*/
/*!
\qmlproperty url WebEngineView::icon
\readonly
- This property holds the location of the currently displaying web site icon,
+ The location of the currently displayed web site icon,
also known as favicon or shortcut icon. This read-only URL corresponds to
the image used within a mobile browser application to represent a
bookmarked page on the device's home screen.
@@ -151,20 +104,20 @@
The following snippet uses the \c{icon} property to build an \c{Image}
component:
- \code
+ \qml
Image {
id: appIcon
source: webView.icon != "" ? webView.icon : "fallbackFavIcon.png";
- ...
+ // ...
}
- \endcode
+ \endqml
*/
/*!
\qmlproperty int WebEngineView::loadProgress
\readonly
- This property holds the amount of the page that has been loaded, expressed
+ The amount of data from the page that has been loaded, expressed
as an integer percentage in the range from \c{0} to \c{100}.
*/
@@ -195,7 +148,7 @@
\qmlproperty string WebEngineView::title
\readonly
- This property holds the title of the currently displaying HTML page, a
+ The title of the currently displayed HTML page. This is a
read-only value that reflects the contents of the \c{<title>} tag.
*/
@@ -206,7 +159,7 @@
Returns \c{true} if the web view is in fullscreen mode, \c{false} otherwise.
- \sa WebEngineView::fullScreenRequested, WebEngineView::fullScreenCancelled
+ \sa fullScreenRequested(), fullScreenCancelled()
*/
/*!
@@ -255,6 +208,7 @@
/*!
\qmlproperty list<WebEngineScript> WebEngineView::userScripts
\readonly
+ \since QtWebEngine 1.1
List of script objects attached to the view.
*/
@@ -269,31 +223,35 @@
/*!
\qmlmethod void WebEngineView::loadHtml(string html, url baseUrl)
- \brief Loads the specified \a html as the content of the web view.
+ Loads the specified \a html as the content of the web view.
This method offers a lower-level alternative to the \c{url} property,
which references HTML pages via URL.
- External objects such as stylesheets or images referenced in the HTML
- document should be located relative to \a baseUrl. For example, if \a html
+ External objects, such as stylesheets or images referenced in the HTML
+ document, should be located relative to \a baseUrl. For example, if \a html
is retrieved from \c http://www.example.com/documents/overview.html, which
- is the base url, then an image referenced with the relative url, \c diagram.png,
+ is the base URL, then an image referenced with the relative URL, \c diagram.png,
should be at \c{http://www.example.com/documents/diagram.png}.
- \sa WebEngineView::url
+ \sa url
*/
/*!
\qmlmethod void WebEngineView::runJavaScript(string script, variant callback)
- \brief Runs the specified \a script in the content of the web view.
+ Runs the specified \a script in the content of the web view.
- In case a callback function is provided it will be invoked after the script
- finished running.
+ In case a callback function is provided, it will be invoked after the script
+ finishes running.
\code
runJavaScript("document.title", function(result) { console.log(result); });
\endcode
+ The script will run in the same \e world as other scripts that are
+ part of the loaded site.
+
+ See WebEngineView::userScripts for an alternative API to inject scripts.
*/
/*!
@@ -336,12 +294,13 @@
*/
/*!
- \qmlmethod WebEngineView::grantFeaturePermission(url securityOrigin, Feature feature, bool granted)
+ \qmlmethod void WebEngineView::grantFeaturePermission(url securityOrigin, Feature feature, bool granted)
\since QtWebEngine 1.1
- Sets the permission for the web site identified by \a securityOrigin to use \a feature.
+ Sets or unsets the permission, depending on \a granted, for the web site
+ identified by \a securityOrigin to use \a feature.
- \sa WebEngineView::featurePermissionRequested
+ \sa featurePermissionRequested()
*/
@@ -352,7 +311,7 @@
Immediately sets \c{isFullScreen} property to \c{false}. It can be used to notify the
browser engine when the windowing system forces the application to leave fullscreen mode.
- \code
+ \qml
ApplicationWindow {
onVisibilityChanged: {
if (webEngineView.isFullScreen && visibility != Window.FullScreen)
@@ -361,30 +320,51 @@
WebEngineView {
id: webEngineView
- ...
+ // ...
}
}
- \endcode
+ \endqml
+
+ \sa isFullScreen, fullScreenRequested()
+*/
+
+/*!
+ \qmlmethod void WebEngineView::setActiveFocusOnPress(bool arg)
+ \since QtWebEngine 1.2
+
+ Sets active focus to a clicked web engine view if \a arg is \c true. By setting it to \c false,
+ a web engine view can be used to create a UI element that should not get focus. This can be
+ useful in a hybrid UI.
- \sa WebEngineView::isFullScreen, WebEngineView::fullScreenRequested
+ \sa activeFocusOnPressChanged()
+*/
+
+/*!
+ \qmlmethod void WebEngineView::triggerWebAction(WebAction action)
+ \since QtWebEngine 1.2
+
+ Triggers the web action \a action.
+
+ \sa WebAction
*/
/*!
\qmlsignal WebEngineView::featurePermissionRequested(url securityOrigin, Feature feature)
+ \since QtWebEngine 1.1
- This is signal is emitted when the web site identified by \a securityOrigin requests
+ This signal is emitted when the web site identified by \a securityOrigin requests
to make use of the resource or device identified by \a feature.
- \sa WebEngineView::grantFeaturePermission
+ \sa grantFeaturePermission()
*/
/*!
\qmlsignal WebEngineView::loadingChanged(loadRequest)
This signal is emitted when a page load begins, ends, or fails.
- The corresponding handler is onLoadingChanged.
+ The corresponding handler is \c onLoadingChanged.
- When handling the signal with onLoadingChanged, various read-only
+ When handling the signal with \c onLoadingChanged, various read-only
parameters are available on the \a loadRequest:
\table
@@ -396,10 +376,7 @@
\li The location of the resource that is loading.
\row
\li status
- \li Reflects one of four load states:
- \c{WebEngineView::LoadStartedStatus}, \c{WebEngineView::LoadStoppedStatus},
- \c{WebEngineView::LoadSucceededStatus}, or \c{WebEngineView::LoadFailedStatus}.
- See WebEngineLoadRequest::status and WebEngineView::LoadStatus.
+ \li The \l{LoadStatus}{load status} of the page.
\row
\li errorString
\li The description of load error.
@@ -408,13 +385,10 @@
\li The HTTP error code.
\row
\li errorDomain
- \li The high-level error types, one of
- \c{WebEngineView::ConnectionErrorDomain}, \c{WebEngineView::HttpErrorDomain}, \c{WebEngineView::InternalErrorDomain},
- \c{WebEngineView::DownloadErrorDomain}, or \c{WebEngineView::NoErrorDomain}. See
- \l{WebEngineView::ErrorDomain} for the full list.
+ \li The high-level \l{ErrorDomain}{error type}.
\endtable
- \sa WebEngineView::loading
+ \sa loading, LoadStatus, ErrorDomain
*/
/*!
@@ -426,14 +400,14 @@
The certificate error can be rejected by calling WebEngineCertificateError::rejectCertificate,
which will stop loading the request.
- The certificate error can be ignored by calling WebEngineCertificateError::ignoreCertificateError
- which will resume loading the request.
+ The certificate error can be ignored by calling
+ WebEngineCertificateError::ignoreCertificateError, which will resume loading the request.
It is possible to defer the decision of rejecting the given certificate by calling
WebEngineCertificateError::defer, which is useful when waiting for user input.
- By default the invalid certificate will be automatically rejected.
+ By default, the invalid certificate will be automatically rejected.
- The corresponding handler is onCertificateError.
+ The corresponding handler is \c onCertificateError.
\sa WebEngineCertificateError
*/
@@ -447,19 +421,20 @@
events that are not cancelled with \c{preventDefault()}. \a{hoveredUrl}
provides the link's location.
- The corresponding handler is onLinkHovered.
+ The corresponding handler is \c onLinkHovered.
*/
/*!
\qmlsignal WebEngineView::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, message, lineNumber, sourceID)
This signal is emitted when a JavaScript program tries to print a \a message to the web browser's console.
- For example in case of evaluation errors the source URL may be provided in \a sourceID as well as the \a lineNumber.
+ For example, in case of evaluation errors the source URL may be provided in \a sourceID as well
+ as the \a lineNumber.
- \a level indicates the severity of the event that triggered the message, i.e. if it
+ \a level indicates the severity of the event that triggered the message, that is, whether it
was triggered by an error or a less severe event.
- The corresponding handler is onJavaScriptConsoleMessage.
+ The corresponding handler is \c onJavaScriptConsoleMessage.
*/
/*!
@@ -467,20 +442,20 @@
\since QtWebEngine 1.1
This signal is emitted when a page load is requested to happen in a separate
- WebEngineView. This can either be because the current page requested it explicitly
- through a JavaScript call to window.open, or because the user clicked on a link
- while holding Shift, Ctrl or a built-in combination that triggers the page to open
+ web engine view. This can either be because the current page requested it explicitly
+ through a JavaScript call to \c window.open, or because the user clicked on a link
+ while holding Shift, Ctrl, or a built-in combination that triggers the page to open
in a new window.
- If this signal isn't handled the requested load will fail.
+ If this signal is not handled, the requested load will fail.
An example implementation:
\snippet snippets/qtwebengine_webengineview_newviewrequested.qml 0
- The corresponding handler is onNewViewRequested.
+ The corresponding handler is \c onNewViewRequested.
- \sa WebEngineNewViewRequest, WebEngineView::NewViewDestination, {WebEngine Quick Nano Browser}
+ \sa WebEngineNewViewRequest, NewViewDestination, {WebEngine Quick Nano Browser}
*/
/*!
@@ -490,15 +465,54 @@
This signal is emitted when the web page requests fullscreen mode through the
JavaScript API.
- The corresponding handler is onFullScreenRequested.
+ The corresponding handler is \c onFullScreenRequested.
- \sa WebEngineFullScreenRequest, WebEngineView::isFullScreen
+ \sa WebEngineFullScreenRequest, isFullScreen
+*/
+
+/*!
+ \qmlsignal WebEngineView::activeFocusOnPressChanged(bool)
+ \since QtWebEngine 1.2
+
+ This signal is emitted when the ability of the web engine view to get focus when clicked
+ changes.
+
+ \sa setActiveFocusOnPress()
+*/
+
+/*!
+ \qmlsignal WebEngineView::backgroundColorChanged()
+ \since QtWebEngine 1.2
+
+ This signal is emitted when the web engine view background color changes.
+*/
+
+/*!
+ \qmlsignal WebEngineView::renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode)
+
+ \since QtWebEngine 1.2
+
+ This signal is emitted when the render process is terminated with a non-zero exit status.
+ \a terminationStatus is the termination status of the process and \a exitCode is the status code
+ with which the process terminated.
+
+ \sa RenderProcessTerminationStatus
+*/
+
+/*!
+ \qmlsignal WebEngineView::windowCloseRequested()
+ \since QtWebEngine 1.2
+
+ This signal is emitted whenever the page requests the web browser window to be closed,
+ for example through the JavaScript \c{window.close()} call.
+
+ The corresponding handler is \c onWindowCloseRequested.
*/
/*!
\qmlproperty enumeration WebEngineView::ErrorDomain
- This enumeration details various high-level error types.
+ Describes various high-level error types:
\value WebEngineView::NoErrorDomain
\value WebEngineView::InternalErrorDomain
@@ -518,68 +532,42 @@
/*!
\qmlproperty enumeration WebEngineView::JavaScriptConsoleMessageLevel
- Indicates the severity of a JavaScript console message.
+ Indicates the severity of a JavaScript console message:
- \table
-
- \header
- \li Constant
- \li Description
-
- \row
- \li InfoMessageLevel
- \li Message is purely informative and should be safe to ignore.
-
- \row
- \li WarningMessageLevel
- \li Message indicates there might be a problem that may need attention.
-
- \row
- \li ErrorMessageLevel
- \li Message indicates there has been an error.
-
- \endtable
+ \value InfoMessageLevel
+ Message is purely informative and can safely be ignored.
+ \value WarningMessageLevel
+ Message indicates there might be a problem that may need attention.
+ \value ErrorMessageLevel
+ Message indicates there has been an error.
*/
/*!
\qmlproperty enumeration WebEngineView::LoadStatus
- Reflects a page's load status.
-
- \table
-
- \header
- \li Constant
- \li Description
-
- \row
- \li LoadStartedStatus
- \li Page is currently loading.
-
- \row
- \li LoadSucceededStatus
- \li Page has successfully loaded, and is not currently loading.
-
- \row
- \li LoadFailedStatus
- \li Page has failed to load, and is not currently loading.
+ Reflects a page's load status:
- \endtable
+ \value LoadStartedStatus
+ Page is currently loading.
+ \value LoadSucceededStatus
+ Page has successfully loaded, and is not currently loading.
+ \value LoadFailedStatus
+ Page has failed to load, and is not currently loading.
*/
/*!
\qmlproperty enumeration WebEngineView::NewViewDestination
- This enumeration details the format in which a new view request should be opened.
+ Describes how to open a new view:
\value WebEngineView::NewViewInWindow
- The page expects to be opened in a separate Window.
+ In a separate Window.
\value WebEngineView::NewViewInTab
- The page expects to be opened in a tab of the same window.
+ In a tab of the same window.
\value WebEngineView::NewViewInDialog
- The page expects to be opened in a Window without any tab, tool or URL bar.
+ In a Window without a tab bar, toolbar, or URL bar.
\value WebEngineView::NewViewInBackgroundTab
- The page expects to be opened in a tab of the same window, without hiding the currently visible WebEngineView.
+ In a tab of the same window, without hiding the currently visible web engine view.
\sa WebEngineNewViewRequest::destination
*/
@@ -587,28 +575,119 @@
/*!
\qmlproperty enumeration WebEngineView::FindFlags
- This enum describes the options available to the findText() function. The options
+ Describes the options available to the findText() function. The options
can be OR-ed together from the following list:
\value FindBackward Searches backwards instead of forwards.
\value FindCaseSensitively By default findText() works case insensitive. Specifying
this option changes the behavior to a case sensitive find operation.
- \sa WebEngineView::findText()
+ \sa findText()
+*/
+
+/*!
+ \qmlproperty enumeration WebEngineView::RenderProcessTerminationStatus
+ \since QtWebEngine 1.2
+
+ Describes the status with which the render process terminated:
+
+ \value NormalTerminationStatus
+ The render process terminated normally.
+ \value AbnormalTerminationStatus
+ The render process terminated with a non-zero exit status.
+ \value CrashedTerminationStatus
+ The render process crashed, for example because of a segmentation fault.
+ \value KilledTerminationStatus
+ The render process was killed, for example by \c SIGKILL or task manager kill.
+*/
+
+/*!
+ \qmlproperty enumeration WebEngineView::WebAction
+ \since QtWebEngine 1.2
+
+ Describes the types of action that can be performed on a web page:
+
+ \value NoWebAction
+ No action is triggered.
+ \value Back
+ Navigate back in the history of navigated links.
+ \value Forward
+ Navigate forward in the history of navigated links.
+ \value Stop
+ Stop loading the current page.
+ \value Reload
+ Reload the current page.
+ \value ReloadAndBypassCache
+ Reload the current page, but do not use any local cache.
+ \value Cut
+ Cut the content currently selected into the clipboard.
+ \value Copy
+ Copy the content currently selected into the clipboard.
+ \value Paste
+ Paste content from the clipboard.
+ \value Undo
+ Undo the last editing action.
+ \value Redo
+ Redo the last editing action.
+ \value SelectAll
+ Select all content.
+ \value PasteAndMatchStyle
+ Paste content from the clipboard with current style.
+ \value OpenLinkInThisWindow
+ Open the current link in the current window. (Added in Qt 5.6)
+ \value OpenLinkInNewWindow
+ Open the current link in a new window. (Added in Qt 5.6)
+ \value OpenLinkInNewTab
+ Open the current link in a new tab. (Added in Qt 5.6)
+ \value CopyLinkToClipboard
+ Copy the current link to the clipboard. (Added in Qt 5.6)
+ \value CopyImageToClipboard
+ Copy the clicked image to the clipboard. (Added in Qt 5.6)
+ \value CopyImageUrlToClipboard
+ Copy the clicked image's URL to the clipboard. (Added in Qt 5.6)
+ \value CopyMediaUrlToClipboard
+ Copy the hovered audio or video's URL to the clipboard. (Added in Qt 5.6)
+ \value ToggleMediaControls
+ Toggle between showing and hiding the controls for the hovered audio or video element.
+ (Added in Qt 5.6)
+ \value ToggleMediaLoop
+ Toggle whether the hovered audio or video should loop on completetion or not.
+ (Added in Qt 5.6)
+ \value ToggleMediaPlayPause
+ Toggle the play/pause state of the hovered audio or video element. (Added in Qt 5.6)
+ \value ToggleMediaMute
+ Mute or unmute the hovered audio or video element. (Added in Qt 5.6)
+ \value DownloadLinkToDisk
+ Download the current link to the disk. (Added in Qt 5.6)
+ \value DownloadImageToDisk
+ Download the highlighted image to the disk. (Added in Qt 5.6)
+ \value DownloadMediaToDisk
+ Download the hovered audio or video to the disk. (Added in Qt 5.6)
+ \value InspectElement
+ Trigger any attached Web Inspector to inspect the highlighed element.
+ (Added in Qt 5.6)
+ \value ExitFullScreen
+ Exit the fullscreen mode. (Added in Qt 5.6)
+
+ \omitvalue WebActionCount
*/
/*!
\qmlproperty enumeration WebEngineView::Feature
- This enum describes the platform feature access categories that the user may be asked to grant or deny access to.
-
- \value Geolocation Access to location hardware or service
- \value MediaAudioCapture Audio capture devices such a microphones
- \value MediaVideoCapture Video devices, e.g. cameras
- \value MediaAudioVideoCapture Both Audio and Video capture devices.
+ Describes the platform feature access categories that the user may be asked to grant or deny
+ access to:
- \sa WebEngineView::featurePermissionRequested, WebEngineView::grantFeaturePermission
+ \value Geolocation
+ Location hardware or service.
+ \value MediaAudioCapture
+ Audio capture devices, such as microphones.
+ \value MediaVideoCapture
+ Video devices, such as cameras.
+ \value MediaAudioVideoCapture
+ Both audio and video capture devices.
+ \sa featurePermissionRequested(), grantFeaturePermission()
*/
/*!
@@ -617,9 +696,9 @@
\inqmlmodule QtWebEngine 1.1
\since QtWebEngine 1.1
- \brief A utility class for the WebEngineView::fullScreenRequested signal.
+ \brief A utility type for the WebEngineView::fullScreenRequested() signal.
- \sa WebEngineView::fullScreenRequested
+ \sa WebEngineView::fullScreenRequested()
*/
/*!
@@ -629,7 +708,7 @@
Returns \c{true} if the application should toggle fullscreen mode on, \c{false} otherwise.
- \sa WebEngineFullScreenRequest::accept()
+ \sa accept()
*/
/*!
@@ -637,9 +716,9 @@
\since QtWebEngine 1.1
Call this method to accept the fullscreen request. It sets the WebEngineView::isFullScreen
- property to be equal to WebEngineFullScreenRequest::toggleOn.
+ property to be equal to toggleOn.
- \code
+ \qml
ApplicationWindow {
id: window
WebEngineView {
@@ -652,7 +731,7 @@
}
}
}
- \endcode
+ \endqml
- \sa WebEngineFullScreenRequest::toggleOn
+ \sa toggleOn
*/
diff --git a/src/webengine/plugin/experimental/experimental.pro b/src/webengine/plugin/experimental/experimental.pro
index 36162e359..d1b59326a 100644
--- a/src/webengine/plugin/experimental/experimental.pro
+++ b/src/webengine/plugin/experimental/experimental.pro
@@ -6,7 +6,7 @@ IMPORT_VERSION = 1.0
QT += webengine qml quick
QT_PRIVATE += webengine-private
-INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core $$QTWEBENGINE_ROOT/src/webengine $$QTWEBENGINE_ROOT/src/webengine/api
+INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core $$QTWEBENGINE_ROOT/src/core/api $$QTWEBENGINE_ROOT/src/webengine $$QTWEBENGINE_ROOT/src/webengine/api
SOURCES = plugin.cpp
diff --git a/src/webengine/plugin/experimental/plugin.cpp b/src/webengine/plugin/experimental/plugin.cpp
index 29b5413f4..f9525e656 100644
--- a/src/webengine/plugin/experimental/plugin.cpp
+++ b/src/webengine/plugin/experimental/plugin.cpp
@@ -63,12 +63,12 @@ public:
qmlRegisterExtendedType<QQuickWebEngineView, QQuickWebEngineViewExperimentalExtension>(uri, 1, 0, "WebEngineView");
qmlRegisterUncreatableType<QQuickWebEngineViewExperimental>(uri, 1, 0, "WebEngineViewExperimental",
- QObject::tr("Cannot create a separate instance of WebEngineViewExperimental"));
+ tr("Cannot create a separate instance of WebEngineViewExperimental"));
qmlRegisterUncreatableType<QQuickWebEngineViewport>(uri, 1, 0, "WebEngineViewport",
- QObject::tr("Cannot create a separate instance of WebEngineViewport"));
+ tr("Cannot create a separate instance of WebEngineViewport"));
// Use the latest revision of QQuickWebEngineView when importing QtWebEngine.experimental 1.0
- qmlRegisterRevision<QQuickWebEngineView, 1>(uri, 1, 0);
+ qmlRegisterRevision<QQuickWebEngineView, LATEST_WEBENGINEVIEW_REVISION>(uri, 1, 0);
}
};
diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp
index c5ef11a5e..16d36b190 100644
--- a/src/webengine/plugin/plugin.cpp
+++ b/src/webengine/plugin/plugin.cpp
@@ -65,24 +65,30 @@ public:
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtWebEngine"));
qmlRegisterType<QQuickWebEngineView>(uri, 1, 0, "WebEngineView");
- qmlRegisterUncreatableType<QQuickWebEngineLoadRequest>(uri, 1, 0, "WebEngineLoadRequest", QObject::tr("Cannot create separate instance of WebEngineLoadRequest"));
- qmlRegisterUncreatableType<QQuickWebEngineNavigationRequest>(uri, 1, 0, "WebEngineNavigationRequest", QObject::tr("Cannot create separate instance of WebEngineNavigationRequest"));
+ qmlRegisterUncreatableType<QQuickWebEngineLoadRequest>(uri, 1, 0, "WebEngineLoadRequest", tr("Cannot create separate instance of WebEngineLoadRequest"));
+ qmlRegisterUncreatableType<QQuickWebEngineNavigationRequest>(uri, 1, 0, "WebEngineNavigationRequest", tr("Cannot create separate instance of WebEngineNavigationRequest"));
qmlRegisterType<QQuickWebEngineView, 1>(uri, 1, 1, "WebEngineView");
+ qmlRegisterType<QQuickWebEngineView, 2>(uri, 1, 2, "WebEngineView");
qmlRegisterType<QQuickWebEngineProfile>(uri, 1, 1, "WebEngineProfile");
+ qmlRegisterType<QQuickWebEngineProfile, 1>(uri, 1, 2, "WebEngineProfile");
qmlRegisterType<QQuickWebEngineScript>(uri, 1, 1, "WebEngineScript");
- qmlRegisterUncreatableType<QQuickWebEngineCertificateError>(uri, 1, 1, "WebEngineCertificateError", QObject::tr("Cannot create separate instance of WebEngineCertificateError"));
+ qmlRegisterUncreatableType<QQuickWebEngineCertificateError>(uri, 1, 1, "WebEngineCertificateError", tr("Cannot create separate instance of WebEngineCertificateError"));
qmlRegisterUncreatableType<QQuickWebEngineDownloadItem>(uri, 1, 1, "WebEngineDownloadItem",
- QObject::tr("Cannot create a separate instance of WebEngineDownloadItem"));
- qmlRegisterUncreatableType<QQuickWebEngineNewViewRequest>(uri, 1, 1, "WebEngineNewViewRequest", QObject::tr("Cannot create separate instance of WebEngineNewViewRequest"));
- qmlRegisterUncreatableType<QQuickWebEngineSettings>(uri, 1, 1, "WebEngineSettings", QObject::tr("Cannot create a separate instance of WebEngineSettings"));
+ tr("Cannot create a separate instance of WebEngineDownloadItem"));
+ qmlRegisterUncreatableType<QQuickWebEngineNewViewRequest>(uri, 1, 1, "WebEngineNewViewRequest", tr("Cannot create separate instance of WebEngineNewViewRequest"));
+ qmlRegisterUncreatableType<QQuickWebEngineSettings>(uri, 1, 1, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings"));
+ // FIXME(QTBUG-40043): qmlRegisterUncreatableType<QQuickWebEngineSettings, 1>(uri, 1, 2, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings"));
qmlRegisterSingletonType<QQuickWebEngineSingleton>(uri, 1, 1, "WebEngine", webEngineSingletonProvider);
qmlRegisterUncreatableType<QQuickWebEngineHistory>(uri, 1, 1, "NavigationHistory",
- QObject::tr("Cannot create a separate instance of NavigationHistory"));
+ tr("Cannot create a separate instance of NavigationHistory"));
qmlRegisterUncreatableType<QQuickWebEngineHistoryListModel>(uri, 1, 1, "NavigationHistoryListModel",
- QObject::tr("Cannot create a separate instance of NavigationHistory"));
+ tr("Cannot create a separate instance of NavigationHistory"));
qmlRegisterUncreatableType<QQuickWebEngineFullScreenRequest>(uri, 1, 1, "FullScreenRequest",
- QObject::tr("Cannot create a separate instance of FullScreenRequest"));
+ tr("Cannot create a separate instance of FullScreenRequest"));
+
+ // For now (1.x import), the latest revision matches the minor version of the import.
+ qmlRegisterRevision<QQuickWebEngineView, LATEST_WEBENGINEVIEW_REVISION>(uri, 1, LATEST_WEBENGINEVIEW_REVISION);
}
};
diff --git a/src/webengine/plugin/plugin.pro b/src/webengine/plugin/plugin.pro
index 123c45511..b6acc760f 100644
--- a/src/webengine/plugin/plugin.pro
+++ b/src/webengine/plugin/plugin.pro
@@ -1,12 +1,12 @@
CXX_MODULE = qml
TARGET = qtwebengineplugin
TARGETPATH = QtWebEngine
-IMPORT_VERSION = 1.1
+IMPORT_VERSION = 1.2
QT += webengine qml quick
QT_PRIVATE += webengine-private
-INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core $$QTWEBENGINE_ROOT/src/webengine $$QTWEBENGINE_ROOT/src/webengine/api $$QTWEBENGINE_ROOT/include/QtWebEngine
+INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core $$QTWEBENGINE_ROOT/src/core/api $$QTWEBENGINE_ROOT/src/webengine $$QTWEBENGINE_ROOT/src/webengine/api $$QTWEBENGINE_ROOT/include/QtWebEngine
SOURCES = plugin.cpp
diff --git a/src/webengine/plugin/plugins.qmltypes b/src/webengine/plugin/plugins.qmltypes
index 9dcded7b0..1e577bf51 100644
--- a/src/webengine/plugin/plugins.qmltypes
+++ b/src/webengine/plugin/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtWebEngine 1.1'
+// 'qmlplugindump -nonrelocatable QtWebEngine 1.2'
Module {
dependencies: []
@@ -571,8 +571,11 @@ Module {
Component {
name: "QQuickWebEngineProfile"
prototype: "QObject"
- exports: ["QtWebEngine/WebEngineProfile 1.1"]
- exportMetaObjectRevisions: [0]
+ exports: [
+ "QtWebEngine/WebEngineProfile 1.1",
+ "QtWebEngine/WebEngineProfile 1.2"
+ ]
+ exportMetaObjectRevisions: [0, 1]
Enum {
name: "HttpCacheType"
values: {
@@ -594,8 +597,10 @@ Module {
Property { name: "cachePath"; type: "string" }
Property { name: "httpUserAgent"; type: "string" }
Property { name: "httpCacheType"; type: "HttpCacheType" }
+ Property { name: "httpAcceptLanguage"; type: "string" }
Property { name: "persistentCookiesPolicy"; type: "PersistentCookiesPolicy" }
Property { name: "httpCacheMaximumSize"; type: "int" }
+ Signal { name: "httpAcceptLanguageChanged"; revision: 1 }
Signal {
name: "downloadRequested"
Parameter { name: "download"; type: "QQuickWebEngineDownloadItem"; isPointer: true }
@@ -604,6 +609,11 @@ Module {
name: "downloadFinished"
Parameter { name: "download"; type: "QQuickWebEngineDownloadItem"; isPointer: true }
}
+ Method {
+ name: "setCookieStoreClient"
+ revision: 1
+ Parameter { name: "client"; type: "QWebEngineCookieStoreClient"; isPointer: true }
+ }
}
Component {
name: "QQuickWebEngineScript"
@@ -685,9 +695,12 @@ Module {
Component {
name: "QQuickWebEngineSettings"
prototype: "QObject"
- exports: ["QtWebEngine/WebEngineSettings 1.1"]
+ exports: [
+ "QtWebEngine/WebEngineSettings 1.1",
+ "QtWebEngine/WebEngineSettings 1.2"
+ ]
isCreatable: false
- exportMetaObjectRevisions: [0]
+ exportMetaObjectRevisions: [0, 1]
Property { name: "autoLoadImages"; type: "bool" }
Property { name: "javascriptEnabled"; type: "bool" }
Property { name: "javascriptCanOpenWindows"; type: "bool" }
@@ -699,7 +712,10 @@ Module {
Property { name: "localContentCanAccessFileUrls"; type: "bool" }
Property { name: "hyperlinkAuditingEnabled"; type: "bool" }
Property { name: "errorPageEnabled"; type: "bool" }
+ Property { name: "pluginsEnabled"; type: "bool" }
+ Property { name: "fullScreenSupportEnabled"; revision: 1; type: "bool" }
Property { name: "defaultTextEncoding"; type: "string" }
+ Signal { name: "fullScreenSupportEnabledChanged"; revision: 1 }
}
Component {
name: "QQuickWebEngineSingleton"
@@ -723,9 +739,10 @@ Module {
prototype: "QQuickItem"
exports: [
"QtWebEngine/WebEngineView 1.0",
- "QtWebEngine/WebEngineView 1.1"
+ "QtWebEngine/WebEngineView 1.1",
+ "QtWebEngine/WebEngineView 1.2"
]
- exportMetaObjectRevisions: [0, 1]
+ exportMetaObjectRevisions: [0, 1, 2]
Enum {
name: "NavigationRequestAction"
values: {
@@ -784,6 +801,41 @@ Module {
}
}
Enum {
+ name: "WebAction"
+ values: {
+ "NoWebAction": -1,
+ "Back": 0,
+ "Forward": 1,
+ "Stop": 2,
+ "Reload": 3,
+ "Cut": 4,
+ "Copy": 5,
+ "Paste": 6,
+ "Undo": 7,
+ "Redo": 8,
+ "SelectAll": 9,
+ "ReloadAndBypassCache": 10,
+ "PasteAndMatchStyle": 11,
+ "OpenLinkInThisWindow": 12,
+ "OpenLinkInNewWindow": 13,
+ "OpenLinkInNewTab": 14,
+ "CopyLinkToClipboard": 15,
+ "DownloadLinkToDisk": 16,
+ "CopyImageToClipboard": 17,
+ "CopyImageUrlToClipboard": 18,
+ "DownloadImageToDisk": 19,
+ "CopyMediaUrlToClipboard": 20,
+ "ToggleMediaControls": 21,
+ "ToggleMediaLoop": 22,
+ "ToggleMediaPlayPause": 23,
+ "ToggleMediaMute": 24,
+ "DownloadMediaToDisk": 25,
+ "InspectElement": 26,
+ "ExitFullScreen": 27,
+ "WebActionCount": 28
+ }
+ }
+ Enum {
name: "JavaScriptConsoleMessageLevel"
values: {
"InfoMessageLevel": 0,
@@ -792,6 +844,15 @@ Module {
}
}
Enum {
+ name: "RenderProcessTerminationStatus"
+ values: {
+ "NormalTerminationStatus": 0,
+ "AbnormalTerminationStatus": 1,
+ "CrashedTerminationStatus": 2,
+ "KilledTerminationStatus": 3
+ }
+ }
+ Enum {
name: "FindFlags"
values: {
"FindBackward": 1,
@@ -830,6 +891,8 @@ Module {
isList: true
isReadonly: true
}
+ Property { name: "activeFocusOnPress"; revision: 2; type: "bool" }
+ Property { name: "backgroundColor"; revision: 2; type: "QColor" }
Signal {
name: "loadingChanged"
Parameter { name: "loadRequest"; type: "QQuickWebEngineLoadRequest"; isPointer: true }
@@ -878,6 +941,18 @@ Module {
}
Signal { name: "profileChanged"; revision: 1 }
Signal { name: "webChannelChanged"; revision: 1 }
+ Signal {
+ name: "activeFocusOnPressChanged"
+ revision: 2
+ Parameter { type: "bool" }
+ }
+ Signal { name: "backgroundColorChanged"; revision: 2 }
+ Signal {
+ name: "renderProcessTerminated"
+ revision: 2
+ Parameter { name: "terminationStatus"; type: "RenderProcessTerminationStatus" }
+ Parameter { name: "exitCode"; type: "int" }
+ }
Method {
name: "runJavaScript"
Parameter { type: "string" }
@@ -932,5 +1007,15 @@ Module {
Parameter { type: "Feature" }
Parameter { name: "granted"; type: "bool" }
}
+ Method {
+ name: "setActiveFocusOnPress"
+ revision: 2
+ Parameter { name: "arg"; type: "bool" }
+ }
+ Method {
+ name: "triggerWebAction"
+ revision: 2
+ Parameter { name: "action"; type: "WebAction" }
+ }
}
}
diff --git a/src/webengine/plugin/testsupport/plugin.cpp b/src/webengine/plugin/testsupport/plugin.cpp
index 98a1d3ca6..28001db54 100644
--- a/src/webengine/plugin/testsupport/plugin.cpp
+++ b/src/webengine/plugin/testsupport/plugin.cpp
@@ -54,7 +54,7 @@ public:
qmlRegisterType<QQuickWebEngineTestSupport>(uri, 1, 0, "WebEngineTestSupport");
qmlRegisterUncreatableType<QQuickWebEngineErrorPage>(uri, 1, 0, "WebEngineErrorPage",
- QObject::tr("Cannot create a separate instance of WebEngineErrorPage"));
+ tr("Cannot create a separate instance of WebEngineErrorPage"));
}
};
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
index a3999ccab..9fc1ed3eb 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
@@ -64,10 +64,14 @@ RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderW
void RenderWidgetHostViewQtDelegateQuick::initAsChild(WebContentsAdapterClient* container)
{
- QQuickWebEngineViewPrivate *viewPrivate = static_cast<QQuickWebEngineViewPrivate *>(container);
- setParentItem(viewPrivate->q_func());
- setSize(viewPrivate->q_func()->boundingRect().size());
+ QQuickWebEngineView *view = static_cast<QQuickWebEngineViewPrivate *>(container)->q_func();
+ setParentItem(view);
+ setSize(view->boundingRect().size());
+ // Focus on creation if the view accepts it
+ if (view->activeFocusOnPress())
+ setFocus(true);
m_initialized = true;
+
}
void RenderWidgetHostViewQtDelegateQuick::initAsPopup(const QRect &r)
@@ -176,9 +180,11 @@ void RenderWidgetHostViewQtDelegateQuick::inputMethodStateChanged(bool editorVis
if (qApp->inputMethod()->isVisible() == editorVisible)
return;
- setFlag(QQuickItem::ItemAcceptsInputMethod, editorVisible);
- qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints);
- qApp->inputMethod()->setVisible(editorVisible);
+ if (parentItem() && parentItem()->flags() & QQuickItem::ItemAcceptsInputMethod) {
+ qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints);
+ qApp->inputMethod()->setVisible(editorVisible);
+ }
+
}
void RenderWidgetHostViewQtDelegateQuick::focusInEvent(QFocusEvent *event)
@@ -193,7 +199,7 @@ void RenderWidgetHostViewQtDelegateQuick::focusOutEvent(QFocusEvent *event)
void RenderWidgetHostViewQtDelegateQuick::mousePressEvent(QMouseEvent *event)
{
- if (!m_isPopup)
+ if (!m_isPopup && (parentItem() && parentItem()->property("activeFocusOnPress").toBool()))
forceActiveFocus();
m_client->forwardEvent(event);
}
@@ -225,7 +231,8 @@ void RenderWidgetHostViewQtDelegateQuick::wheelEvent(QWheelEvent *event)
void RenderWidgetHostViewQtDelegateQuick::touchEvent(QTouchEvent *event)
{
- if (event->type() == QEvent::TouchBegin && !m_isPopup)
+ if (event->type() == QEvent::TouchBegin && !m_isPopup
+ && (parentItem() && parentItem()->property("activeFocusOnPress").toBool()))
forceActiveFocus();
m_client->forwardEvent(event);
}
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.h b/src/webengine/render_widget_host_view_qt_delegate_quick.h
index ddd0e4d9e..eb2860b27 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h
@@ -70,6 +70,8 @@ public:
virtual void move(const QPoint&) Q_DECL_OVERRIDE { }
virtual void inputMethodStateChanged(bool editorVisible) Q_DECL_OVERRIDE;
virtual void setTooltip(const QString&) Q_DECL_OVERRIDE { }
+ // The QtQuick view doesn't have a backbuffer of its own and doesn't need this
+ virtual void setClearColor(const QColor &) Q_DECL_OVERRIDE { }
protected:
virtual void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE;
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
index cda51a1ab..a4b08482f 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
@@ -73,6 +73,7 @@ public:
virtual void move(const QPoint &screenPos) Q_DECL_OVERRIDE;
virtual void inputMethodStateChanged(bool) Q_DECL_OVERRIDE {}
virtual void setTooltip(const QString &tooltip) Q_DECL_OVERRIDE;
+ virtual void setClearColor(const QColor &) Q_DECL_OVERRIDE { }
private:
QScopedPointer<RenderWidgetHostViewQtDelegate> m_realDelegate;
diff --git a/src/webengine/ui/AuthenticationDialog.qml b/src/webengine/ui/AuthenticationDialog.qml
new file mode 100644
index 000000000..46e2e3151
--- /dev/null
+++ b/src/webengine/ui/AuthenticationDialog.qml
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// FIXME: authentication missing in Qt Quick Dialogs atm. Make our own for now.
+import QtQuick.Controls 1.4
+import QtQuick.Layouts 1.0
+import QtQuick 2.5
+
+ApplicationWindow {
+ signal accepted(string user, string password);
+ signal rejected;
+ property alias text: message.text;
+
+ width: 350
+ height: 100
+ flags: Qt.Dialog
+
+ title: "Authentication Required"
+
+ function open() {
+ show();
+ }
+
+ ColumnLayout {
+ anchors.fill: parent;
+ anchors.margins: 4;
+ Text {
+ id: message;
+ Layout.fillWidth: true;
+ }
+ RowLayout {
+ Label {
+ text: "Username:"
+ }
+ TextField {
+ id: userField;
+ Layout.fillWidth: true;
+ }
+ }
+ RowLayout {
+ Label {
+ text: "Password:"
+ }
+ TextField {
+ id: passwordField;
+ Layout.fillWidth: true;
+ echoMode: TextInput.Password;
+ }
+ }
+ RowLayout {
+ Layout.alignment: Qt.AlignRight
+ spacing: 8;
+ Button {
+ text: "Log In"
+ onClicked: {
+ accepted(userField.text, passwordField.text);
+ close();
+ destroy();
+ }
+ }
+ Button {
+ text: "Cancel"
+ onClicked: {
+ rejected();
+ close();
+ destroy();
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/webengine/ui/ui.pro b/src/webengine/ui/ui.pro
index fdf7a85bc..28ea691b2 100644
--- a/src/webengine/ui/ui.pro
+++ b/src/webengine/ui/ui.pro
@@ -1,6 +1,8 @@
TARGETPATH = QtWebEngine/UIDelegates
QML_FILES += \
+ # Authentication Dialog
+ AuthenticationDialog.qml \
# JS Dialogs
AlertDialog.qml \
ConfirmDialog.qml \
diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp
index d22e6546f..6c4282eb3 100644
--- a/src/webengine/ui_delegates_manager.cpp
+++ b/src/webengine/ui_delegates_manager.cpp
@@ -37,12 +37,15 @@
#include "ui_delegates_manager.h"
#include "api/qquickwebengineview_p.h"
+#include "authentication_dialog_controller.h"
+#include "file_picker_controller.h"
#include "javascript_dialog_controller.h"
#include <QAbstractListModel>
#include <QClipboard>
#include <QFileInfo>
#include <QGuiApplication>
+#include <QMimeData>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQmlProperty>
@@ -57,7 +60,7 @@ namespace QtWebEngineCore {
#if defined(Q_OS_WIN)
#define FILE_NAME_CASE_STATEMENT(TYPE, COMPONENT) \
case UIDelegatesManager::TYPE:\
- return QStringLiteral(#TYPE L ##".qml");
+ return QString::fromLatin1(#TYPE ##".qml");
#else
#define FILE_NAME_CASE_STATEMENT(TYPE, COMPONENT) \
case UIDelegatesManager::TYPE:\
@@ -107,32 +110,6 @@ MenuItemHandler::MenuItemHandler(QObject *parent)
{
}
-
-CopyMenuItem::CopyMenuItem(QObject *parent, const QString &textToCopy)
- : MenuItemHandler(parent)
- , m_textToCopy(textToCopy)
-{
- connect(this, &MenuItemHandler::triggered, this, &CopyMenuItem::onTriggered);
-}
-
-void CopyMenuItem::onTriggered()
-{
- qApp->clipboard()->setText(m_textToCopy);
-}
-
-NavigateMenuItem::NavigateMenuItem(QObject *parent, const QExplicitlySharedDataPointer<WebContentsAdapter> &adapter, const QUrl &targetUrl)
- : MenuItemHandler(parent)
- , m_adapter(adapter)
- , m_targetUrl(targetUrl)
-{
- connect(this, &MenuItemHandler::triggered, this, &NavigateMenuItem::onTriggered);
-}
-
-void NavigateMenuItem::onTriggered()
-{
- m_adapter->load(m_targetUrl);
-}
-
#define COMPONENT_MEMBER_INIT(TYPE, COMPONENT) \
, COMPONENT##Component(0)
@@ -272,15 +249,19 @@ void UIDelegatesManager::showDialog(QSharedPointer<JavaScriptDialogController> d
switch (dialogController->type()) {
case WebContentsAdapterClient::AlertDialog:
dialogComponentType = AlertDialog;
- title = QObject::tr("Javascript Alert - %1").arg(m_view->url().toString());
+ title = QCoreApplication::translate("UIDelegatesManager", "Javascript Alert - %1").arg(m_view->url().toString());
break;
case WebContentsAdapterClient::ConfirmDialog:
dialogComponentType = ConfirmDialog;
- title = QObject::tr("Javascript Confirm - %1").arg(m_view->url().toString());
+ title = QCoreApplication::translate("UIDelegatesManager", "Javascript Confirm - %1").arg(m_view->url().toString());
break;
case WebContentsAdapterClient::PromptDialog:
dialogComponentType = PromptDialog;
- title = QObject::tr("Javascript Prompt - %1").arg(m_view->url().toString());
+ title = QCoreApplication::translate("UIDelegatesManager", "Javascript Prompt - %1").arg(m_view->url().toString());
+ break;
+ case WebContentsAdapterClient::UnloadDialog:
+ dialogComponentType = ConfirmDialog;
+ title = QCoreApplication::translate("UIDelegatesManager", "Are you sure you want to leave this page?");
break;
case WebContentsAdapterClient::InternalAuthorizationDialog:
dialogComponentType = ConfirmDialog;
@@ -341,50 +322,48 @@ void UIDelegatesManager::showDialog(QSharedPointer<JavaScriptDialogController> d
QMetaObject::invokeMethod(dialog, "open");
}
-namespace {
-class FilePickerController : public QObject {
- Q_OBJECT
-public:
- FilePickerController(WebContentsAdapterClient::FileChooserMode, const QExplicitlySharedDataPointer<WebContentsAdapter> &, QObject * = 0);
-
-public Q_SLOTS:
- void accepted(const QVariant &files);
- void rejected();
+void UIDelegatesManager::showDialog(QSharedPointer<AuthenticationDialogController> dialogController)
+{
+ Q_ASSERT(!dialogController.isNull());
-private:
- QExplicitlySharedDataPointer<WebContentsAdapter> m_adapter;
- WebContentsAdapterClient::FileChooserMode m_mode;
+ if (!ensureComponentLoaded(AuthenticationDialog)) {
+ // Let the controller know it couldn't be loaded
+ qWarning("Failed to load authentication dialog, rejecting.");
+ dialogController->reject();
+ return;
+ }
-};
+ QQmlContext *context = qmlContext(m_view);
+ QObject *authenticationDialog = authenticationDialogComponent->beginCreate(context);
+ authenticationDialog->setParent(m_view);
+ QString introMessage;
+ if (dialogController->isProxy()) {
+ introMessage = QObject::tr("Connect to proxy \"%1\" using:");
+ introMessage = introMessage.arg(dialogController->host().toHtmlEscaped());
+ } else {
+ introMessage = QObject::tr("Enter username and password for \"%1\" at %2");
+ introMessage = introMessage.arg(dialogController->realm()).arg(dialogController->url().toString().toHtmlEscaped());
+ }
+ QQmlProperty textProp(authenticationDialog, QStringLiteral("text"));
+ textProp.write(introMessage);
-FilePickerController::FilePickerController(WebContentsAdapterClient::FileChooserMode mode, const QExplicitlySharedDataPointer<WebContentsAdapter> &adapter, QObject *parent)
- : QObject(parent)
- , m_adapter(adapter)
- , m_mode(mode)
-{
-}
+ QQmlProperty acceptSignal(authenticationDialog, QStringLiteral("onAccepted"));
+ QQmlProperty rejectSignal(authenticationDialog, QStringLiteral("onRejected"));
+ CHECK_QML_SIGNAL_PROPERTY(acceptSignal, authenticationDialogComponent->url());
+ CHECK_QML_SIGNAL_PROPERTY(rejectSignal, authenticationDialogComponent->url());
-void FilePickerController::accepted(const QVariant &files)
-{
- QStringList stringList;
- Q_FOREACH (const QUrl &url, files.value<QList<QUrl> >())
- stringList.append(url.toLocalFile());
- m_adapter->filesSelectedInChooser(stringList, m_mode);
-}
+ static int acceptIndex = dialogController->metaObject()->indexOfSlot("accept(QString,QString)");
+ QObject::connect(authenticationDialog, acceptSignal.method(), dialogController.data(), dialogController->metaObject()->method(acceptIndex));
+ static int rejectIndex = dialogController->metaObject()->indexOfSlot("reject()");
+ QObject::connect(authenticationDialog, rejectSignal.method(), dialogController.data(), dialogController->metaObject()->method(rejectIndex));
-void FilePickerController::rejected()
-{
- m_adapter->filesSelectedInChooser(QStringList(), m_mode);
+ authenticationDialogComponent->completeCreate();
+ QMetaObject::invokeMethod(authenticationDialog, "open");
}
-} // namespace
-
-
-void UIDelegatesManager::showFilePicker(WebContentsAdapterClient::FileChooserMode mode, const QString &defaultFileName, const QStringList &acceptedMimeTypes, const QExplicitlySharedDataPointer<WebContentsAdapter> &adapter)
+void UIDelegatesManager::showFilePicker(FilePickerController *controller)
{
- Q_UNUSED(defaultFileName);
- Q_UNUSED(acceptedMimeTypes);
if (!ensureComponentLoaded(FilePicker))
return;
@@ -397,23 +376,24 @@ void UIDelegatesManager::showFilePicker(WebContentsAdapterClient::FileChooserMod
filePickerComponent->completeCreate();
// Fine-tune some properties depending on the mode.
- switch (mode) {
- case WebContentsAdapterClient::Open:
+ switch (controller->mode()) {
+ case FilePickerController::Open:
break;
- case WebContentsAdapterClient::Save:
+ case FilePickerController::Save:
filePicker->setProperty("selectExisting", false);
break;
- case WebContentsAdapterClient::OpenMultiple:
+ case FilePickerController::OpenMultiple:
filePicker->setProperty("selectMultiple", true);
break;
- case WebContentsAdapterClient::UploadFolder:
+ case FilePickerController::UploadFolder:
filePicker->setProperty("selectFolder", true);
break;
default:
Q_UNREACHABLE();
}
- FilePickerController *controller = new FilePickerController(mode, adapter, filePicker);
+ controller->setParent(filePicker);
+
QQmlProperty filesPickedSignal(filePicker, QStringLiteral("onFilesSelected"));
CHECK_QML_SIGNAL_PROPERTY(filesPickedSignal, filePickerComponent->url());
QQmlProperty rejectSignal(filePicker, QStringLiteral("onRejected"));
@@ -464,5 +444,3 @@ void UIDelegatesManager::moveMessageBubble(const QRect &anchor)
}
} // namespace QtWebEngineCore
-
-#include "ui_delegates_manager.moc"
diff --git a/src/webengine/ui_delegates_manager.h b/src/webengine/ui_delegates_manager.h
index f2b78f792..2a86b2803 100644
--- a/src/webengine/ui_delegates_manager.h
+++ b/src/webengine/ui_delegates_manager.h
@@ -55,7 +55,8 @@
F(ConfirmDialog, confirmDialog) SEPARATOR \
F(PromptDialog, promptDialog) SEPARATOR \
F(FilePicker, filePicker) SEPARATOR \
- F(MessageBubble, messageBubble) SEPARATOR
+ F(MessageBubble, messageBubble) SEPARATOR \
+ F(AuthenticationDialog, authenticationDialog) SEPARATOR
#define COMMA_SEPARATOR ,
#define SEMICOLON_SEPARATOR ;
@@ -72,7 +73,9 @@ class QQuickWebEngineView;
QT_END_NAMESPACE
namespace QtWebEngineCore {
+class AuthenticationDialogController;
class JavaScriptDialogController;
+class FilePickerController;
const char *defaultPropertyName(QObject *obj);
@@ -85,29 +88,6 @@ Q_SIGNALS:
void triggered();
};
-class CopyMenuItem : public MenuItemHandler {
- Q_OBJECT
-public:
- CopyMenuItem(QObject *parent, const QString &textToCopy);
-
-private:
- void onTriggered();
-
- QString m_textToCopy;
-};
-
-class NavigateMenuItem : public MenuItemHandler {
- Q_OBJECT
-public:
- NavigateMenuItem(QObject *parent, const QExplicitlySharedDataPointer<WebContentsAdapter> &adapter, const QUrl &targetUrl);
-
-private:
- void onTriggered();
-
- QExplicitlySharedDataPointer<WebContentsAdapter> m_adapter;
- QUrl m_targetUrl;
-};
-
class UIDelegatesManager {
public:
@@ -124,8 +104,8 @@ public:
QObject *addMenu(QObject *parentMenu, const QString &title, const QPoint &pos = QPoint());
QQmlContext *creationContextForComponent(QQmlComponent *);
void showDialog(QSharedPointer<JavaScriptDialogController>);
- void showFilePicker(WebContentsAdapterClient::FileChooserMode, const QString &defaultFileName, const QStringList &acceptedMimeTypes
- , const QExplicitlySharedDataPointer<WebContentsAdapter> &);
+ void showDialog(QSharedPointer<AuthenticationDialogController>);
+ void showFilePicker(FilePickerController *controller);
void showMessageBubble(const QRect &anchor, const QString &mainText, const QString &subText);
void hideMessageBubble();
void moveMessageBubble(const QRect &anchor);
diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro
index 6cba9c5d9..8bb5a8e77 100644
--- a/src/webengine/webengine.pro
+++ b/src/webengine/webengine.pro
@@ -3,12 +3,12 @@ TARGET = QtWebEngine
# For our export macros
DEFINES += QT_BUILD_WEBENGINE_LIB
-QT += qml quick
-QT_PRIVATE += webenginecore quick-private gui-private core-private
+QT += qml quick webenginecore
+QT_PRIVATE += quick-private gui-private core-private
QMAKE_DOCS = $$PWD/doc/qtwebengine.qdocconf
-INCLUDEPATH += $$PWD api ../core
+INCLUDEPATH += $$PWD api ../core ../core/api
SOURCES = \
api/qquickwebenginecertificateerror.cpp \
diff --git a/src/webenginewidgets/api/qwebenginecertificateerror.h b/src/webenginewidgets/api/qwebenginecertificateerror.h
index 90b23208c..7706ea32d 100644
--- a/src/webenginewidgets/api/qwebenginecertificateerror.h
+++ b/src/webenginewidgets/api/qwebenginecertificateerror.h
@@ -37,10 +37,10 @@
#ifndef QWEBENGINECERTIFICATEERROR_H
#define QWEBENGINECERTIFICATEERROR_H
-#include "qtwebenginewidgetsglobal.h"
+#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h>
-#include <QtCore/QScopedPointer>
-#include <QtCore/QUrl>
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qurl.h>
QT_BEGIN_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.h b/src/webenginewidgets/api/qwebenginedownloaditem.h
index 9fbf42ad3..05e0f8765 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem.h
+++ b/src/webenginewidgets/api/qwebenginedownloaditem.h
@@ -37,9 +37,9 @@
#ifndef QWEBENGINEDOWNLOADITEM_H
#define QWEBENGINEDOWNLOADITEM_H
-#include "qtwebenginewidgetsglobal.h"
+#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h>
-#include <QObject>
+#include <QtCore/qobject.h>
QT_BEGIN_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebenginefullscreenrequest.cpp b/src/webenginewidgets/api/qwebenginefullscreenrequest.cpp
new file mode 100644
index 000000000..6223c070d
--- /dev/null
+++ b/src/webenginewidgets/api/qwebenginefullscreenrequest.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwebenginefullscreenrequest.h"
+#include "qwebenginepage_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QWebEngineFullScreenRequest::QWebEngineFullScreenRequest(QWebEnginePagePrivate *pagePrivate, const QUrl &origin, bool fullscreen)
+ : m_pagePrivate(pagePrivate)
+ , m_origin(origin)
+ , m_toggleOn(fullscreen)
+{
+}
+
+void QWebEngineFullScreenRequest::reject() const
+{
+ m_pagePrivate->setFullScreenMode(!m_toggleOn);
+}
+
+void QWebEngineFullScreenRequest::accept() const
+{
+ m_pagePrivate->setFullScreenMode(m_toggleOn);
+}
+
+QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebengineurlschemehandler_p_p.h b/src/webenginewidgets/api/qwebenginefullscreenrequest.h
index d349d7d8c..c6768f4d6 100644
--- a/src/webenginewidgets/api/qwebengineurlschemehandler_p_p.h
+++ b/src/webenginewidgets/api/qwebenginefullscreenrequest.h
@@ -34,46 +34,35 @@
**
****************************************************************************/
-#ifndef QWEBENGINEURLSCHEMEHANDLER_P_H
-#define QWEBENGINEURLSCHEMEHANDLER_P_H
+#ifndef QWEBENGINEFULLSCREENREQUEST_H
+#define QWEBENGINEFULLSCREENREQUEST_H
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qwebengineurlschemehandler_p.h"
-
-#include "custom_url_scheme_handler.h"
-
-#include <QPointer>
+#include <qtwebenginewidgetsglobal.h>
+#include <qwebenginepage.h>
+#include <QtCore/qurl.h>
QT_BEGIN_NAMESPACE
+class QWebEnginePagePrivate;
-class QWebEngineProfile;
-class QWebEngineUrlRequestJob;
-class QWebEngineUrlSchemeHandler;
-
-class QWebEngineUrlSchemeHandlerPrivate : public QtWebEngineCore::CustomUrlSchemeHandler {
+class QWEBENGINEWIDGETS_EXPORT QWebEngineFullScreenRequest {
+ Q_GADGET
+ Q_PROPERTY(bool toggleOn READ toggleOn)
+ Q_PROPERTY(QUrl origin READ origin)
public:
- Q_DECLARE_PUBLIC(QWebEngineUrlSchemeHandler)
-
- QWebEngineUrlSchemeHandlerPrivate(const QByteArray &, QWebEngineUrlSchemeHandler *, QWebEngineProfile *);
- virtual ~QWebEngineUrlSchemeHandlerPrivate();
-
- virtual bool handleJob(QtWebEngineCore::URLRequestCustomJobDelegate*) Q_DECL_OVERRIDE;
+ Q_INVOKABLE void reject() const;
+ Q_INVOKABLE void accept() const;
+ bool toggleOn() const { return m_toggleOn; }
+ const QUrl &origin() const { return m_origin; }
private:
- QWebEngineUrlSchemeHandler *q_ptr;
- QPointer<QWebEngineProfile> m_profile;
+ Q_DISABLE_COPY(QWebEngineFullScreenRequest)
+ QWebEngineFullScreenRequest(QWebEnginePagePrivate *pagePrivate, const QUrl &origin, bool toggleOn);
+ QWebEnginePagePrivate *m_pagePrivate;
+ const QUrl m_origin;
+ const bool m_toggleOn;
+ friend class QWebEnginePagePrivate;
};
QT_END_NAMESPACE
-#endif // QWEBENGINEURLSCHEMEHANDLER_P_H
+#endif
diff --git a/src/webenginewidgets/api/qwebenginehistory.cpp b/src/webenginewidgets/api/qwebenginehistory.cpp
index b04c81147..9aed2aca9 100644
--- a/src/webenginewidgets/api/qwebenginehistory.cpp
+++ b/src/webenginewidgets/api/qwebenginehistory.cpp
@@ -92,6 +92,11 @@ QDateTime QWebEngineHistoryItem::lastVisited() const
return d->page ? d->page->webContents()->getNavigationEntryTimestamp(d->index) : QDateTime();
}
+/*!
+ Returns the URL of the icon associated with the history item.
+
+ \sa url(), originalUrl(), title()
+*/
QUrl QWebEngineHistoryItem::iconUrl() const
{
Q_D(const QWebEngineHistoryItem);
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 6207a2b30..93e229db8 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -23,9 +23,12 @@
#include "qwebenginepage.h"
#include "qwebenginepage_p.h"
+#include "authentication_dialog_controller.h"
#include "browser_context_adapter.h"
#include "certificate_error_controller.h"
+#include "file_picker_controller.h"
#include "javascript_dialog_controller.h"
+#include "qwebenginefullscreenrequest.h"
#include "qwebenginehistory.h"
#include "qwebenginehistory_p.h"
#include "qwebengineprofile.h"
@@ -54,6 +57,7 @@
#include <QLayout>
#include <QMenu>
#include <QMessageBox>
+#include <QMimeData>
#include <QStandardPaths>
#include <QStyle>
#include <QUrl>
@@ -77,106 +81,6 @@ static QWebEnginePage::WebWindowType toWindowType(WebContentsAdapterClient::Wind
}
}
-CallbackDirectory::~CallbackDirectory()
-{
- // "Cancel" pending callbacks by calling them with an invalid value.
- // This guarantees that each callback is called exactly once.
- Q_FOREACH (const CallbackSharedDataPointer &sharedPtr, m_callbackMap) {
- switch (sharedPtr.type) {
- case CallbackSharedDataPointer::Variant:
- (*sharedPtr.variantCallback)(QVariant());
- break;
- case CallbackSharedDataPointer::String:
- (*sharedPtr.stringCallback)(QString());
- break;
- case CallbackSharedDataPointer::Bool:
- (*sharedPtr.boolCallback)(false);
- break;
- default:
- Q_UNREACHABLE();
- }
- }
-}
-
-void CallbackDirectory::registerCallback(quint64 requestId, const QExplicitlySharedDataPointer<VariantCallback> &callback)
-{
- m_callbackMap.insert(requestId, CallbackSharedDataPointer(callback.data()));
-}
-
-void CallbackDirectory::registerCallback(quint64 requestId, const QExplicitlySharedDataPointer<StringCallback> &callback)
-{
- m_callbackMap.insert(requestId, CallbackSharedDataPointer(callback.data()));
-}
-
-void CallbackDirectory::registerCallback(quint64 requestId, const QExplicitlySharedDataPointer<BoolCallback> &callback)
-{
- m_callbackMap.insert(requestId, CallbackSharedDataPointer(callback.data()));
-}
-
-void CallbackDirectory::invoke(quint64 requestId, const QVariant &result)
-{
- CallbackSharedDataPointer sharedPtr = m_callbackMap.take(requestId);
- if (sharedPtr) {
- Q_ASSERT(sharedPtr.type == CallbackSharedDataPointer::Variant);
- (*sharedPtr.variantCallback)(result);
- }
-}
-
-void CallbackDirectory::invoke(quint64 requestId, const QString &result)
-{
- CallbackSharedDataPointer sharedPtr = m_callbackMap.take(requestId);
- if (sharedPtr) {
- Q_ASSERT(sharedPtr.type == CallbackSharedDataPointer::String);
- (*sharedPtr.stringCallback)(result);
- }
-}
-
-void CallbackDirectory::invoke(quint64 requestId, bool result)
-{
- CallbackSharedDataPointer sharedPtr = m_callbackMap.take(requestId);
- if (sharedPtr) {
- Q_ASSERT(sharedPtr.type == CallbackSharedDataPointer::Bool);
- (*sharedPtr.boolCallback)(result);
- }
-}
-
-void CallbackDirectory::CallbackSharedDataPointer::doRef()
-{
- switch (type) {
- case None:
- break;
- case Variant:
- variantCallback->ref.ref();
- break;
- case String:
- stringCallback->ref.ref();
- break;
- case Bool:
- boolCallback->ref.ref();
- break;
- }
-}
-
-void CallbackDirectory::CallbackSharedDataPointer::doDeref()
-{
- switch (type) {
- case None:
- break;
- case Variant:
- if (!variantCallback->ref.deref())
- delete variantCallback;
- break;
- case String:
- if (!stringCallback->ref.deref())
- delete stringCallback;
- break;
- case Bool:
- if (!boolCallback->ref.deref())
- delete boolCallback;
- break;
- }
-}
-
QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
: adapter(new WebContentsAdapter)
, history(new QWebEngineHistory(new QWebEngineHistoryPrivate(this)))
@@ -185,6 +89,8 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
, view(0)
, isLoading(false)
, scriptCollection(new QWebEngineScriptCollectionPrivate(browserContextAdapter()->userScriptController(), adapter.data()))
+ , m_backgroundColor(Qt::white)
+ , fullscreenMode(false)
{
memset(actions, 0, sizeof(actions));
}
@@ -247,6 +153,11 @@ qreal QWebEnginePagePrivate::dpiScale() const
return 1.0;
}
+QColor QWebEnginePagePrivate::backgroundColor() const
+{
+ return m_backgroundColor;
+}
+
void QWebEnginePagePrivate::loadStarted(const QUrl &provisionalUrl, bool isErrorPage)
{
Q_UNUSED(provisionalUrl);
@@ -314,6 +225,11 @@ void QWebEnginePagePrivate::close()
Q_EMIT q->windowCloseRequested();
}
+void QWebEnginePagePrivate::windowCloseRejected()
+{
+ // Do nothing for now.
+}
+
void QWebEnginePagePrivate::didRunJavaScript(quint64 requestId, const QVariant& result)
{
m_callbacks.invoke(requestId, result);
@@ -340,18 +256,24 @@ void QWebEnginePagePrivate::passOnFocus(bool reverse)
view->focusNextPrevChild(!reverse);
}
-void QWebEnginePagePrivate::authenticationRequired(const QUrl &requestUrl, const QString &realm, bool isProxy, const QString &challengingHost, QString *outUser, QString *outPassword)
+void QWebEnginePagePrivate::authenticationRequired(QSharedPointer<AuthenticationDialogController> controller)
{
Q_Q(QWebEnginePage);
QAuthenticator networkAuth;
- networkAuth.setRealm(realm);
+ networkAuth.setRealm(controller->realm());
- if (isProxy)
- Q_EMIT q->proxyAuthenticationRequired(requestUrl, &networkAuth, challengingHost);
+ if (controller->isProxy())
+ Q_EMIT q->proxyAuthenticationRequired(controller->url(), &networkAuth, controller->host());
else
- Q_EMIT q->authenticationRequired(requestUrl, &networkAuth);
- *outUser = networkAuth.user();
- *outPassword = networkAuth.password();
+ Q_EMIT q->authenticationRequired(controller->url(), &networkAuth);
+
+ // Authentication has been cancelled
+ if (networkAuth.isNull()) {
+ controller->reject();
+ return;
+ }
+
+ controller->accept(networkAuth.user(), networkAuth.password());
}
void QWebEnginePagePrivate::runMediaAccessPermissionRequest(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags requestFlags)
@@ -451,6 +373,14 @@ void QWebEnginePagePrivate::recreateFromSerializedHistory(QDataStream &input)
}
}
+void QWebEnginePagePrivate::setFullScreenMode(bool fullscreen)
+{
+ if (fullscreenMode != fullscreen) {
+ fullscreenMode = fullscreen;
+ adapter->changedFullScreen();
+ }
+}
+
BrowserContextAdapter *QWebEnginePagePrivate::browserContextAdapter()
{
return profile->d_ptr->browserContext();
@@ -466,10 +396,49 @@ QWebEnginePage::QWebEnginePage(QObject* parent)
}
/*!
- Constructs an empty QWebEnginePage in the QWebEngineProfile \a profile with parent \a parent.
+ \enum QWebEnginePage::RenderProcessTerminationStatus
+
+ This enum describes the status with which the render process terminated:
+
+ \value NormalTerminationStatus
+ The render process terminated normally.
+ \value AbnormalTerminationStatus
+ The render process terminated with with a non-zero exit status.
+ \value CrashedTerminationStatus
+ The render process crashed, for example because of a segmentation fault.
+ \value KilledTerminationStatus
+ The render process was killed, for example by \c SIGKILL or task manager kill.
+*/
- If the profile is not the default profile the caller must ensure the profile is alive for as
- long as the page is.
+/*!
+ \fn QWebEnginePage::renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode)
+
+ This signal is emitted when the render process is terminated with a non-zero exit status.
+ \a terminationStatus is the termination status of the process and \a exitCode is the status code
+ with which the process terminated.
+*/
+
+/*!
+ \fn QWebEnginePage::fullScreenRequested(const QWebEngineFullScreenRequest &request)
+
+ This signal is emitted when the web page issues the request to enter fullscreen mode for
+ a web-element, usually a video element.
+
+ The request object \a request can be used to accept or reject the request.
+
+ If the request is accepted the element requesting fullscreen will fill the viewport,
+ but it is up to the application to make the view fullscreen or move the page to a view
+ that is fullscreen.
+
+ \sa QWebEngineSettings::FullScreenSupportEnabled
+*/
+
+/*!
+ Constructs an empty web engine page in the web engine profile \a profile with the parent
+ \a parent.
+
+ If the profile is not the default profile, the caller must ensure that the profile stays alive
+ for as long as the page does.
\since 5.5
*/
@@ -501,12 +470,12 @@ QWebEngineSettings *QWebEnginePage::settings() const
}
/*!
- * Returns a pointer to the web channel instance used by this page, or a null pointer if none was set.
- * This channel is automatically using the internal QtWebEngine transport mechanism over Chromium IPC,
- * and exposed in the javascript context of this page as \c qt.webChannelTransport
+ * Returns a pointer to the web channel instance used by this page or a null pointer if none was set.
+ * This channel automatically uses the internal web engine transport mechanism over Chromium IPC
+ * that is exposed in the JavaScript context of this page as \c qt.webChannelTransport.
*
* \since 5.5
- * \sa {QtWebChannel::QWebChannel}{QWebChannel}
+ * \sa QWebChannel
*/
QWebChannel *QWebEnginePage::webChannel() const
{
@@ -515,14 +484,14 @@ QWebChannel *QWebEnginePage::webChannel() const
}
/*!
- * Sets the web channel instance to be used by this page and connects it to QtWebEngine's transport
- * using Chromium IPC messages. That transport is exposed in the javascript context of this page as
+ * Sets the web channel instance to be used by this page to \a channel and connects it to
+ * web engine's transport using Chromium IPC messages. The transport is exposed in the JavaScript
+ * context of this page as
* \c qt.webChannelTransport, which should be used when using the \l{Qt WebChannel JavaScript API}.
*
- * \note The page does not take ownership of the \a channel object.
+ * \note The page does not take ownership of the channel object.
*
* \since 5.5
- * \param channel
*/
void QWebEnginePage::setWebChannel(QWebChannel *channel)
@@ -531,6 +500,33 @@ void QWebEnginePage::setWebChannel(QWebChannel *channel)
d->adapter->setWebChannel(channel);
}
+/*!
+ \property QWebEnginePage::backgroundColor
+ \brief the page's background color behind the document's body.
+ \since 5.6
+
+ You can set the background color to Qt::transparent or to a translucent
+ color to see through the document, or you can set it to match your
+ web content in a hybrid application to prevent the white flashes that may appear
+ during loading.
+
+ The default value is white.
+*/
+QColor QWebEnginePage::backgroundColor() const
+{
+ Q_D(const QWebEnginePage);
+ return d->m_backgroundColor;
+}
+
+void QWebEnginePage::setBackgroundColor(const QColor &color)
+{
+ Q_D(QWebEnginePage);
+ if (d->m_backgroundColor == color)
+ return;
+ d->m_backgroundColor = color;
+ d->adapter->backgroundColorChanged();
+}
+
void QWebEnginePage::setView(QWidget *view)
{
QWebEngineViewPrivate::bind(qobject_cast<QWebEngineView*>(view), this);
@@ -543,7 +539,7 @@ QWidget *QWebEnginePage::view() const
}
/*!
- Returns the QWebEngineProfile the page belongs to.
+ Returns the web engine profile the page belongs to.
\since 5.5
*/
QWebEngineProfile *QWebEnginePage::profile() const
@@ -614,6 +610,57 @@ QAction *QWebEnginePage::action(WebAction action) const
case PasteAndMatchStyle:
text = tr("Paste and Match Style");
break;
+ case OpenLinkInThisWindow:
+ text = tr("Open Link in This Window");
+ break;
+ case OpenLinkInNewWindow:
+ text = tr("Open Link in New Window");
+ break;
+ case OpenLinkInNewTab:
+ text = tr("Open Link in New Tab");
+ break;
+ case CopyLinkToClipboard:
+ text = tr("Copy Link URL");
+ break;
+ case DownloadLinkToDisk:
+ text = tr("Save Link");
+ break;
+ case CopyImageToClipboard:
+ text = tr("Copy Image");
+ break;
+ case CopyImageUrlToClipboard:
+ text = tr("Copy Image URL");
+ break;
+ case DownloadImageToDisk:
+ text = tr("Save Image");
+ break;
+ case CopyMediaUrlToClipboard:
+ text = tr("Copy Media URL");
+ break;
+ case ToggleMediaControls:
+ text = tr("Toggle Media Controls");
+ break;
+ case ToggleMediaLoop:
+ text = tr("Toggle Looping");
+ break;
+ case ToggleMediaPlayPause:
+ text = tr("Toggle Play/Pause");
+ break;
+ case ToggleMediaMute:
+ text = tr("Toggle Mute");
+ break;
+ case DownloadMediaToDisk:
+ text = tr("Save Media");
+ break;
+ case InspectElement:
+ text = tr("Inspect Element");
+ break;
+ case ExitFullScreen:
+ text = tr("Exit Full Screen Mode");
+ break;
+ case RequestClose:
+ text = tr("Close Page");
+ break;
default:
break;
}
@@ -671,6 +718,122 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
case PasteAndMatchStyle:
d->adapter->pasteAndMatchStyle();
break;
+ case OpenLinkInThisWindow:
+ if (d->m_menuData.linkUrl.isValid())
+ setUrl(d->m_menuData.linkUrl);
+ break;
+ case OpenLinkInNewWindow:
+ if (d->m_menuData.linkUrl.isValid()) {
+ QWebEnginePage *newPage = createWindow(WebBrowserWindow);
+ if (newPage)
+ newPage->setUrl(d->m_menuData.linkUrl);
+ }
+ break;
+ case OpenLinkInNewTab:
+ if (d->m_menuData.linkUrl.isValid()) {
+ QWebEnginePage *newPage = createWindow(WebBrowserTab);
+ if (newPage)
+ newPage->setUrl(d->m_menuData.linkUrl);
+ }
+ break;
+ case CopyLinkToClipboard:
+ if (d->m_menuData.linkUrl.isValid()) {
+ QString urlString = d->m_menuData.linkUrl.toString(QUrl::FullyEncoded);
+ QString title = d->m_menuData.linkText.toHtmlEscaped();
+ QMimeData *data = new QMimeData();
+ data->setText(urlString);
+ QString html = QStringLiteral("<a href=\"") + urlString + QStringLiteral("\">") + title + QStringLiteral("</a>");
+ data->setHtml(html);
+ data->setUrls(QList<QUrl>() << d->m_menuData.linkUrl);
+ qApp->clipboard()->setMimeData(data);
+ }
+ break;
+ case DownloadLinkToDisk:
+ if (d->m_menuData.linkUrl.isValid())
+ d->adapter->download(d->m_menuData.linkUrl, d->m_menuData.suggestedFileName);
+ break;
+ case CopyImageToClipboard:
+ if (d->m_menuData.hasImageContent &&
+ (d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeImage ||
+ d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas))
+ {
+ d->adapter->copyImageAt(d->m_menuData.pos);
+ }
+ break;
+ case CopyImageUrlToClipboard:
+ if (d->m_menuData.mediaUrl.isValid() && d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeImage) {
+ QString urlString = d->m_menuData.mediaUrl.toString(QUrl::FullyEncoded);
+ QString title = d->m_menuData.linkText;
+ if (!title.isEmpty())
+ title = QStringLiteral(" alt=\"%1\"").arg(title.toHtmlEscaped());
+ QMimeData *data = new QMimeData();
+ data->setText(urlString);
+ QString html = QStringLiteral("<img src=\"") + urlString + QStringLiteral("\"") + title + QStringLiteral("></img>");
+ data->setHtml(html);
+ data->setUrls(QList<QUrl>() << d->m_menuData.mediaUrl);
+ qApp->clipboard()->setMimeData(data);
+ }
+ break;
+ case DownloadImageToDisk:
+ case DownloadMediaToDisk:
+ if (d->m_menuData.mediaUrl.isValid())
+ d->adapter->download(d->m_menuData.mediaUrl, d->m_menuData.suggestedFileName);
+ break;
+ case CopyMediaUrlToClipboard:
+ if (d->m_menuData.mediaUrl.isValid() &&
+ (d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio ||
+ d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo))
+ {
+ QString urlString = d->m_menuData.mediaUrl.toString(QUrl::FullyEncoded);
+ QMimeData *data = new QMimeData();
+ data->setText(urlString);
+ if (d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio)
+ data->setHtml(QStringLiteral("<audio src=\"") + urlString + QStringLiteral("\"></audio>"));
+ else
+ data->setHtml(QStringLiteral("<video src=\"") + urlString + QStringLiteral("\"></video>"));
+ data->setUrls(QList<QUrl>() << d->m_menuData.mediaUrl);
+ qApp->clipboard()->setMimeData(data);
+ }
+ break;
+ case ToggleMediaControls:
+ if (d->m_menuData.mediaUrl.isValid() && d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) {
+ bool enable = !(d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaControls);
+ d->adapter->executeMediaPlayerActionAt(d->m_menuData.pos, WebContentsAdapter::MediaPlayerControls, enable);
+ }
+ break;
+ case ToggleMediaLoop:
+ if (d->m_menuData.mediaUrl.isValid() &&
+ (d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio ||
+ d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo))
+ {
+ bool enable = !(d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaLoop);
+ d->adapter->executeMediaPlayerActionAt(d->m_menuData.pos, WebContentsAdapter::MediaPlayerLoop, enable);
+ }
+ break;
+ case ToggleMediaPlayPause:
+ if (d->m_menuData.mediaUrl.isValid() &&
+ (d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio ||
+ d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo))
+ {
+ bool enable = (d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaPaused);
+ d->adapter->executeMediaPlayerActionAt(d->m_menuData.pos, WebContentsAdapter::MediaPlayerPlay, enable);
+ }
+ break;
+ case ToggleMediaMute:
+ if (d->m_menuData.mediaUrl.isValid() && d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) {
+ bool enable = (d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaMuted);
+ d->adapter->executeMediaPlayerActionAt(d->m_menuData.pos, WebContentsAdapter::MediaPlayerMute, enable);
+ }
+ break;
+ case InspectElement:
+ d->adapter->inspectElementAt(d->m_menuData.pos);
+ break;
+ case ExitFullScreen:
+ d->adapter->exitFullScreen();
+ break;
+ case RequestClose:
+ d->adapter->requestClose();
+ break;
default:
Q_UNREACHABLE();
}
@@ -681,12 +844,10 @@ void QWebEnginePage::findText(const QString &subString, FindFlags options, const
Q_D(QWebEnginePage);
if (subString.isEmpty()) {
d->adapter->stopFinding();
- if (resultCallback.d)
- (*resultCallback.d)(false);
+ d->m_callbacks.invokeEmpty(resultCallback);
} else {
quint64 requestId = d->adapter->findText(subString, options & FindCaseSensitively, options & FindBackward);
- if (resultCallback.d)
- d->m_callbacks.registerCallback(requestId, resultCallback.d);
+ d->m_callbacks.registerCallback(requestId, resultCallback);
}
}
@@ -703,6 +864,7 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData
if (!view)
return false;
+ m_menuData = WebEngineContextMenuData();
QContextMenuEvent event(QContextMenuEvent::Mouse, data.pos, view->mapToGlobal(data.pos));
switch (view->contextMenuPolicy()) {
case Qt::PreventContextMenu:
@@ -727,7 +889,6 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData
}
Q_ASSERT(view->d_func()->m_pendingContextMenuEvent);
view->d_func()->m_pendingContextMenuEvent = false;
- m_menuData = WebEngineContextMenuData();
return true;
}
@@ -738,6 +899,18 @@ void QWebEnginePagePrivate::navigationRequested(int navigationType, const QUrl &
navigationRequestAction = accepted ? WebContentsAdapterClient::AcceptRequest : WebContentsAdapterClient::IgnoreRequest;
}
+void QWebEnginePagePrivate::requestFullScreenMode(const QUrl &origin, bool fullscreen)
+{
+ Q_Q(QWebEnginePage);
+ QWebEngineFullScreenRequest request(this, origin, fullscreen);
+ Q_EMIT q->fullScreenRequested(request);
+}
+
+bool QWebEnginePagePrivate::isFullScreenMode() const
+{
+ return fullscreenMode;
+}
+
void QWebEnginePagePrivate::javascriptDialog(QSharedPointer<JavaScriptDialogController> controller)
{
Q_Q(QWebEnginePage);
@@ -756,6 +929,9 @@ void QWebEnginePagePrivate::javascriptDialog(QSharedPointer<JavaScriptDialogCont
if (accepted)
controller->textProvided(promptResult);
break;
+ case UnloadDialog:
+ accepted = (QMessageBox::information(view, QCoreApplication::translate("QWebEnginePage", "Are you sure you want to leave this page?"), controller->message(), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes);
+ break;
case InternalAuthorizationDialog:
accepted = (QMessageBox::question(view, controller->title(), controller->message(), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes);
break;
@@ -807,34 +983,12 @@ void QWebEnginePagePrivate::moveValidationMessage(const QRect &anchor)
#endif
}
-namespace {
-class SaveToClipboardFunctor
+void QWebEnginePagePrivate::renderProcessTerminated(RenderProcessTerminationStatus terminationStatus,
+ int exitCode)
{
- QString m_text;
-public:
- SaveToClipboardFunctor(const QString &text)
- : m_text(text)
- {}
- void operator()() const
- {
- qApp->clipboard()->setText(m_text);
- }
-};
-
-class LoadUrlFunctor
-{
- QWebEnginePage *m_page;
- QUrl m_url;
-public:
- LoadUrlFunctor(QWebEnginePage *page, const QUrl &url)
- : m_page(page)
- , m_url(url)
- {}
- void operator()() const
- {
- m_page->load(m_url);
- }
-};
+ Q_Q(QWebEnginePage);
+ Q_EMIT q->renderProcessTerminated(static_cast<QWebEnginePage::RenderProcessTerminationStatus>(
+ terminationStatus), exitCode);
}
QMenu *QWebEnginePage::createStandardContextMenu()
@@ -843,6 +997,12 @@ QMenu *QWebEnginePage::createStandardContextMenu()
QMenu *menu = new QMenu(d->view);
QAction *action = 0;
WebEngineContextMenuData contextMenuData(d->m_menuData);
+ if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) {
+ action = QWebEnginePage::action(OpenLinkInThisWindow);
+ action->setText(tr("Follow Link"));
+ menu->addAction(action);
+ menu->addAction(QWebEnginePage::action(DownloadLinkToDisk));
+ }
if (contextMenuData.selectedText.isEmpty()) {
action = new QAction(QIcon::fromTheme(QStringLiteral("go-previous")), tr("&Back"), menu);
connect(action, &QAction::triggered, d->view, &QWebEngineView::back);
@@ -858,20 +1018,46 @@ QMenu *QWebEnginePage::createStandardContextMenu()
connect(action, &QAction::triggered, d->view, &QWebEngineView::reload);
menu->addAction(action);
} else {
- action = new QAction(tr("Copy..."), menu);
- connect(action, &QAction::triggered, SaveToClipboardFunctor(contextMenuData.selectedText));
- menu->addAction(action);
+ menu->addAction(QWebEnginePage::action(Copy));
}
if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) {
- menu->addSeparator();
- action = new QAction(tr("Navigate to..."), menu);
- connect(action, &QAction::triggered, LoadUrlFunctor(this, contextMenuData.linkUrl));
- menu->addAction(action);
- action = new QAction(tr("Copy link address"), menu);
- connect(action, &QAction::triggered, SaveToClipboardFunctor(contextMenuData.linkUrl.toString()));
- menu->addAction(action);
+ menu->addAction(QWebEnginePage::action(CopyLinkToClipboard));
+ }
+ if (contextMenuData.mediaUrl.isValid()) {
+ switch (contextMenuData.mediaType) {
+ case WebEngineContextMenuData::MediaTypeImage:
+ menu->addAction(QWebEnginePage::action(DownloadImageToDisk));
+ menu->addAction(QWebEnginePage::action(CopyImageUrlToClipboard));
+ menu->addAction(QWebEnginePage::action(CopyImageToClipboard));
+ break;
+ case WebEngineContextMenuData::MediaTypeCanvas:
+ Q_UNREACHABLE(); // mediaUrl is invalid for canvases
+ break;
+ case WebEngineContextMenuData::MediaTypeAudio:
+ case WebEngineContextMenuData::MediaTypeVideo:
+ menu->addAction(QWebEnginePage::action(DownloadMediaToDisk));
+ menu->addAction(QWebEnginePage::action(CopyMediaUrlToClipboard));
+ menu->addAction(QWebEnginePage::action(ToggleMediaPlayPause));
+ menu->addAction(QWebEnginePage::action(ToggleMediaLoop));
+ if (d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio)
+ menu->addAction(QWebEnginePage::action(ToggleMediaMute));
+ if (d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls)
+ menu->addAction(QWebEnginePage::action(ToggleMediaControls));
+ break;
+ default:
+ break;
+ }
+ } else if (contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas) {
+ menu->addAction(QWebEnginePage::action(CopyImageToClipboard));
}
+
+ if (d->adapter->hasInspector())
+ menu->addAction(QWebEnginePage::action(InspectElement));
+
+ if (d->isFullScreenMode())
+ menu->addAction(QWebEnginePage::action(ExitFullScreen));
+
return menu;
}
@@ -914,17 +1100,22 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine
}
}
-static inline QWebEnginePage::FileSelectionMode toPublic(WebContentsAdapterClient::FileChooserMode mode)
+static inline QWebEnginePage::FileSelectionMode toPublic(FilePickerController::FileChooserMode mode)
{
// Should the underlying values change, we'll need a switch here.
return static_cast<QWebEnginePage::FileSelectionMode>(mode);
}
-void QWebEnginePagePrivate::runFileChooser(WebContentsAdapterClient::FileChooserMode mode, const QString &defaultFileName, const QStringList &acceptedMimeTypes)
+void QWebEnginePagePrivate::runFileChooser(FilePickerController *controller)
{
Q_Q(QWebEnginePage);
- QStringList selectedFileNames = q->chooseFiles(toPublic(mode), (QStringList() << defaultFileName), acceptedMimeTypes);
- adapter->filesSelectedInChooser(selectedFileNames, mode);
+
+ QStringList selectedFileNames = q->chooseFiles(toPublic(controller->mode()), (QStringList() << controller->defaultFileName()), controller->acceptedMimeTypes());
+
+ if (!selectedFileNames.empty())
+ controller->accepted(selectedFileNames);
+ else
+ controller->rejected();
}
WebEngineSettings *QWebEnginePagePrivate::webEngineSettings() const
@@ -942,14 +1133,14 @@ void QWebEnginePage::toHtml(const QWebEngineCallback<const QString &> &resultCal
{
Q_D(const QWebEnginePage);
quint64 requestId = d->adapter->fetchDocumentMarkup();
- d->m_callbacks.registerCallback(requestId, resultCallback.d);
+ d->m_callbacks.registerCallback(requestId, resultCallback);
}
void QWebEnginePage::toPlainText(const QWebEngineCallback<const QString &> &resultCallback) const
{
Q_D(const QWebEnginePage);
quint64 requestId = d->adapter->fetchDocumentInnerText();
- d->m_callbacks.registerCallback(requestId, resultCallback.d);
+ d->m_callbacks.registerCallback(requestId, resultCallback);
}
void QWebEnginePage::setHtml(const QString &html, const QUrl &baseUrl)
@@ -1016,7 +1207,7 @@ void QWebEnginePage::runJavaScript(const QString& scriptSource, const QWebEngine
{
Q_D(QWebEnginePage);
quint64 requestId = d->adapter->runJavaScriptCallbackResult(scriptSource);
- d->m_callbacks.registerCallback(requestId, resultCallback.d);
+ d->m_callbacks.registerCallback(requestId, resultCallback);
}
/*!
@@ -1041,8 +1232,8 @@ QWebEnginePage *QWebEnginePage::createWindow(WebWindowType type)
return 0;
}
-ASSERT_ENUMS_MATCH(WebContentsAdapterClient::Open, QWebEnginePage::FileSelectOpen)
-ASSERT_ENUMS_MATCH(WebContentsAdapterClient::OpenMultiple, QWebEnginePage::FileSelectOpenMultiple)
+ASSERT_ENUMS_MATCH(FilePickerController::Open, QWebEnginePage::FileSelectOpen)
+ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, QWebEnginePage::FileSelectOpenMultiple)
QStringList QWebEnginePage::chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes)
{
@@ -1051,23 +1242,23 @@ QStringList QWebEnginePage::chooseFiles(FileSelectionMode mode, const QStringLis
Q_UNUSED(acceptedMimeTypes);
QStringList ret;
QString str;
- switch (static_cast<WebContentsAdapterClient::FileChooserMode>(mode)) {
- case WebContentsAdapterClient::OpenMultiple:
+ switch (static_cast<FilePickerController::FileChooserMode>(mode)) {
+ case FilePickerController::OpenMultiple:
ret = QFileDialog::getOpenFileNames(view(), QString());
break;
// Chromium extension, not exposed as part of the public API for now.
- case WebContentsAdapterClient::UploadFolder:
+ case FilePickerController::UploadFolder:
str = QFileDialog::getExistingDirectory(view(), tr("Select folder to upload")) + QLatin1Char('/');
if (!str.isNull())
ret << str;
break;
- case WebContentsAdapterClient::Save:
+ case FilePickerController::Save:
str = QFileDialog::getSaveFileName(view(), QString(), (QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + oldFiles.first()));
if (!str.isNull())
ret << str;
break;
default:
- case WebContentsAdapterClient::Open:
+ case FilePickerController::Open:
str = QFileDialog::getOpenFileName(view(), QString(), oldFiles.first());
if (!str.isNull())
ret << str;
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index b4cf52298..07b27deee 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -37,8 +37,9 @@
#ifndef QWEBENGINEPAGE_H
#define QWEBENGINEPAGE_H
-#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h>
-#include <QtWebEngineWidgets/qwebenginecertificateerror.h>
+#include <qtwebenginewidgetsglobal.h>
+#include <qwebenginecertificateerror.h>
+#include <qwebenginecallback.h>
#include <QtCore/qobject.h>
#include <QtCore/qurl.h>
@@ -49,6 +50,7 @@
QT_BEGIN_NAMESPACE
class QMenu;
class QWebChannel;
+class QWebEngineFullScreenRequest;
class QWebEngineHistory;
class QWebEnginePage;
class QWebEnginePagePrivate;
@@ -56,37 +58,6 @@ class QWebEngineProfile;
class QWebEngineScriptCollection;
class QWebEngineSettings;
-namespace QtWebEnginePrivate {
-
-template <typename T>
-class QWebEngineCallbackPrivateBase : public QSharedData {
-public:
- virtual ~QWebEngineCallbackPrivateBase() {}
- virtual void operator()(T) = 0;
-};
-
-template <typename T, typename F>
-class QWebEngineCallbackPrivate : public QWebEngineCallbackPrivateBase<T> {
-public:
- QWebEngineCallbackPrivate(F callable) : m_callable(callable) {}
- virtual void operator()(T value) Q_DECL_OVERRIDE { m_callable(value); }
-private:
- F m_callable;
-};
-
-} // namespace QtWebEnginePrivate
-
-template <typename T>
-class QWebEngineCallback {
-public:
- template <typename F>
- QWebEngineCallback(F f) : d(new QtWebEnginePrivate::QWebEngineCallbackPrivate<T, F>(f)) { }
- QWebEngineCallback() { }
-private:
- QExplicitlySharedDataPointer<QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> > d;
- friend class QWebEnginePage;
-};
-
class QWEBENGINEWIDGETS_EXPORT QWebEnginePage : public QObject {
Q_OBJECT
Q_PROPERTY(QString selectedText READ selectedText)
@@ -98,6 +69,7 @@ class QWEBENGINEWIDGETS_EXPORT QWebEnginePage : public QObject {
Q_PROPERTY(QString title READ title)
Q_PROPERTY(QUrl url READ url WRITE setUrl)
Q_PROPERTY(QUrl iconUrl READ iconUrl)
+ Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
public:
enum WebAction {
@@ -118,6 +90,27 @@ public:
PasteAndMatchStyle,
+ OpenLinkInThisWindow,
+ OpenLinkInNewWindow,
+ OpenLinkInNewTab,
+ CopyLinkToClipboard,
+ DownloadLinkToDisk,
+
+ CopyImageToClipboard,
+ CopyImageUrlToClipboard,
+ DownloadImageToDisk,
+
+ CopyMediaUrlToClipboard,
+ ToggleMediaControls,
+ ToggleMediaLoop,
+ ToggleMediaPlayPause,
+ ToggleMediaMute,
+ DownloadMediaToDisk,
+
+ InspectElement,
+ ExitFullScreen,
+ RequestClose,
+
WebActionCount
};
@@ -174,6 +167,14 @@ public:
ErrorMessageLevel
};
+ // must match WebContentsAdapterClient::RenderProcessTerminationStatus
+ enum RenderProcessTerminationStatus {
+ NormalTerminationStatus = 0,
+ AbnormalTerminationStatus,
+ CrashedTerminationStatus,
+ KilledTerminationStatus
+ };
+
explicit QWebEnginePage(QObject *parent = 0);
QWebEnginePage(QWebEngineProfile *profile, QObject *parent = 0);
~QWebEnginePage();
@@ -236,6 +237,8 @@ public:
QWebChannel *webChannel() const;
void setWebChannel(QWebChannel *);
+ QColor backgroundColor() const;
+ void setBackgroundColor(const QColor &color);
Q_SIGNALS:
void loadStarted();
@@ -249,10 +252,13 @@ Q_SIGNALS:
void featurePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
void featurePermissionRequestCanceled(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
+ void fullScreenRequested(const QWebEngineFullScreenRequest &fullScreenRequest);
void authenticationRequired(const QUrl &requestUrl, QAuthenticator *authenticator);
void proxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *authenticator, const QString &proxyHost);
+ void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode);
+
// Ex-QWebFrame signals
void titleChanged(const QString &title);
void urlChanged(const QUrl &url);
@@ -261,7 +267,6 @@ Q_SIGNALS:
protected:
virtual QWebEnginePage *createWindow(WebWindowType type);
-
virtual QStringList chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes);
virtual void javaScriptAlert(const QUrl &securityOrigin, const QString& msg);
virtual bool javaScriptConfirm(const QUrl &securityOrigin, const QString& msg);
@@ -271,6 +276,7 @@ protected:
virtual bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame);
private:
+ Q_DISABLE_COPY(QWebEnginePage)
Q_DECLARE_PRIVATE(QWebEnginePage)
QScopedPointer<QWebEnginePagePrivate> d_ptr;
#ifndef QT_NO_ACTION
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 0fcd05d3c..8009336ec 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -50,10 +50,10 @@
#include "qwebenginepage.h"
+#include "qwebenginecallback_p.h"
#include "qwebenginescriptcollection.h"
#include "web_contents_adapter_client.h"
#include <QtCore/qcompilerdetection.h>
-#include <QSharedData>
namespace QtWebEngineCore {
class RenderWidgetHostViewQtDelegate;
@@ -67,49 +67,6 @@ class QWebEngineProfile;
class QWebEngineSettings;
class QWebEngineView;
-class CallbackDirectory {
-public:
- typedef QtWebEnginePrivate::QWebEngineCallbackPrivateBase<const QVariant&> VariantCallback;
- typedef QtWebEnginePrivate::QWebEngineCallbackPrivateBase<const QString&> StringCallback;
- typedef QtWebEnginePrivate::QWebEngineCallbackPrivateBase<bool> BoolCallback;
-
- ~CallbackDirectory();
- void registerCallback(quint64 requestId, const QExplicitlySharedDataPointer<VariantCallback> &callback);
- void registerCallback(quint64 requestId, const QExplicitlySharedDataPointer<StringCallback> &callback);
- void registerCallback(quint64 requestId, const QExplicitlySharedDataPointer<BoolCallback> &callback);
- void invoke(quint64 requestId, const QVariant &result);
- void invoke(quint64 requestId, const QString &result);
- void invoke(quint64 requestId, bool result);
-
-private:
- struct CallbackSharedDataPointer {
- enum {
- None,
- Variant,
- String,
- Bool
- } type;
- union {
- VariantCallback *variantCallback;
- StringCallback *stringCallback;
- BoolCallback *boolCallback;
- };
- CallbackSharedDataPointer() : type(None) { }
- CallbackSharedDataPointer(VariantCallback *callback) : type(Variant), variantCallback(callback) { callback->ref.ref(); }
- CallbackSharedDataPointer(StringCallback *callback) : type(String), stringCallback(callback) { callback->ref.ref(); }
- CallbackSharedDataPointer(BoolCallback *callback) : type(Bool), boolCallback(callback) { callback->ref.ref(); }
- CallbackSharedDataPointer(const CallbackSharedDataPointer &other) : type(other.type), variantCallback(other.variantCallback) { doRef(); }
- ~CallbackSharedDataPointer() { doDeref(); }
- operator bool () const { return type != None; }
-
- private:
- void doRef();
- void doDeref();
- };
-
- QHash<quint64, CallbackSharedDataPointer> m_callbackMap;
-};
-
class QWebEnginePagePrivate : public QtWebEngineCore::WebContentsAdapterClient
{
public:
@@ -129,6 +86,7 @@ public:
virtual void selectionChanged() Q_DECL_OVERRIDE;
virtual QRectF viewportRect() const Q_DECL_OVERRIDE;
virtual qreal dpiScale() const Q_DECL_OVERRIDE;
+ virtual QColor backgroundColor() const Q_DECL_OVERRIDE;
virtual void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) Q_DECL_OVERRIDE;
virtual void loadCommitted() Q_DECL_OVERRIDE;
virtual void loadVisuallyCommitted() Q_DECL_OVERRIDE { }
@@ -137,19 +95,20 @@ public:
virtual void unhandledKeyEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
virtual void adoptNewWindow(QtWebEngineCore::WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &initialGeometry) Q_DECL_OVERRIDE;
virtual void close() Q_DECL_OVERRIDE;
+ virtual void windowCloseRejected() Q_DECL_OVERRIDE;
virtual bool contextMenuRequested(const QtWebEngineCore::WebEngineContextMenuData &data) Q_DECL_OVERRIDE;
virtual void navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) Q_DECL_OVERRIDE;
- virtual void requestFullScreen(bool) Q_DECL_OVERRIDE { }
- virtual bool isFullScreen() const Q_DECL_OVERRIDE { return false; }
+ virtual void requestFullScreenMode(const QUrl &origin, bool fullscreen) Q_DECL_OVERRIDE;
+ virtual bool isFullScreenMode() const Q_DECL_OVERRIDE;
virtual void javascriptDialog(QSharedPointer<QtWebEngineCore::JavaScriptDialogController>) Q_DECL_OVERRIDE;
- virtual void runFileChooser(FileChooserMode, const QString &defaultFileName, const QStringList &acceptedMimeTypes) Q_DECL_OVERRIDE;
+ virtual void runFileChooser(QtWebEngineCore::FilePickerController *controller) Q_DECL_OVERRIDE;
virtual void didRunJavaScript(quint64 requestId, const QVariant& result) Q_DECL_OVERRIDE;
virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) Q_DECL_OVERRIDE;
virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) Q_DECL_OVERRIDE;
virtual void didFindText(quint64 requestId, int matchCount) Q_DECL_OVERRIDE;
virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE;
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
- virtual void authenticationRequired(const QUrl &requestUrl, const QString &realm, bool isProxy, const QString &challengingHost, QString *outUser, QString *outPassword) Q_DECL_OVERRIDE;
+ virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE;
virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) Q_DECL_OVERRIDE;
virtual void runGeolocationPermissionRequest(const QUrl &securityOrigin) Q_DECL_OVERRIDE;
virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) Q_DECL_OVERRIDE;
@@ -161,6 +120,8 @@ public:
virtual void showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText) Q_DECL_OVERRIDE;
virtual void hideValidationMessage() Q_DECL_OVERRIDE;
virtual void moveValidationMessage(const QRect &anchor) Q_DECL_OVERRIDE;
+ virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus,
+ int exitCode) Q_DECL_OVERRIDE;
virtual QtWebEngineCore::BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE;
@@ -171,18 +132,21 @@ public:
QtWebEngineCore::WebContentsAdapter *webContents() { return adapter.data(); }
void recreateFromSerializedHistory(QDataStream &input);
+ void setFullScreenMode(bool);
+
QExplicitlySharedDataPointer<QtWebEngineCore::WebContentsAdapter> adapter;
QWebEngineHistory *history;
QWebEngineProfile *profile;
QWebEngineSettings *settings;
QWebEngineView *view;
- QSize viewportSize;
QUrl explicitUrl;
QtWebEngineCore::WebEngineContextMenuData m_menuData;
bool isLoading;
QWebEngineScriptCollection scriptCollection;
+ QColor m_backgroundColor;
+ bool fullscreenMode;
- mutable CallbackDirectory m_callbacks;
+ mutable QtWebEngineCore::CallbackDirectory m_callbacks;
mutable QAction *actions[QWebEnginePage::WebActionCount];
};
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index fee57f5ec..07deeeefc 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -36,12 +36,12 @@
#include "qwebengineprofile.h"
+#include "qwebenginecookiestoreclient.h"
#include "qwebenginedownloaditem.h"
#include "qwebenginedownloaditem_p.h"
#include "qwebenginepage.h"
#include "qwebengineprofile_p.h"
#include "qwebenginesettings.h"
-#include "qwebengineurlschemehandler_p_p.h"
#include "qwebenginescriptcollection_p.h"
#include "browser_context_adapter.h"
@@ -59,30 +59,37 @@ using QtWebEngineCore::BrowserContextAdapter;
\inmodule QtWebEngineWidgets
- QWebEngineProfile contains settings and history shared by all QWebEnginePages that belong
- to the profile.
+ QWebEngineProfile contains settings, scripts, and the list of visited links shared by all
+ web engine pages that belong to the profile. As such, profiles can be used to isolate pages
+ from each other. A typical use case is a dedicated profile for a 'private browsing' mode.
- A default profile is built-in that all web pages not specifically created with another profile
- belongs to.
+ The default profile is a built-in profile that all web pages not specifically created with
+ another profile belong to.
*/
/*!
\enum QWebEngineProfile::HttpCacheType
- This enum describes the HTTP cache types QtWebEngine can be configured to use.
+ This enum describes the HTTP cache type:
- \value MemoryHttpCache Use a in-memory cache. This is the only setting possible if off-the-record is set or no cache path is available.
+ \value MemoryHttpCache Use an in-memory cache. This is the only setting possible if
+ \c off-the-record is set or no cache path is available.
\value DiskHttpCache Use a disk cache. This is the default.
*/
/*!
\enum QWebEngineProfile::PersistentCookiesPolicy
- This enum describes policy for cookie persistency.
+ This enum describes policy for cookie persistency:
- \value NoPersistentCookies Both session and persistent cookies are stored in memory. This is the only setting possible if off-the-record is set or no persistent data path is available.
- \value AllowPersistentCookies Cookies marked persistent are save and restored from disk, session cookies are only stored to disk for crash recovery. This is the default setting.
- \value ForcePersistentCookies Both session and persistent cookies are save and restored from disk.
+ \value NoPersistentCookies
+ Both session and persistent cookies are stored in memory. This is the only setting
+ possible if \c off-the-record is set or no persistent data path is available.
+ \value AllowPersistentCookies
+ Cookies marked persistent are saved to and restored from disk, whereas session cookies
+ are only stored to disk for crash recovery. This is the default setting.
+ \value ForcePersistentCookies
+ Both session and persistent cookies are saved to and restored from disk.
*/
/*!
@@ -92,12 +99,11 @@ using QtWebEngineCore::BrowserContextAdapter;
This signal is emitted whenever a download has been triggered.
The \a download argument holds the state of the download.
- The \a download either has to be explicitly accepted with
- QWebEngineDownloadItem::accept(), else the download will be
+ The download has to be explicitly accepted with QWebEngineDownloadItem::accept() or it will be
cancelled by default.
- The download item is parented by the profile, but if not accepted
+ The download item is parented by the profile. If it is not accepted, it
will be deleted immediately after the signal emission.
- This signal can not be used with a queued connection.
+ This signal cannot be used with a queued connection.
\sa QWebEngineDownloadItem
*/
@@ -183,10 +189,10 @@ void QWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info)
}
/*!
- Constructs a new off-the-record profile.
+ Constructs a new off-the-record profile with the parent \a parent.
An off-the-record profile leaves no record on the local machine, and has no persistent data or cache.
- Thus, the HTTP cache can only be in memory and the cookies only be non-persistent, trying to change
+ Thus, the HTTP cache can only be in memory and the cookies can only be non-persistent. Trying to change
these settings will have no effect.
\sa isOffTheRecord()
@@ -199,7 +205,7 @@ QWebEngineProfile::QWebEngineProfile(QObject *parent)
}
/*!
- Constructs a new profile with storage name \a storageName.
+ Constructs a new profile with the storage name \a storageName and parent \a parent.
The storage name must be unique.
@@ -242,7 +248,7 @@ QString QWebEngineProfile::storageName() const
}
/*!
- Returns true if this is an off-the-record profile that leaves no record on the computer.
+ Returns \c true if this is an off-the-record profile that leaves no record on the computer.
This will force cookies and HTTP cache to be in memory, but also force all other normally
persistent data to be stored in memory.
@@ -256,9 +262,10 @@ bool QWebEngineProfile::isOffTheRecord() const
/*!
Returns the path used to store persistent data for the browser and web content.
- Persistent data includes persistent cookies, HTML5 local storage and visited links.
+ Persistent data includes persistent cookies, HTML5 local storage, and visited links.
- By default this is below QStandardPaths::writableLocation(QStandardPaths::DataLocation) in a storage name specific directory.
+ By default, this is below QStandardPaths::writableLocation() in a storage name specific
+ directory.
\sa setPersistentStoragePath(), storageName(), QStandardPaths::writableLocation()
*/
@@ -271,7 +278,7 @@ QString QWebEngineProfile::persistentStoragePath() const
/*!
Overrides the default path used to store persistent web engine data.
- If set to the null string, the default path is restored.
+ If \a path is set to the null string, the default path is restored.
\sa persistentStoragePath()
*/
@@ -284,7 +291,8 @@ void QWebEngineProfile::setPersistentStoragePath(const QString &path)
/*!
Returns the path used for caches.
- By default this is below QStandardPaths::writableLocation(QStandardPaths::CacheLocation) in a storage name specific directory.
+ By default, this is below QStandardPaths::writableLocation() in a storage name specific
+ directory.
\sa setCachePath(), storageName(), QStandardPaths::writableLocation()
*/
@@ -295,7 +303,7 @@ QString QWebEngineProfile::cachePath() const
}
/*!
- Overrides the default path used for disk caches.
+ Overrides the default path used for disk caches, setting it to \a path.
If set to the null string, the default path is restored.
@@ -308,7 +316,7 @@ void QWebEngineProfile::setCachePath(const QString &path)
}
/*!
- Returns the user-agent string send with HTTP to identify the browser.
+ Returns the user-agent string sent with HTTP to identify the browser.
\sa setHttpUserAgent()
*/
@@ -332,7 +340,7 @@ void QWebEngineProfile::setHttpUserAgent(const QString &userAgent)
/*!
Returns the type of HTTP cache used.
- If the profile is off-the-record MemoryHttpCache is returned.
+ If the profile is off-the-record, MemoryHttpCache is returned.
\sa setHttpCacheType(), cachePath()
*/
@@ -354,9 +362,31 @@ void QWebEngineProfile::setHttpCacheType(QWebEngineProfile::HttpCacheType httpCa
}
/*!
+ Sets the value of the Accept-Language HTTP request-header field to \a httpAcceptLanguage.
+
+ \since 5.6
+ */
+void QWebEngineProfile::setHttpAcceptLanguage(const QString &httpAcceptLanguage)
+{
+ Q_D(QWebEngineProfile);
+ d->browserContext()->setHttpAcceptLanguage(httpAcceptLanguage);
+}
+
+/*!
+ Returns the value of the Accept-Language HTTP request-header field.
+
+ \since 5.6
+ */
+QString QWebEngineProfile::httpAcceptLanguage() const
+{
+ Q_D(const QWebEngineProfile);
+ return d->browserContext()->httpAcceptLanguage();
+}
+
+/*!
Returns the current policy for persistent cookies.
- If the profile is off-the-record NoPersistentCookies is returned.
+ If the profile is off-the-record, NoPersistentCookies is returned.
\sa setPersistentCookiesPolicy()
*/
@@ -378,9 +408,9 @@ void QWebEngineProfile::setPersistentCookiesPolicy(QWebEngineProfile::Persistent
}
/*!
- Returns the maximum size of the HTTP size.
+ Returns the maximum size of the HTTP cache in bytes.
- Will return 0 if the size is automatically controlled by QtWebEngine.
+ Will return \c 0 if the size is automatically controlled by QtWebEngine.
\sa setHttpCacheMaximumSize(), httpCacheType()
*/
@@ -391,9 +421,9 @@ int QWebEngineProfile::httpCacheMaximumSize() const
}
/*!
- Sets the maximum size of the HTTP cache to \a maxSize.
+ Sets the maximum size of the HTTP cache to \a maxSize bytes.
- Setting it to 0 means the size will be controlled automatically by QtWebEngine.
+ Setting it to \c 0 means the size will be controlled automatically by QtWebEngine.
\sa httpCacheMaximumSize(), setHttpCacheType()
*/
@@ -404,6 +434,31 @@ void QWebEngineProfile::setHttpCacheMaximumSize(int maxSize)
}
/*!
+ Returns the cookie store client singleton, if one has been set.
+*/
+
+QWebEngineCookieStoreClient* QWebEngineProfile::cookieStoreClient()
+{
+ Q_D(QWebEngineProfile);
+ return d->browserContext()->cookieStoreClient();
+}
+
+
+/*!
+ Registers a request interceptor singleton \a interceptor to intercept URL requests.
+
+ The profile does not take ownership of the pointer.
+
+ \sa QWebEngineUrlRequestInfo
+*/
+
+void QWebEngineProfile::setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
+{
+ Q_D(QWebEngineProfile);
+ d->browserContext()->setRequestInterceptor(interceptor);
+}
+
+/*!
Clears all links from the visited links database.
\sa clearVisitedLinks()
@@ -426,7 +481,7 @@ void QWebEngineProfile::clearVisitedLinks(const QList<QUrl> &urls)
}
/*!
- Returns true if \a url is considered a visited link by this profile.
+ Returns \c true if \a url is considered a visited link by this profile.
*/
bool QWebEngineProfile::visitedLinksContainsUrl(const QUrl &url) const
{
@@ -468,10 +523,16 @@ QWebEngineSettings *QWebEngineProfile::settings() const
return d->settings();
}
-QWebEngineUrlSchemeHandler *QWebEngineProfilePrivate::urlSchemeHandler(const QByteArray &protocol)
+/*!
+ \since 5.6
+
+ Returns the custom URL scheme handler register for the URL scheme \a scheme.
+*/
+const QWebEngineUrlSchemeHandler *QWebEngineProfile::urlSchemeHandler(const QByteArray &scheme) const
{
- if (m_urlSchemeHandlers.contains(protocol))
- return m_urlSchemeHandlers.value(protocol);
+ const Q_D(QWebEngineProfile);
+ if (d->browserContext()->customUrlSchemeHandlers().contains(scheme))
+ return d->browserContext()->customUrlSchemeHandlers().value(scheme);
return 0;
}
@@ -485,38 +546,76 @@ static bool checkInternalScheme(const QByteArray &scheme)
return internalSchemes.contains(scheme);
}
-void QWebEngineProfilePrivate::installUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
+/*!
+ \since 5.6
+
+ Registers a handler \a handler for custom URL scheme \a scheme in the profile.
+*/
+void QWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
{
+ Q_D(QWebEngineProfile);
Q_ASSERT(handler);
- QByteArray scheme = handler->scheme();
if (checkInternalScheme(scheme)) {
- qWarning() << "Can not install a URL scheme handler overriding internal scheme: " << scheme;
+ qWarning("Cannot install a URL scheme handler overriding internal scheme: %s", scheme.constData());
return;
}
- if (m_urlSchemeHandlers.contains(scheme)) {
- qWarning() << "URL scheme handler already installed for the scheme: " << scheme;
+ if (d->browserContext()->customUrlSchemeHandlers().contains(scheme)) {
+ if (d->browserContext()->customUrlSchemeHandlers().value(scheme) != handler)
+ qWarning("URL scheme handler already installed for the scheme: %s", scheme.constData());
return;
}
- m_urlSchemeHandlers.insert(scheme, handler);
- browserContext()->customUrlSchemeHandlers().append(handler->d_func());
- browserContext()->updateCustomUrlSchemeHandlers();
+ d->browserContext()->addCustomUrlSchemeHandler(scheme, handler);
+ connect(handler, SIGNAL(destroyed(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
+}
+
+/*!
+ \since 5.6
+
+ Removes the custom URL scheme handler \a handler from the profile.
+
+ \sa removeUrlScheme()
+*/
+void QWebEngineProfile::removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
+{
+ Q_D(QWebEngineProfile);
+ Q_ASSERT(handler);
+ if (!d->browserContext()->removeCustomUrlSchemeHandler(handler))
+ return;
+ disconnect(handler, SIGNAL(destroyed(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
}
-void QWebEngineProfilePrivate::removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
+/*!
+ \since 5.6
+
+ Removes the custom URL scheme \a scheme from the profile.
+
+ \sa removeUrlSchemeHandler()
+*/
+void QWebEngineProfile::removeUrlScheme(const QByteArray &scheme)
{
- int count = m_urlSchemeHandlers.remove(handler->scheme());
- if (!count)
+ Q_D(QWebEngineProfile);
+ QWebEngineUrlSchemeHandler *handler = d->browserContext()->takeCustomUrlSchemeHandler(scheme);
+ if (!handler)
return;
- browserContext()->customUrlSchemeHandlers().removeOne(handler->d_func());
- browserContext()->updateCustomUrlSchemeHandlers();
+ disconnect(handler, SIGNAL(destroyed(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
+}
+
+/*!
+ \since 5.6
+
+ Removes all custom URL scheme handlers installed in the profile.
+*/
+void QWebEngineProfile::removeAllUrlSchemeHandlers()
+{
+ Q_D(QWebEngineProfile);
+ d->browserContext()->customUrlSchemeHandlers().clear();
+ d->browserContext()->updateCustomUrlSchemeHandlers();
}
-void QWebEngineProfilePrivate::clearUrlSchemeHandlers()
+void QWebEngineProfile::destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler *obj)
{
- m_urlSchemeHandlers.clear();
- browserContext()->customUrlSchemeHandlers().clear();
- browserContext()->updateCustomUrlSchemeHandlers();
+ removeUrlSchemeHandler(obj);
}
QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebengineprofile.h b/src/webenginewidgets/api/qwebengineprofile.h
index 4308fe75d..7e03c065c 100644
--- a/src/webenginewidgets/api/qwebengineprofile.h
+++ b/src/webenginewidgets/api/qwebengineprofile.h
@@ -37,22 +37,25 @@
#ifndef QWEBENGINEPROFILE_H
#define QWEBENGINEPROFILE_H
-#include "qtwebenginewidgetsglobal.h"
+#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h>
-#include <QObject>
-#include <QScopedPointer>
-#include <QString>
+#include <QtCore/qobject.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
class QObject;
class QUrl;
+class QWebEngineCookieStoreClient;
class QWebEngineDownloadItem;
class QWebEnginePage;
class QWebEnginePagePrivate;
class QWebEngineProfilePrivate;
class QWebEngineSettings;
class QWebEngineScriptCollection;
+class QWebEngineUrlRequestInterceptor;
+class QWebEngineUrlSchemeHandler;
class QWEBENGINEWIDGETS_EXPORT QWebEngineProfile : public QObject {
Q_OBJECT
@@ -87,12 +90,18 @@ public:
HttpCacheType httpCacheType() const;
void setHttpCacheType(QWebEngineProfile::HttpCacheType);
+ void setHttpAcceptLanguage(const QString &httpAcceptLanguage);
+ QString httpAcceptLanguage() const;
+
PersistentCookiesPolicy persistentCookiesPolicy() const;
void setPersistentCookiesPolicy(QWebEngineProfile::PersistentCookiesPolicy);
int httpCacheMaximumSize() const;
void setHttpCacheMaximumSize(int maxSize);
+ QWebEngineCookieStoreClient* cookieStoreClient();
+ void setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
+
void clearAllVisitedLinks();
void clearVisitedLinks(const QList<QUrl> &urls);
bool visitedLinksContainsUrl(const QUrl &url) const;
@@ -100,12 +109,22 @@ public:
QWebEngineSettings *settings() const;
QWebEngineScriptCollection *scripts() const;
+ const QWebEngineUrlSchemeHandler *urlSchemeHandler(const QByteArray &) const;
+ void installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *);
+ void removeUrlScheme(const QByteArray &scheme);
+ void removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *);
+ void removeAllUrlSchemeHandlers();
+
static QWebEngineProfile *defaultProfile();
Q_SIGNALS:
void downloadRequested(QWebEngineDownloadItem *download);
+private Q_SLOTS:
+ void destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler *obj);
+
private:
+ Q_DISABLE_COPY(QWebEngineProfile)
Q_DECLARE_PRIVATE(QWebEngineProfile)
QWebEngineProfile(QWebEngineProfilePrivate *, QObject *parent = 0);
diff --git a/src/webenginewidgets/api/qwebengineprofile_p.h b/src/webenginewidgets/api/qwebengineprofile_p.h
index ee3ea57d8..7dcc76598 100644
--- a/src/webenginewidgets/api/qwebengineprofile_p.h
+++ b/src/webenginewidgets/api/qwebengineprofile_p.h
@@ -50,7 +50,6 @@
#include "browser_context_adapter_client.h"
#include "qwebengineprofile.h"
-#include "qwebengineurlschemehandler_p.h"
#include "qwebenginescriptcollection.h"
#include <QMap>
#include <QPointer>
@@ -79,18 +78,12 @@ public:
void downloadRequested(DownloadItemInfo &info) Q_DECL_OVERRIDE;
void downloadUpdated(const DownloadItemInfo &info) Q_DECL_OVERRIDE;
- QWebEngineUrlSchemeHandler *urlSchemeHandler(const QByteArray &);
- void installUrlSchemeHandler(QWebEngineUrlSchemeHandler *);
- void removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *);
- void clearUrlSchemeHandlers();
-
private:
QWebEngineProfile *q_ptr;
QWebEngineSettings *m_settings;
QScopedPointer<QWebEngineScriptCollection> m_scriptCollection;
QExplicitlySharedDataPointer<QtWebEngineCore::BrowserContextAdapter> m_browserContextRef;
QMap<quint32, QPointer<QWebEngineDownloadItem> > m_ongoingDownloads;
- QMap<QByteArray, QPointer<QWebEngineUrlSchemeHandler> > m_urlSchemeHandlers;
};
QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebenginescript.cpp b/src/webenginewidgets/api/qwebenginescript.cpp
index e47766f4c..1bd56604d 100644
--- a/src/webenginewidgets/api/qwebenginescript.cpp
+++ b/src/webenginewidgets/api/qwebenginescript.cpp
@@ -47,24 +47,27 @@ using QtWebEngineCore::UserScript;
\since 5.5
\brief The QWebEngineScript class encapsulates a JavaScript program.
- QWebEngineScript allows the programmatic injection of so called "user scripts" in the
- javascript engine at different points, determined by injectionPoint(), during the loading of web contents.
- Scripts can be executed either in the main javascript world, along with the rest of the JavaScript coming
- from the web contents, or in their own isolated world. While the DOM of the page can be accessed from any world,
- JavaScript variables a function defined in one world are not accessible from a different one.
- ScriptWorldId provides some predefined ids for this purpose.
+ QWebEngineScript enables the programmatic injection of so called \e {user scripts} in the
+ JavaScript engine at different points, determined by injectionPoint(), during the loading of web
+ contents.
+
+ Scripts can be executed either in the main JavaScript \e world, along with the rest of the
+ JavaScript coming from the web contents, or in their own isolated world. While the DOM of the
+ page can be accessed from any world, JavaScript variables of a function defined in one world are
+ not accessible from a different one. ScriptWorldId provides some predefined IDs for this
+ purpose.
*/
/*!
\enum QWebEngineScript::InjectionPoint
- This enum describes the timing for when the script injection should happen.
+ This enum describes the timing of the script injection:
\value DocumentCreation The script will be executed as soon as the document is created. This is not suitable for
any DOM operation.
- \value DocumentReady The script will run as soon as the DOM is ready. This is equivalent to the DOMContentLoaded
- event firing in JavaScript.
+ \value DocumentReady The script will run as soon as the DOM is ready. This is equivalent to the
+ \c DOMContentLoaded event firing in JavaScript.
\value Deferred The script will run when the page load finishes, or 500ms after the document is ready, whichever
comes first.
@@ -72,20 +75,30 @@ using QtWebEngineCore::UserScript;
/*!
\enum QWebEngineScript::ScriptWorldId
- This enum provides pre defined world ids for isolating user scripts into different worlds.
+ This enum provides pre-defined world IDs for isolating user scripts into different worlds:
\value MainWorld The world used by the page's web contents. It can be useful in order to expose custom functionality
to web contents in certain scenarios.
\value ApplicationWorld The default isolated world used for application level functionality implemented in JavaScript.
\value UserWorld The first isolated world to be used by scripts set by users if the application is not making use
- of more worlds. As a rule of thumbs, if that functionality is exposed to the application users, each individual script
+ of more worlds. As a rule of thumb, if that functionality is exposed to the application users, each individual script
should probably get its own isolated world.
*/
/*!
- * \brief QWebEngineScript::QWebEngineScript
- *
+ \fn QWebEngineScript::operator!=(const QWebEngineScript &other) const
+
+ Returns \c true if the script is not equal to \a other, otherwise returns \c false.
+*/
+
+/*!
+ \fn QWebEngineScript::swap(QWebEngineScript &other)
+
+ Swaps the contents of the script with the contents of \a other.
+*/
+
+/*!
* Constructs a null script.
*/
@@ -93,34 +106,42 @@ QWebEngineScript::QWebEngineScript()
: d(new UserScript)
{
}
+
/*!
- * \brief QWebEngineScript::isNull
- * \return \c true is the script is null, \c false otherwise.
+ * Constructs a user script using the contents of \a other.
*/
-
QWebEngineScript::QWebEngineScript(const QWebEngineScript &other)
: d(other.d)
{
}
+/*!
+ Destroys a script.
+*/
QWebEngineScript::~QWebEngineScript()
{
}
+/*!
+ Assigns \a other to the script.
+*/
QWebEngineScript &QWebEngineScript::operator=(const QWebEngineScript &other)
{
d = other.d;
return *this;
}
+/*!
+ Returns \c true is the script is null; otherwise returns \c false.
+*/
bool QWebEngineScript::isNull() const
{
return d->isNull();
}
/*!
- * \brief QWebEngineScript::name
- * \return The name of the script. Can be useful to retrieve a given script from a QWebEngineScriptCollection.
+ * Returns the name of the script. Can be useful to retrieve a particular script from a
+ * QWebEngineScriptCollection.
*
* \sa QWebEngineScriptCollection::findScript(), QWebEngineScriptCollection::findScripts()
*/
@@ -131,9 +152,6 @@ QString QWebEngineScript::name() const
}
/*!
- * \brief QWebEngineScript::setName
- * \param scriptName
- *
* Sets the script name to \a scriptName.
*/
void QWebEngineScript::setName(const QString &scriptName)
@@ -144,8 +162,7 @@ void QWebEngineScript::setName(const QString &scriptName)
}
/*!
- * \brief QWebEngineScript::sourceCode
- * \return the source of the script.
+ Returns the source of the script.
*/
QString QWebEngineScript::sourceCode() const
{
@@ -153,8 +170,6 @@ QString QWebEngineScript::sourceCode() const
}
/*!
- * \brief QWebEngineScript::setSourceCode
- * \param scriptSource
* Sets the script source to \a scriptSource.
*/
void QWebEngineScript::setSourceCode(const QString &scriptSource)
@@ -169,8 +184,7 @@ ASSERT_ENUMS_MATCH(QWebEngineScript::DocumentReady, UserScript::DocumentLoadFini
ASSERT_ENUMS_MATCH(QWebEngineScript::DocumentCreation, UserScript::DocumentElementCreation)
/*!
- * \brief QWebEngineScript::injectionPoint
- * \return the point in the loading process at which the script will be executed.
+ * Returns the point in the loading process at which the script will be executed.
* The default value is QWebEngineScript::Deferred.
*
* \sa setInjectionPoint
@@ -180,9 +194,7 @@ QWebEngineScript::InjectionPoint QWebEngineScript::injectionPoint() const
return static_cast<QWebEngineScript::InjectionPoint>(d->injectionPoint());
}
/*!
- * \brief QWebEngineScript::setInjectionPoint
- * \param p
- * Sets the point at which to execute the script to be \p.
+ * Sets the point at which to execute the script to be \a p.
*
* \sa QWebEngineScript::InjectionPoint
*/
@@ -194,8 +206,7 @@ void QWebEngineScript::setInjectionPoint(QWebEngineScript::InjectionPoint p)
}
/*!
- * \brief QWebEngineScript::worldId
- * \return the world id defining which world the script is executed in.
+ Returns the world ID defining which world the script is executed in.
*/
quint32 QWebEngineScript::worldId() const
{
@@ -203,9 +214,7 @@ quint32 QWebEngineScript::worldId() const
}
/*!
- * \brief QWebEngineScript::setWorldId
- * \param id
- * Sets the world id of the isolated world to use when running this script.
+ Sets the world ID of the isolated world to \a id when running this script.
*/
void QWebEngineScript::setWorldId(quint32 id)
{
@@ -215,8 +224,8 @@ void QWebEngineScript::setWorldId(quint32 id)
}
/*!
- * \brief QWebEngineScript::runsOnSubFrames
- * \return \c true if the script is executed on every frame in the page, \c false if it is only ran for the main frame.
+ Returns \c true if the script is executed on every frame in the page, or \c false if it is only
+ ran for the main frame.
*/
bool QWebEngineScript::runsOnSubFrames() const
{
@@ -224,9 +233,7 @@ bool QWebEngineScript::runsOnSubFrames() const
}
/*!
- * \brief QWebEngineScript::setRunsOnSubFrames
- * \param on
- * Sets whether or not the script is executed on sub frames in addition to the main frame.
+ * Executes the script on sub frames in addition to the main frame if \a on returns \c true.
*/
void QWebEngineScript::setRunsOnSubFrames(bool on)
{
@@ -236,9 +243,7 @@ void QWebEngineScript::setRunsOnSubFrames(bool on)
}
/*!
- * \brief QWebEngineScript::operator ==
- * \param other
- * \return \c true if this QWebEngineScript is equal to \a other, otherwise returns \c false.
+ Returns \c true if the script is equal to \a other, otherwise returns \c false.
*/
bool QWebEngineScript::operator==(const QWebEngineScript &other) const
{
diff --git a/src/webenginewidgets/api/qwebenginescript.h b/src/webenginewidgets/api/qwebenginescript.h
index 2b03cd06f..4cff2631d 100644
--- a/src/webenginewidgets/api/qwebenginescript.h
+++ b/src/webenginewidgets/api/qwebenginescript.h
@@ -36,10 +36,11 @@
#ifndef QWEBENGINESCRIPT_H
#define QWEBENGINESCRIPT_H
-#include "qtwebenginewidgetsglobal.h"
-#include <QtCore/QSharedDataPointer>
-#include <QtCore/QString>
+#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h>
+
+#include <QtCore/qshareddata.h>
+#include <QtCore/qstring.h>
namespace QtWebEngineCore {
class UserScript;
diff --git a/src/webenginewidgets/api/qwebenginescriptcollection.cpp b/src/webenginewidgets/api/qwebenginescriptcollection.cpp
index 21cb0d05e..80a7f9b6e 100644
--- a/src/webenginewidgets/api/qwebenginescriptcollection.cpp
+++ b/src/webenginewidgets/api/qwebenginescriptcollection.cpp
@@ -49,18 +49,32 @@ using QtWebEngineCore::UserScript;
*/
+/*!
+ \fn QWebEngineScriptCollection::isEmpty() const
+
+ Returns \c true if the collection is empty; otherwise returns \c false.
+*/
+
+/*!
+ \fn QWebEngineScriptCollection::size() const
+
+ Returns the number of elements in the collection.
+*/
+
QWebEngineScriptCollection::QWebEngineScriptCollection(QWebEngineScriptCollectionPrivate *collectionPrivate)
:d(collectionPrivate)
{
}
+/*!
+ Destroys the collection.
+*/
QWebEngineScriptCollection::~QWebEngineScriptCollection()
{
}
/*!
- * \brief QWebEngineScriptCollection::count
- * \return the number of elements in the collection.
+ Returns the number of elements in the collection.
*/
int QWebEngineScriptCollection::count() const
@@ -69,9 +83,8 @@ int QWebEngineScriptCollection::count() const
}
/*!
- * \brief QWebEngineScriptCollection::contains
- * \param value
- * \return \c true if the collection contains an occurrence of \a value; otherwise returns false.
+ Returns \c true if the collection contains an occurrence of \a value; otherwise returns
+ \c false.
*/
bool QWebEngineScriptCollection::contains(const QWebEngineScript &value) const
@@ -80,11 +93,10 @@ bool QWebEngineScriptCollection::contains(const QWebEngineScript &value) const
}
/*!
- * \brief QWebEngineScriptCollection::findScript
- * \param name
- * \return the first script found in collection the name property of which is \a name, or a null QWebEngineScript if none was found.
- * \note the order in which the script collection is traversed is undefined, which means this should be used when the unicity is
- * guaranteed at the application level.
+ * Returns the first script found in the collection with the name \a name, or a null
+ * QWebEngineScript if none was found.
+ * \note The order in which the script collection is traversed is undefined, which means this should
+ * be used when the unicity is guaranteed at the application level.
* \sa findScripts()
*/
@@ -94,9 +106,8 @@ QWebEngineScript QWebEngineScriptCollection::findScript(const QString &name) con
}
/*!
- * \brief QWebEngineScriptCollection::findScripts
- * \param name
- * \return the list of scripts in the collection the name property of which is \a name, or an empty list if none was found.
+ Returns the list of scripts in the collection with the name \a name, or an empty list if none
+ was found.
*/
QList<QWebEngineScript> QWebEngineScriptCollection::findScripts(const QString &name) const
@@ -104,20 +115,14 @@ QList<QWebEngineScript> QWebEngineScriptCollection::findScripts(const QString &n
return d->toList(name);
}
/*!
- * \brief QWebEngineScriptCollection::insert
- * \param s
- *
- * Inserts script \c s into the collection.
+ Inserts the script \a s into the collection.
*/
void QWebEngineScriptCollection::insert(const QWebEngineScript &s)
{
d->insert(s);
}
/*!
- * \brief QWebEngineScriptCollection::insert
- * \param list
- *
- * Inserts scripts \c list into the collection.
+ Inserts scripts from the list \a list into the collection.
*/
void QWebEngineScriptCollection::insert(const QList<QWebEngineScript> &list)
{
@@ -127,10 +132,10 @@ void QWebEngineScriptCollection::insert(const QList<QWebEngineScript> &list)
}
/*!
- * \brief QWebEngineScriptCollection::remove
- * \param script
- * Removes \a script from the collection, if it is present.
- * \return \c true if the script was found and successfully removed from the collection, \c false otherwise.
+ Removes \a script from the collection.
+
+ Returns \c true if the script was found and successfully removed from the collection; otherwise
+ returns \c false.
*/
bool QWebEngineScriptCollection::remove(const QWebEngineScript &script)
{
@@ -138,7 +143,6 @@ bool QWebEngineScriptCollection::remove(const QWebEngineScript &script)
}
/*!
- * \brief QWebEngineScriptCollection::clear
* Removes all scripts from this collection.
*/
void QWebEngineScriptCollection::clear()
@@ -147,8 +151,7 @@ void QWebEngineScriptCollection::clear()
}
/*!
- * \brief QWebEngineScriptCollection::toList
- * \return a QList with the values of the scripts used in this collection.
+ Returns a list with the values of the scripts used in this collection.
*/
QList<QWebEngineScript> QWebEngineScriptCollection::toList() const
{
diff --git a/src/webenginewidgets/api/qwebenginescriptcollection.h b/src/webenginewidgets/api/qwebenginescriptcollection.h
index fe3ce2861..40196b478 100644
--- a/src/webenginewidgets/api/qwebenginescriptcollection.h
+++ b/src/webenginewidgets/api/qwebenginescriptcollection.h
@@ -37,12 +37,12 @@
#ifndef QWEBENGINESCRIPTCOLLECTION_H
#define QWEBENGINESCRIPTCOLLECTION_H
-#include "qtwebenginewidgetsglobal.h"
+#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h>
+#include <QtWebEngineWidgets/qwebenginescript.h>
-#include "qwebenginescript.h"
-#include <QtCore/QScopedPointer>
-#include <QtCore/QList>
-#include <QtCore/QSet>
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qset.h>
QT_BEGIN_NAMESPACE
class QWebEngineScriptCollectionPrivate;
diff --git a/src/webenginewidgets/api/qwebenginesettings.cpp b/src/webenginewidgets/api/qwebenginesettings.cpp
index 164bf8db6..430d64185 100644
--- a/src/webenginewidgets/api/qwebenginesettings.cpp
+++ b/src/webenginewidgets/api/qwebenginesettings.cpp
@@ -72,6 +72,10 @@ static WebEngineSettings::Attribute toWebEngineAttribute(QWebEngineSettings::Web
return WebEngineSettings::ScrollAnimatorEnabled;
case QWebEngineSettings::ErrorPageEnabled:
return WebEngineSettings::ErrorPageEnabled;
+ case QWebEngineSettings::PluginsEnabled:
+ return WebEngineSettings::PluginsEnabled;
+ case QWebEngineSettings::FullScreenSupportEnabled:
+ return WebEngineSettings::FullScreenSupportEnabled;
default:
return WebEngineSettings::UnsupportedInCoreSettings;
}
diff --git a/src/webenginewidgets/api/qwebenginesettings.h b/src/webenginewidgets/api/qwebenginesettings.h
index 44339a2f6..327fd447b 100644
--- a/src/webenginewidgets/api/qwebenginesettings.h
+++ b/src/webenginewidgets/api/qwebenginesettings.h
@@ -58,7 +58,9 @@ public:
LocalContentCanAccessFileUrls,
HyperlinkAuditingEnabled,
ScrollAnimatorEnabled,
- ErrorPageEnabled
+ ErrorPageEnabled,
+ PluginsEnabled,
+ FullScreenSupportEnabled
};
enum FontSize {
diff --git a/src/webenginewidgets/api/qwebengineurlschemehandler.cpp b/src/webenginewidgets/api/qwebengineurlschemehandler.cpp
deleted file mode 100644
index a0e751c24..000000000
--- a/src/webenginewidgets/api/qwebengineurlschemehandler.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwebengineurlschemehandler_p.h"
-#include "qwebengineurlschemehandler_p_p.h"
-
-#include "qwebengineprofile.h"
-#include "qwebengineprofile_p.h"
-#include "qwebengineurlrequestjob_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QWebEngineUrlSchemeHandler
- \brief The QWebEngineUrlSchemeHandler Base class for handling custom URL schemes.
- \since 5.5
- \internal
-
- To implement a custom URL scheme for QtWebEngine you must write a class derived from this class,
- and reimplement requestStarted().
-
- To install a custom URL scheme handler into a QtWebProfile, you only need to call the constructor
- with the correct profile. Each instance of a QWebEngineUrlSchemeHandler can only handle requests
- from a single profile.
-
- \inmodule QtWebEngineWidgets
-
-*/
-
-QWebEngineUrlSchemeHandlerPrivate::QWebEngineUrlSchemeHandlerPrivate(const QByteArray &scheme, QWebEngineUrlSchemeHandler *q, QWebEngineProfile *profile)
- : CustomUrlSchemeHandler(scheme)
- , q_ptr(q)
- , m_profile(profile)
-{
-}
-
-QWebEngineUrlSchemeHandlerPrivate::~QWebEngineUrlSchemeHandlerPrivate()
-{
-}
-
-bool QWebEngineUrlSchemeHandlerPrivate::handleJob(QtWebEngineCore::URLRequestCustomJobDelegate *job)
-{
- QWebEngineUrlRequestJob *requestJob = new QWebEngineUrlRequestJob(job);
- q_ptr->requestStarted(requestJob);
- return true;
-}
-
-/*!
- Constructs a new URL scheme handler.
-
- The handler is created for \a scheme and for the \a profile.
-
- */
-QWebEngineUrlSchemeHandler::QWebEngineUrlSchemeHandler(const QByteArray &scheme, QWebEngineProfile *profile, QObject *parent)
- : QObject(parent)
- , d_ptr(new QWebEngineUrlSchemeHandlerPrivate(scheme, this, profile))
-{
- profile->d_func()->installUrlSchemeHandler(this);
-}
-
-QWebEngineUrlSchemeHandler::~QWebEngineUrlSchemeHandler()
-{
- if (d_ptr->m_profile)
- d_ptr->m_profile->d_func()->removeUrlSchemeHandler(this);
-}
-
-/*!
- Returns the custom URL scheme handled.
-*/
-QByteArray QWebEngineUrlSchemeHandler::scheme() const
-{
- return d_ptr->scheme();
-}
-
-/*!
- \fn void QWebEngineUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *request)
-
- This method is called whenever a request for the registered scheme is started.
-
- This method must be reimplemented by all custom URL scheme handlers.
- The request is asynchronous and does not need to be handled right away.
-
- \sa QWebEngineUrlRequestJob
-*/
-
-QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index a4a8dd760..9baa8e34a 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -86,6 +86,7 @@ void QWebEngineViewPrivate::bind(QWebEngineView *view, QWebEnginePage *page)
QObject::connect(page, &QWebEnginePage::loadProgress, view, &QWebEngineView::loadProgress);
QObject::connect(page, &QWebEnginePage::loadFinished, view, &QWebEngineView::loadFinished);
QObject::connect(page, &QWebEnginePage::selectionChanged, view, &QWebEngineView::selectionChanged);
+ QObject::connect(page, &QWebEnginePage::renderProcessTerminated, view, &QWebEngineView::renderProcessTerminated);
}
}
@@ -107,6 +108,14 @@ QWebEngineViewPrivate::QWebEngineViewPrivate()
#endif // QT_NO_ACCESSIBILITY
}
+/*!
+ \fn QWebEngineView::renderProcessTerminated(QWebEnginePage::RenderProcessTerminationStatus terminationStatus, int exitCode)
+
+ This signal is emitted when the render process is terminated with a non-zero exit status.
+ \a terminationStatus is the termination status of the process and \a exitCode is the status code
+ with which the process terminated.
+*/
+
QWebEngineView::QWebEngineView(QWidget *parent)
: QWidget(parent)
, d_ptr(new QWebEngineViewPrivate)
diff --git a/src/webenginewidgets/api/qwebengineview.h b/src/webenginewidgets/api/qwebengineview.h
index 6b37dbf39..ae38e6c5c 100644
--- a/src/webenginewidgets/api/qwebengineview.h
+++ b/src/webenginewidgets/api/qwebengineview.h
@@ -113,6 +113,8 @@ Q_SIGNALS:
void selectionChanged();
void urlChanged(const QUrl&);
void iconUrlChanged(const QUrl&);
+ void renderProcessTerminated(QWebEnginePage::RenderProcessTerminationStatus terminationStatus,
+ int exitCode);
protected:
virtual QWebEngineView *createWindow(QWebEnginePage::WebWindowType type);
@@ -120,6 +122,7 @@ protected:
virtual bool event(QEvent*) Q_DECL_OVERRIDE;
private:
+ Q_DISABLE_COPY(QWebEngineView)
Q_DECLARE_PRIVATE(QWebEngineView)
QScopedPointer<QWebEngineViewPrivate> d_ptr;
diff --git a/src/webenginewidgets/doc/qtwebenginewidgets.qdocconf b/src/webenginewidgets/doc/qtwebenginewidgets.qdocconf
deleted file mode 100644
index ad1e46f1c..000000000
--- a/src/webenginewidgets/doc/qtwebenginewidgets.qdocconf
+++ /dev/null
@@ -1,39 +0,0 @@
-include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
-
-project = QtWebEngineWidgets
-description = Qt WebEngineWidgets Reference Documentation
-version = $QT_VERSION
-
-examplesinstallpath = webenginewidgets
-
-qhp.projects = QtWebEngineWidgets
-
-qhp.QtWebEngineWidgets.file = qtwebenginewidgets.qhp
-qhp.QtWebEngineWidgets.namespace = org.qt-project.qtwebenginewidgets.$QT_VERSION_TAG
-qhp.QtWebEngineWidgets.virtualFolder = qtwebenginewidgets
-qhp.QtWebEngineWidgets.indexTitle = Qt WebEngine Widgets
-qhp.QtWebEngineWidgets.indexRoot =
-
-qhp.QtWebEngineWidgets.filterAttributes = qtwebenginewidgets $QT_VERSION qtrefdoc
-qhp.QtWebEngineWidgets.customFilters.Qt.name = QtWebEngineWidgets $QT_VERSION
-qhp.QtWebEngineWidgets.customFilters.Qt.filterAttributes = qtwebenginewidgets $QT_VERSION
-qhp.QtWebEngineWidgets.subprojects = classes examples
-qhp.QtWebEngineWidgets.subprojects.classes.title = C++ Classes
-qhp.QtWebEngineWidgets.subprojects.classes.indexTitle = Qt WebEngine Widgets C++ Classes
-qhp.QtWebEngineWidgets.subprojects.classes.selectors = class fake:headerfile
-qhp.QtWebEngineWidgets.subprojects.classes.sortPages = true
-qhp.QtWebEngineWidgets.subprojects.examples.title = Examples
-qhp.QtWebEngineWidgets.subprojects.examples.indexTitle = Qt WebEngine Widgets Examples
-qhp.QtWebEngineWidgets.subprojects.examples.selectors = fake:example
-qhp.QtWebEngineWidgets.subprojects.examples.sortPages = true
-
-tagfile = ../../../doc/qtwebenginewidgets/qtwebenginewidgets.tags
-
-depends += qtwebengine qtcore qtnetwork qtgui qtwidgets qtwebkit qtdoc
-
-headerdirs += ../api
-sourcedirs += ../api
-exampledirs += ../../../examples/webenginewidgets .
-
-navigation.landingpage = "Qt WebEngine Widgets"
-navigation.cppclassespage = "Qt WebEngine Widgets C++ Classes"
diff --git a/src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc b/src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc
new file mode 100644
index 000000000..eff22be26
--- /dev/null
+++ b/src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc
@@ -0,0 +1,38 @@
+/*
+ Copyright (C) 2015 The Qt Company Ltd.
+ Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*!
+ \group webengine-widgetexamples
+ \title Qt WebEngine Widgets Examples
+ \brief Examples demonstrating the Qt WebEngine Widgets usage
+ \ingroup all-examples
+
+ Qt provides an integrated Web browser component based on Chromium, the popular
+ open source browser engine.
+
+ These examples and demonstrations show a range of different uses for Qt WebEngine,
+ from displaying Web pages within a Qt user interface to an implementation of
+ a basic function Web browser.
+*/
diff --git a/src/webenginewidgets/doc/src/qtwebenginewidgets.qdoc b/src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc
index 1e8cda065..77596a370 100644
--- a/src/webenginewidgets/doc/src/qtwebenginewidgets.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc
@@ -26,74 +26,29 @@
****************************************************************************/
/*!
- \module QtWebEngineWidgets
- \title Qt WebEngine Widgets C++ Classes
- \qtvariable webenginewidgets
- \brief Provides a web browser engine as well as C++ classes to render and
- interact with web content
-
- To include the definitions of the module's classes, use the
- following directive:
-
- \snippet snippets/qtwebengine_build_snippet.qdoc 1
-
- To link against the module, add this line to your \l qmake \c
- .pro file:
-
- \snippet snippets/qtwebengine_build_snippet.qdoc 0
-*/
-
-/*!
\page qtwebenginewidgets-index.html
\title Qt WebEngine Widgets
\ingroup modules
- \brief The Qt WebEngine Widgets module provides a web browser engine as
- well as C++ classes to display and interact with web content.
-
- Qt WebEngine Widgets gives you a Web browser engine that you can use to
- embed content easily from the World Wide Web into your Qt application.
-
- Qt WebEngine Widgets lets you display HyperText Markup Language version 5
- (HTML5), Extensible HyperText Markup Language (XHTML) and Scalable Vector
- Graphics (SVG) documents, styled using Cascading Style Sheets (CSS) and
- scripted with JavaScript.
-
- HTML and XHTML documents can also be made fully editable to the user by
- using the \c{contenteditable} attribute on HTML elements.
+ \brief Provides a web browser engine as well as C++ classes to render web content and interact
+ with it.
- Qt WebEngine is based on the Chromium project. See the
- \l{http://www.chromium.org}{Chromium Project} Web site for more information.
-
- \section1 Including In Your Project
+ \section1 Getting Started
To include the definitions of the module's classes, use the
following directive:
- \snippet snippets/qtwebengine_build_snippet.qdoc 1
-
- To link against the module, add this line to your \l qmake \c
- .pro file:
-
- \snippet snippets/qtwebengine_build_snippet.qdoc 0
+ \snippet qtwebengine_build_snippet.qdoc 1
- \section1 Architecture
+ To link against the module, add this line to your qmake project file:
- Use the QWebEngineView class to display web pages in the simplest way.
- Because it's a widget, you can embed QWebEngineView into your forms and use
- its convenience functions to download and display web sites.
+ \snippet qtwebengine_build_snippet.qdoc 0
- \snippet snippets/simple/main.cpp Using QWebEngineView
-
- An instance of QWebEngineView has one QWebEnginePage. QWebEnginePage
- provides access to the page's navigation history, ability to run JavaScript
- code in the context of the page's main frame, and enables customization of
- handlers for specific events like showing custom authentication dialogs.
-
- \section1 Reference Documentation
+ \section1 Articles and Guides
\list
- \li \l {Qt WebEngine Widgets C++ Classes}
+ \li \l{Qt WebEngine Overview}
+ \li \l{Porting from Qt WebKit to Qt WebEngine}
\endlist
\section1 Examples
@@ -102,7 +57,14 @@
\li \l {Qt WebEngine Widgets Examples}
\endlist
+ \section1 API Reference
+
+ \list
+ \li \l {Qt WebEngine Widgets C++ Classes}
+ \endlist
+
\section1 License Information
+
This is a snapshot of the integration of Chromium into Qt.
Qt Commercial Edition licensees that wish to distribute applications that
@@ -146,17 +108,3 @@
\endlegalese
*/
-
-/*!
- \group webengine-widgetexamples
- \title Qt WebEngine Widgets Examples
- \brief Examples demonstrating the Qt WebEngine Widgets usage
- \ingroup all-examples
-
- Qt provides an integrated Web browser component based on Chromium, the popular
- open source browser engine.
-
- These examples and demonstrations show a range of different uses for Qt WebEngine,
- from displaying Web pages within a Qt user interface to an implementation of
- a basic function Web browser.
-*/
diff --git a/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc b/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
new file mode 100644
index 000000000..a9ef6ad8c
--- /dev/null
+++ b/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \module QtWebEngineWidgets
+ \title Qt WebEngine Widgets C++ Classes
+ \brief Provides a web browser engine as well as C++ classes to render and
+ interact with web content
+ \ingroup modules
+ \ingroup qtwebengine-modules
+ \qtvariable webenginewidgets
+
+ The Qt WebEngineWidgets module provides a web browser engine as well as C++ classes to render
+ and interact with web content.
+
+ To include the definitions of the module's classes, use the
+ following directive:
+
+ \snippet qtwebengine_build_snippet.qdoc 1
+
+ To link against the module, add the following to your qmake project file:
+
+ \snippet qtwebengine_build_snippet.qdoc 0
+*/
diff --git a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
index 174f59d83..927b08cb5 100644
--- a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
@@ -31,8 +31,10 @@
\brief This guide gives an overview of the differences between the Qt WebKit
and Qt WebEngine APIs in applications.
- This provides rough steps to follow when porting an application using
- Qt WebKit's QWebView API to use Qt WebEngine's QWebEngineView.
+ This guide provides rough steps to follow when porting an application that uses the
+ \l{http://doc.qt.io/archives/qt-5.3/qtwebkit-index.html}{Qt WebKit}
+ \l{http://doc.qt.io/archives/qt-5.3/qml-qtwebkit-webview.html}{QWebView API} to use the
+ \l{Qt WebEngine} QWebEngineView.
\section1 Class Names
diff --git a/src/webenginewidgets/doc/src/qwebenginehistory_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginehistory_lgpl.qdoc
index 2674890de..5e3ebecb1 100644
--- a/src/webenginewidgets/doc/src/qwebenginehistory_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginehistory_lgpl.qdoc
@@ -24,23 +24,12 @@
/*!
\class QWebEngineHistoryItem
- \brief The QWebEngineHistoryItem class represents one item in the history of a QWebEnginePage
+ \brief The QWebEngineHistoryItem class represents one item in the history of a web engine page.
\since 5.4
\inmodule QtWebEngineWidgets
- Each QWebEngineHistoryItem instance represents an entry in the history stack of a Web page,
- containing information about the page, its location, and when it was last visited.
-
- The following table shows the properties of the page held by the history item, and
- the functions used to access them.
-
- \table
- \header \li Function \li Description
- \row \li title() \li The page title.
- \row \li url() \li The location of the page.
- \row \li originalUrl() \li The URL used to access the page.
- \row \li lastVisited() \li The date and time of the user's last visit to the page.
- \endtable
+ Each web engine history item represents an entry in the history stack of a web page,
+ containing information about the page, its location, and the time when it was last visited.
\sa QWebEngineHistory, QWebEnginePage::history()
*/
@@ -87,7 +76,7 @@
/*!
\fn QDateTime QWebEngineHistoryItem::lastVisited() const
- Returns the date and time that the page associated with the item was last visited.
+ Returns the date and time when the page associated with the item was last visited.
\sa title(), url()
*/
@@ -99,13 +88,12 @@
/*!
\class QWebEngineHistory
- \brief The QWebEngineHistory class represents the history of a QWebEnginePage
+ \brief The QWebEngineHistory class represents the history of a web engine page.
\since 5.4
\inmodule QtWebEngineWidgets
- Each QWebEnginePage instance contains a history of visited pages that can be accessed
- by QWebEnginePage::history(). QWebEngineHistory represents this history and makes it possible
- to navigate it.
+ Each web engine page contains a history of visited pages that can be accessed
+ by QWebEnginePage::history().
The history uses the concept of a \e{current item}, dividing the pages visited
into those that can be visited by navigating \e back and \e forward using the
@@ -161,23 +149,23 @@
/*!
\fn bool QWebEngineHistory::canGoBack() const
- Returns true if there is an item preceding the current item in the history;
- otherwise returns false.
+ Returns \c true if there is an item preceding the current item in the history;
+ otherwise returns \c false.
\sa canGoForward()
*/
/*!
\fn bool QWebEngineHistory::canGoForward() const
- Returns true if we have an item to go forward to; otherwise returns false.
+ Returns \c true if we have an item to go forward to; otherwise returns \c false.
\sa canGoBack()
*/
/*!
\fn void QWebEngineHistory::back()
- Set the current item to be the previous item in the history and goes to the
- corresponding page; i.e., goes back one history item.
+ Sets the current item to be the previous item in the history and goes to the
+ corresponding page; that is, goes back one history item.
\sa forward(), goToItem()
*/
@@ -185,7 +173,7 @@
/*!
\fn void QWebEngineHistory::forward()
Sets the current item to be the next item in the history and goes to the
- corresponding page; i.e., goes forward one history item.
+ corresponding page; that is, goes forward one history item.
\sa back(), goToItem()
*/
@@ -231,9 +219,7 @@
\fn QDataStream& operator<<(QDataStream& stream, const QWebEngineHistory& history)
\relates QWebEngineHistory
- \brief The operator<< function streams a history into a data stream.
-
- It saves the \a history into the specified \a stream.
+ Saves the web engine history \a history into \a stream.
*/
@@ -241,7 +227,5 @@
\fn QDataStream& operator>>(QDataStream& stream, QWebEngineHistory& history)
\relates QWebEngineHistory
- \brief The operator>> function loads a history from a data stream.
-
- Loads a QWebEngineHistory from the specified \a stream into the given \a history.
+ Loads the web engine history from \a stream into \a history.
*/
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index 40c5c8d04..b7b3bf022 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -30,8 +30,8 @@
\since 5.4
\inmodule QtWebEngineWidgets
- QWebEnginePage holds a main frame responsible for web content, the history
- of navigated links and actions.
+ A web engine page holds a main frame responsible for web content, the history
+ of navigated links, and actions.
QWebEnginePage's API is very similar to QWebEngineView, as you are still provided with
common functions like action() (known as
@@ -39,7 +39,7 @@
and findText().
A page can be loaded using load() or setUrl(). Alternatively, if you have
- the HTML content readily available, you can use setHtml() instead.
+ the HTML content readily available, you can use setHtml().
The QWebEnginePage class also offers methods to retrieve both the URL currently
loaded by its main frame (see url()) as well as the URL originally requested
@@ -55,12 +55,11 @@
The zoomFactor() property can be used to change the overall size
of the content displayed in the page.
- The loadStarted() signal is emitted when the page begins to load.The
- loadProgress() signal, on the other hand, is emitted whenever an element
- of the web page completes loading, such as an embedded image, a script,
- etc. Finally, the loadFinished() signal is emitted when the page contents
- are loaded completely, independent of script execution or page rendering.
- Its argument, either true or false, indicates whether or not the load
+ The loadStarted() signal is emitted when the page begins to load, whereas the loadProgress()
+ signal is emitted whenever an element of the web page completes loading, such as an embedded
+ image or a script. The loadFinished() signal is emitted when the page contents
+ have been loaded completely, independent of script execution or page rendering.
+ Its argument, either \c true or \c false, indicates whether or not the load
operation succeeded.
*/
@@ -95,9 +94,35 @@
\value Paste Paste content from the clipboard.
\value Undo Undo the last editing action.
\value Redo Redo the last editing action.
- \value SelectAll Selects all content.
+ \value SelectAll Select all content.
\value PasteAndMatchStyle Paste content from the clipboard with current style.
+ \value OpenLinkInThisWindow Open the current link in the current window. (Added in Qt 5.6)
+ \value OpenLinkInNewWindow Open the current link in a new window. (Added in Qt 5.6)
+ \value OpenLinkInNewTab Open the current link in a new tab. (Added in Qt 5.6)
+ \value CopyLinkToClipboard Copy the current link to the clipboard. (Added in Qt 5.6)
+
+ \value CopyImageToClipboard Copy the clicked image to the clipboard. (Added in Qt 5.6)
+ \value CopyImageUrlToClipboard Copy the clicked image's URL to the clipboard. (Added in Qt 5.6)
+ \value CopyMediaUrlToClipboard Copy the hovered audio or video's URL to the clipboard. (Added in Qt 5.6)
+ \value ToggleMediaControls Toggle between showing and hiding the controls for the hovered audio
+ or video element. (Added in Qt 5.6)
+ \value ToggleMediaLoop Toggle whether the hovered audio or video should loop on completetion or
+ not. (Added in Qt 5.6)
+ \value ToggleMediaPlayPause Toggle the play/pause state of the hovered audio or video element.
+ (Added in Qt 5.6)
+ \value ToggleMediaMute Mute or unmute the hovered audio or video element. (Added in Qt 5.6)
+ \value DownloadLinkToDisk Download the current link to the disk. (Added in Qt 5.6)
+ \value DownloadImageToDisk Download the highlighted image to the disk. (Added in Qt 5.6)
+ \value DownloadMediaToDisk Download the hovered audio or video to the disk. (Added in Qt 5.6)
+
+ \value InspectElement Trigger any attached Web Inspector to inspect the highlighed element.
+ (Added in Qt 5.6)
+ \value ExitFullScreen Exit the fullscreen mode. (Added in Qt 5.6)
+ \value RequestClose Request to close the web page. If defined, the \c{window.onbeforeunload}
+ handler is run, and the user can confirm or reject to close the page. If the close
+ request is confirmed, \c windowCloseRequested is emitted. (Added in Qt 5.6)
+
\omitvalue WebActionCount
*/
@@ -105,31 +130,37 @@
/*!
\enum QWebEnginePage::WebWindowType
- This enum describes the types of window that can be created by the createWindow() function.
+ This enum describes the types of window that can be created by the createWindow() function:
- \value WebBrowserWindow The page should be opened in a complete web browser window.
- \value WebBrowserTab The page should be opened as a web browser tab.
- \value WebDialog The page should be opened in a window without decoration.
+ \value WebBrowserWindow
+ A complete web browser window.
+ \value WebBrowserTab
+ A web browser tab.
+ \value WebDialog
+ A window without decoration.
*/
/*!
\enum QWebEnginePage::JavaScriptConsoleMessageLevel
- This enum describes the different severity levels a JavaScript console message can have.
+ This enum describes the different severity levels a JavaScript console message can have:
\value InfoMessageLevel The message is purely informative and can safely be ignored.
- \value WarningMessageLevel The message informs about unexpected behaviors or errors that may need attention.
+ \value WarningMessageLevel The message informs about unexpected behavior or errors that may
+ need attention.
\value ErrorMessageLevel The message indicates there has been an error.
*/
/*!
\enum QWebEnginePage::FileSelectionMode
- This enum indicates whether the implementation of the chooseFiles function should
- return only one file or may return multiple files.
+ This enum indicates whether the implementation of the chooseFiles() function should
+ return only one file or may return multiple files:
- \value FileSelectOpen The implementation should return only one file name.
- \value FileSelectOpenMultiple The implementation may return multiple file names.
+ \value FileSelectOpen
+ Return only one file name.
+ \value FileSelectOpenMultiple
+ Return multiple file names.
\sa chooseFiles()
*/
@@ -137,7 +168,7 @@
/*!
\enum QWebEnginePage::PermissionPolicy
- This enum describes the permission policies that the user may set for data or device access.
+ This enum describes the permission policies that the user may set for data or device access:
\value PermissionUnknown It is unknown whether the user grants or denies permission.
\value PermissionGrantedByUser The user has granted permission.
@@ -149,12 +180,12 @@
/*!
\enum QWebEnginePage::NavigationType
- This enum describes the type of a navigation request.
+ This enum describes the type of a navigation request:
\value NavigationTypeLinkClicked The navigation request resulted from a clicked link.
- \value NavigationTypeTyped The navigation request resulted from an explicitly loaded url.
+ \value NavigationTypeTyped The navigation request resulted from an explicitly loaded URL.
\value NavigationTypeFormSubmitted The navigation request resulted from a form submission.
- \value NavigationTypeBackForward The navigation request resulted from a back/forward action.
+ \value NavigationTypeBackForward The navigation request resulted from a back or forward action.
\value NavigationTypeReload The navigation request resulted from a reload action.
\value NavigationTypeOther The navigation request was triggered by other means not covered by the above.
@@ -164,12 +195,20 @@
/*!
\enum QWebEnginePage::Feature
- This enum describes the platform feature access categories that the user may be asked to grant or deny access to.
-
- \value Geolocation Access to location hardware or service
- \value MediaAudioCapture Audio capture devices such a microphones
- \value MediaVideoCapture Video devices, e.g. cameras
- \value MediaAudioVideoCapture Both Audio and Video capture devices.
+ This enum describes the platform feature access categories that the user may be asked to grant
+ or deny access to:
+
+ \value Geolocation
+ Location hardware or service.
+ \value MediaAudioCapture
+ Audio capture devices, such as microphones.
+ \value MediaVideoCapture
+ Video devices, such as cameras.
+ \value MediaAudioVideoCapture
+ Both audio and video capture devices.
+ \value MouseLock
+ Mouse locking, which locks the mouse pointer to the web view and is typically used in
+ games.
\sa featurePermissionRequested(), featurePermissionRequestCanceled(), setFeaturePermission(), PermissionPolicy
@@ -177,7 +216,7 @@
/*!
\fn QWebEnginePage::QWebEnginePage(QObject *parent)
- Constructs an empty QWebEnginePage with parent \a parent.
+ Constructs an empty QWebEnginePage with the parent \a parent.
*/
/*!
@@ -206,19 +245,21 @@
/*!
\fn QMenu *QWebEnginePage::createStandardContextMenu()
- This function creates the standard context menu which is shown when
+ Creates the standard context menu which is shown when
the user clicks on the web page with the right mouse button. It is
- called from the default contextMenuEvent() handler. The popup menu's
+ called from the default \l{QWidget::}{contextMenuEvent()} handler. The popup menu's
ownership is transferred to the caller.
*/
/*!
\fn void QWebEnginePage::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID)
- This function is called whenever a JavaScript program tries to print a \a message to the web browser's console.
+ This function is called when a JavaScript program tries to print the \a message to the web
+ browser's console.
- For example in case of evaluation errors the source URL may be provided in \a sourceID as well as the \a lineNumber.
+ For example, in case of evaluation errors the source URL may be provided in \a sourceID as well
+ as the \a lineNumber.
- \a level indicates the severity of the event that triggered the message, i.e. if it
+ \a level indicates the severity of the event that triggered the message. That is, whether it
was triggered by an error or a less severe event.
The default implementation prints nothing.
@@ -226,25 +267,27 @@
/*!
\fn bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
- This function is called whenever there is a request to navigate to a specified \a url by means of the specified navigation type \atype.
- The \a isMainFrame argument marks if the request corresponds to the main frame, or a sub frame.
- If the request is accepted Chromium will continue to load the page, else the request will be ignored.
- The default implementation accepts the navigation request.
+ \since 5.5
+ This function is called upon receiving a request to navigate to the specified \a url by means of
+ the specified navigation type \a type. \a isMainFrame indicates whether the request corresponds
+ to the main frame or a sub frame. If the function returns \c true, the navigation request is
+ accepted and \c url is loaded. The default implementation accepts all navigation requests.
*/
/*!
\fn void QWebEnginePage::javaScriptAlert(const QUrl &securityOrigin, const QString& msg)
- This function is called whenever a JavaScript program running in a frame affiliated with \a securityOrigin calls the alert() function with
- the message \a msg.
+ This function is called whenever a JavaScript program running in a frame affiliated with
+ \a securityOrigin calls the \c alert() function with the message \a msg.
The default implementation shows the message, \a msg, with QMessageBox::information.
*/
/*!
\fn bool QWebEnginePage::javaScriptConfirm(const QUrl &securityOrigin, const QString& msg)
- This function is called whenever a JavaScript program running in a frame affiliated with \a securityOrigin calls the confirm() function
- with the message, \a msg. Returns true if the user confirms the message; otherwise returns false.
+ This function is called whenever a JavaScript program running in a frame affiliated with
+ \a securityOrigin calls the \c confirm() function with the message \a msg. Returns \c true
+ if the user confirms the message; otherwise returns \c false.
The default implementation executes the query using QMessageBox::information with QMessageBox::Ok and QMessageBox::Cancel buttons.
*/
@@ -254,36 +297,38 @@
This function is called whenever a JavaScript program running in a frame affiliated with \a securityOrigin tries to prompt the user for input.
The program may provide an optional message, \a msg, as well as a default value for the input in \a defaultValue.
- If the prompt was cancelled by the user the implementation should return false; otherwise the
- result should be written to \a result and true should be returned. If the prompt was not cancelled by the
- user, the implementation should return true and the result string must not be null.
+ If the prompt was cancelled by the user, the implementation should return \c false; otherwise the
+ result should be written to \a result and \c true should be returned. If the prompt was not
+ cancelled by the user, the implementation should return \c true and the result string must not
+ be null.
The default implementation uses QInputDialog::getText().
*/
/*!
\fn QWebEnginePage *QWebEnginePage::createWindow(WebWindowType type)
- This function is called whenever the WebEngine wants to create a new window of the given \a type, for example when a JavaScript program requests to open a document in a new window.
+ This function is called to create a new window of the specified \a type. For example, when a
+ JavaScript program requests to open a document in a new window.
If the new window can be created, the new window's QWebEnginePage is returned; otherwise a null pointer is returned.
If the view associated with the web page is a QWebEngineView object, then the default implementation forwards
- the request to QWebEngineView's createWindow() function; otherwise it returns a null pointer.
+ the request to QWebEngineView::createWindow(); otherwise it returns a null pointer.
\note In the cases when the window creation is being triggered by JavaScript, apart from
- reimplementing this method application must also set the JavaScriptCanOpenWindows attribute
- of QWebEngineSettings to true in order for it to get called.
+ reimplementing this method the application must also set
+ QWebEngineSettings::JavascriptCanOpenWindows to \c true in order for the method to get called.
\sa QWebEngineView::createWindow()
*/
/*!
- \fn void QWebEnginePage::triggerAction(WebAction action, bool)
+ \fn void QWebEnginePage::triggerAction(WebAction action, bool checked = false)
This function can be called to trigger the specified \a action.
It is also called by Qt WebEngine if the user triggers the action, for example
through a context menu item.
- If \a action is a checkable action then \a checked specified whether the action
+ If \a action is a checkable action, then \a checked specifies whether the action
is toggled or not.
\sa action()
@@ -331,11 +376,11 @@
To clear the selection, just pass an empty string.
- The \a resultCallback must take a boolean parameter. It will be called with a value of true if the \a subString
- was found; otherwise the callback value will be false.
+ The \a resultCallback must take a boolean parameter. It will be called with a value of \c true
+ if the \a subString was found; otherwise the callback value will be \c false.
For example:
- \snippet snippets/qtwebengine_qwebenginepage_snippet.cpp 0
+ \snippet qtwebengine_qwebenginepage_snippet.cpp 0
*/
/*!
@@ -351,7 +396,8 @@
The \a certificateError parameter contains information about the certificate and details of the error.
- Return true to ignore the error and complete the request, otherwise return false to stop loading the request.
+ Return \c true to ignore the error and complete the request. Return \c false to stop loading
+ the request.
\sa QWebEngineCertificateError
*/
@@ -359,9 +405,9 @@
/*!
\fn QString QWebEnginePage::chooseFiles(FileSelectionMode mode, const QStringList& oldFiles, const QStringList& acceptedMimeTypes)
This function is called when the web content requests a file name, for example
- as a result of the user clicking on a "file upload" button in a HTML form.
+ as a result of the user clicking on a file upload button in an HTML form.
- \a mode indicates whether only one file or multiples files are expected to be returned.
+ \a mode indicates whether only one file or multiple files are expected to be returned.
A suggested filename may be provided as the first entry of \a oldFiles. \a acceptedMimeTypes is ignored by the default implementation,
but might be used by overrides.
@@ -399,7 +445,7 @@
\fn void QWebEnginePage::selectionChanged()
This signal is emitted whenever the selection changes, either interactively
- or programmatically (e.g. by calling triggerAction() with a selection action).
+ or programmatically. For example, by calling triggerAction() with a selection action.
\sa selectedText()
*/
@@ -439,6 +485,8 @@
This signal is emitted whenever the page requests the web browser window to be closed,
for example through the JavaScript \c{window.close()} call.
+
+ \sa QWebEnginePage::RequestClose
*/
/*!
@@ -471,7 +519,7 @@
/*!
\property QWebEnginePage::url
- \brief the url of the frame currently viewed
+ \brief the URL of the frame currently viewed
Setting this property clears the view and loads the URL.
@@ -482,16 +530,16 @@
/*!
\property QWebEnginePage::iconUrl
- \brief the url of the icon associated with the frame currently viewed.
+ \brief the URL of the icon associated with the frame currently viewed.
\sa iconUrlChanged()
*/
/*!
\property QWebEnginePage::requestedUrl
+ \brief the URL requested to be loaded by the frame currently viewed
- The URL requested to loaded by the frame currently viewed. The URL may differ from
- the one returned by url() if a DNS resolution or a redirection occurs.
+ The URL may differ from the one returned by url() if a DNS resolution or a redirection occurs.
\sa url(), setUrl()
*/
@@ -500,7 +548,7 @@
\fn void QWebEnginePage::load(const QUrl &url)
Loads \a url into this frame.
- \note The view remains the same until enough data has arrived to display the new \a url.
+ \note The view remains the same until enough data has arrived to display the new URL.
\sa setUrl(), setHtml(), setContent()
*/
@@ -516,16 +564,16 @@
for example due to being blocked by a modal JavaScript alert dialog, this method will return
as soon as possible after the timeout and any subsequent \a html will be loaded asynchronously.
- When using this method WebEngie assumes that external resources such as JavaScript programs or style
- sheets are encoded in UTF-8 unless otherwise specified. For example, the encoding of an external
+ When using this method, the web engine assumes that external resources, such as JavaScript programs or style
+ sheets, are encoded in UTF-8 unless otherwise specified. For example, the encoding of an external
script can be specified through the charset attribute of the HTML script tag. It is also possible
- for the encoding to be specified by web server.
+ for the encoding to be specified by the web server.
This is a convenience function equivalent to setContent(html, "text/html", baseUrl).
\note This method will not affect session or global history for the frame.
- \warning This function works only for HTML, for other mime types (i.e. XHTML, SVG)
+ \warning This function works only for HTML, for other mime types (such as XHTML and SVG)
setContent() should be used instead.
\sa toHtml(), setContent(), load()
@@ -534,7 +582,7 @@
/*!
\fn void QWebEnginePage::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
Sets the content of this page's main frame to the specified content \a data. If the \a mimeType argument
- is empty it is currently assumed that the content is HTML but in future versions we may introduce
+ is empty, it is currently assumed that the content is HTML but in future versions we may introduce
auto-detection.
External objects referenced in the content are located relative to \a baseUrl.
@@ -553,16 +601,27 @@
/*!
\fn void QWebEnginePage::runJavaScript(const QString& scriptSource)
- Runs the JavaScript code contained in \a scriptSource.
+ \overload runJavaScript()
+
+ This convenience function runs the JavaScript code contained in \a scriptSource.
*/
/*!
\fn void QWebEnginePage::runJavaScript(const QString& scriptSource, FunctorOrLambda resultCallback)
+
Runs the JavaScript code contained in \a scriptSource.
+ The script will run in the same \e world as other scripts that are part of the loaded site.
+
When the script has been executed, \a resultCallback is called with the result of the last executed statement.
+ \a resultCallback can be any of a function pointer, a functor or a lambda, and it is expected to take a
+ QVariant parameter. For example:
+
+ \code
+ page.runJavaScript("document.title", [](const QVariant &v) { qDebug() << v.toString(); });
+ \endcode
- \note \a resultCallback can be any of a function pointer, a functor or a lambda, and it is expected to take a QVariant parameter.
+ See scripts() for an alternative API to inject scripts.
*/
/*!
@@ -570,7 +629,7 @@
Sets the permission for the web site identified by \a securityOrigin to use \a feature to \a policy.
- \note Call this method on featurePermissionRequested() signal, as it is
+ \note Call this method on the featurePermissionRequested() signal, as it is
meant to serve pending feature requests only. Setting feature permissions
ahead of a request has no effect.
diff --git a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
index 567f26e20..3dc23e037 100644
--- a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
@@ -119,6 +119,10 @@
Enables animated scrolling. Disabled by default.
\value ErrorPageEnabled
Enables displaying the built-in error pages of Chromium. Enabled by default.
+ \value PluginsEnabled
+ Enables support for Pepper plugins, such as the Flash player. Disabled by default.
+ \value FullScreenSupportEnabled
+ Enables fullscreen support in an application. Disabled by default.
*/
/*!
diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
index 163e9a28e..9d03527e1 100644
--- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
@@ -33,57 +33,48 @@
\inmodule QtWebEngineWidgets
- QWebEngineView is the main widget component of the Qt WebEngine web browsing module.
+ A \e {web view} is the main widget component of the Qt WebEngine web browsing module.
It can be used in various applications to display web content live from the
Internet.
- A web site can be loaded onto QWebEngineView with the load() function. Like all
+ A \e {web site} can be loaded to a web view with the load() function. Like all
Qt widgets, the show() function must be invoked in order to display
- QWebEngineView. The snippet below illustrates this:
+ the web view. The snippet below illustrates this:
- \snippet snippets/simple/main.cpp Using QWebEngineView
+ \snippet simple/main.cpp Using QWebEngineView
- Alternatively, setUrl() can also be used to load a web site. If you have
+ Alternatively, setUrl() can be used to load a web site. If you have
the HTML content readily available, you can use setHtml() instead.
- The loadStarted() signal is emitted when the view begins loading. The
- loadProgress() signal, on the other hand, is emitted whenever an element of
- the web view completes loading, such as an embedded image, a script, etc.
- Finally, the loadFinished() signal is emitted when the view has loaded
- completely. It's argument - either \c true or \c false - indicates
- load success or failure.
+ The loadStarted() signal is emitted when the view begins loading and the loadProgress()
+ signal is emitted whenever an element of the web view completes loading, such as an embedded
+ image or a script. The loadFinished() signal is emitted when the view has been loaded
+ completely. Its argument, either \c true or \c false, indicates whether loading was
+ successful or failed.
- The page() function returns a pointer to the web page object. See
- \l{Elements of QWebEngineView} for an explanation of how the web page
- is related to the view.
+ The page() function returns a pointer to a \e {web page} object. A QWebEngineView contains a
+ QWebEnginePage, which in turn allows access to the QWebEngineHistory in the page's context.
The title of an HTML document can be accessed with the title() property.
- Additionally, a web site may also specify an icon, which can be accessed
+ Additionally, a web site may specify an icon, which can be accessed
using the iconUrl() property. If the title or the icon changes, the corresponding
titleChanged() and iconUrlChanged() signals will be emitted. The
- textSizeMultiplier() property can be used to change the overall size of
- the text displayed in the web view.
+ zoomFactor() property can be used to change the overall size of the contents of the web view.
If you require a custom context menu, you can implement it by reimplementing
\l{QWidget::}{contextMenuEvent()} and populating your QMenu with the actions
- obtained from pageAction(). More functionality such as reloading the view,
- copying selected text to the clipboard, or pasting into the view, is also
+ obtained from pageAction(). Additional functionality, such as reloading the view,
+ copying selected text to the clipboard, or pasting into the view, is
encapsulated within the QAction objects returned by pageAction(). These
actions can be programmatically triggered using triggerPageAction().
Alternatively, the actions can be added to a toolbar or a menu directly.
- QWebEngineView maintains the state of the returned actions but allows
+ The web view maintains the state of the returned actions but allows
modification of action properties such as \l{QAction::}{text} or
\l{QAction::}{icon}.
If you want to provide support for web sites that allow the user to open
new windows, such as pop-up windows, you can subclass QWebEngineView and
reimplement the createWindow() function.
-
- \section1 Elements of QWebEngineView
-
- QWebEngineView contains a QWebEnginePage, which in turn allows access to the
- QWebEngineHistory in the page's context.
-
*/
// FIXME: reintroduce the following when we have proper names for the examples.
// \sa {WebEngine Tab Browser Example}, {WebEngine Fancy Browser Example}
@@ -91,7 +82,7 @@
/*!
\fn QWebEngineView::QWebEngineView(QWidget *parent)
- Constructs an empty QWebEngineView with parent \a parent.
+ Constructs an empty web view with the parent \a parent.
\sa load()
*/
@@ -123,29 +114,29 @@
\fn void QWebEngineView::load(const QUrl &url)
Loads the specified \a url and displays it.
- \note The view remains the same until enough data has arrived to display the new \a url.
+ \note The view remains the same until enough data has arrived to display the new URL.
\sa setUrl(), url(), urlChanged(), QUrl::fromUserInput()
*/
/*!
\fn void QWebEngineView::setHtml(const QString &html, const QUrl &baseUrl)
- Sets the content of the web view to the specified \a html.
+ Sets the content of the web view to the specified \a html content.
- External objects such as stylesheets or images referenced in the HTML
- document are located relative to \a baseUrl.
+ External objects, such as stylesheets or images referenced in the HTML
+ document, are located relative to \a baseUrl.
- The \a html is loaded immediately; external objects are loaded asynchronously.
+ The HTML document is loaded immediately, whereas external objects are loaded asynchronously.
- When using this method, Qt WebEngine assumes that external resources such as
- JavaScript programs or style sheets are encoded in UTF-8 unless otherwise
+ When using this method, Qt WebEngine assumes that external resources, such as
+ JavaScript programs or style sheets, are encoded in UTF-8 unless otherwise
specified. For example, the encoding of an external script can be specified
- through the charset attribute of the HTML script tag. Alternatively, the
- encoding can also be specified by the web server.
+ through the \c charset attribute of the HTML script tag. Alternatively, the
+ encoding can be specified by the web server.
This is a convenience function equivalent to setContent(html, "text/html", baseUrl).
- \warning This function works only for HTML, for other mime types (i.e. XHTML, SVG)
+ \warning This function works only for HTML. For other MIME types (such as XHTML or SVG),
setContent() should be used instead.
\sa load(), setContent(), QWebEnginePage::toHtml(), QWebEnginePage::setContent()
@@ -154,12 +145,12 @@
/*!
\fn void QWebEngineView::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
Sets the content of the web view to the specified content \a data. If the \a mimeType argument
- is empty it is currently assumed that the content is HTML but in future versions we may introduce
- auto-detection.
+ is empty, it is currently assumed that the content is HTML but in future versions we may
+ introduce auto-detection.
External objects referenced in the content are located relative to \a baseUrl.
- The \a data is loaded immediately; external objects are loaded asynchronously.
+ The data is loaded immediately; external objects are loaded asynchronously.
\sa load(), setHtml(), QWebEnginePage::toHtml()
*/
@@ -168,9 +159,9 @@
\fn QWebEngineHistory *QWebEngineView::history() const
Returns a pointer to the view's history of navigated web pages.
- It is equivalent to
+ It is equivalent to:
- \snippet snippets/qtwebengine_qwebengineview_snippet.cpp 0
+ \snippet qtwebengine_qwebengineview_snippet.cpp 0
*/
/*!
@@ -184,7 +175,7 @@
/*!
\property QWebEngineView::url
- \brief the url of the web page currently viewed
+ \brief the URL of the web page currently viewed
Setting this property clears the view and loads the URL.
@@ -195,7 +186,7 @@
/*!
\property QWebEngineView::iconUrl
- \brief the url of the icon associated with the web page currently viewed
+ \brief the URL of the icon associated with the web page currently viewed
\sa iconUrlChanged()
*/
@@ -204,7 +195,7 @@
\property QWebEngineView::hasSelection
\brief whether this page contains selected content or not.
- By default, this property is false.
+ By default, this property is \c false.
\sa selectionChanged()
*/
@@ -225,13 +216,13 @@
/*!
\fn void QWebEngineView::triggerPageAction(QWebEnginePage::WebAction action, bool checked)
- Triggers the specified \a action. If it is a checkable action the specified
+ Triggers the specified \a action. If it is a checkable action, the specified
\a checked state is assumed.
The following example triggers the copy action and therefore copies any
selected text to the clipboard.
- \snippet snippets/qtwebengine_qwebengineview_snippet.cpp 2
+ \snippet qtwebengine_qwebengineview_snippet.cpp 2
\sa pageAction()
*/
@@ -256,8 +247,8 @@
To clear the selection, just pass an empty string.
- The \a resultCallback must take a boolean parameter. It will be called with a value of true if the \a subString
- was found; otherwise the callback value will be false.
+ \a resultCallback must take a boolean parameter. It will be called with a value of \c true
+ if \a subString was found; otherwise the callback value will be \c false.
\sa selectedText(), selectionChanged()
*/
@@ -266,9 +257,9 @@
\fn void QWebEngineView::stop()
Convenience slot that stops loading the document.
- It is equivalent to
+ It is equivalent to:
- \snippet snippets/qtwebengine_qwebengineview_snippet.cpp 3
+ \snippet qtwebengine_qwebengineview_snippet.cpp 3
\sa reload(), pageAction(), loadFinished()
*/
@@ -278,9 +269,9 @@
Convenience slot that loads the previous document in the list of documents
built by navigating links. Does nothing if there is no previous document.
- It is equivalent to
+ It is equivalent to:
- \snippet snippets/qtwebengine_qwebengineview_snippet.cpp 4
+ \snippet qtwebengine_qwebengineview_snippet.cpp 4
\sa forward(), pageAction()
*/
@@ -290,9 +281,9 @@
Convenience slot that loads the next document in the list of documents
built by navigating links. Does nothing if there is no next document.
- It is equivalent to
+ It is equivalent to:
- \snippet snippets/qtwebengine_qwebengineview_snippet.cpp 5
+ \snippet qtwebengine_qwebengineview_snippet.cpp 5
\sa back(), pageAction()
*/
@@ -306,11 +297,11 @@
/*!
\fn QWebEngineView *QWebEngineView::createWindow(QWebEnginePage::WebWindowType type)
- This function is called from the createWindow() method of the associated QWebEnginePage,
- each time the page wants to create a new window of the given \a type. This might
- be the result, for example, of a JavaScript request to open a document in a new window.
+ This function is called from the \l{QWebEnginePage::}{createWindow()} method of the associated
+ QWebEnginePage each time the page wants to create a new window of the given \a type. For
+ example, when a JavaScript request to open a document in a new window is issued.
- \note If the createWindow() method of the associated page is reimplemented, this
+ \note If the \c createWindow() method of the associated page is reimplemented, this
method is not called, unless explicitly done so in the reimplementation.
\sa QWebEnginePage::createWindow()
@@ -351,8 +342,8 @@
/*!
\fn void QWebEngineView::loadFinished(bool ok)
- This signal is emitted when a load of the page is finished.
- \a ok will indicate whether the load was successful or any error occurred.
+ This signal is emitted when a load of the page has finished.
+ \a ok will indicate whether the load was successful or an error occurred.
\sa loadStarted()
*/
@@ -382,11 +373,11 @@
/*!
\fn QWebEngineSettings *QWebEngineView::settings() const
- Returns a pointer to the view/page specific settings object.
+ Returns a pointer to the view or page specific settings object.
- It is equivalent to
+ It is equivalent to:
- \snippet snippets/qtwebengine_qwebengineview_snippet.cpp 6
+ \snippet qtwebengine_qwebengineview_snippet.cpp 6
\sa QWebEngineSettings::globalSettings()
*/
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
index dba37cea7..76ca8d354 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -59,6 +59,7 @@ RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(Rende
, m_rootNode(new QSGRootNode)
, m_sgEngine(new QSGEngine)
, m_isPopup(false)
+ , m_clearColor(Qt::white)
{
setFocusPolicy(Qt::StrongFocus);
@@ -218,6 +219,19 @@ void RenderWidgetHostViewQtDelegateWidget::setTooltip(const QString &tooltip)
setToolTip(wrappedTip);
}
+void RenderWidgetHostViewQtDelegateWidget::setClearColor(const QColor &color)
+{
+ m_clearColor = color;
+ // QOpenGLWidget is usually blended by punching holes into widgets
+ // above it to simulate the visual stacking order. If we want it to be
+ // transparent we have to throw away the proper stacking order and always
+ // blend the complete normal widgets backing store under it.
+ bool isTranslucent = color.alpha() < 255;
+ setAttribute(Qt::WA_AlwaysStackOnTop, isTranslucent);
+ setAttribute(Qt::WA_OpaquePaintEvent, !isTranslucent);
+ update();
+}
+
QVariant RenderWidgetHostViewQtDelegateWidget::inputMethodQuery(Qt::InputMethodQuery query) const
{
return m_client->inputMethodQuery(query);
@@ -270,7 +284,7 @@ void RenderWidgetHostViewQtDelegateWidget::initializeGL()
m_sgEngine->initialize(QOpenGLContext::currentContext());
m_sgRenderer.reset(m_sgEngine->createRenderer());
m_sgRenderer->setRootNode(m_rootNode.data());
- m_sgRenderer->setClearColor(Qt::white);
+ m_sgRenderer->setClearColor(m_clearColor);
}
void RenderWidgetHostViewQtDelegateWidget::paintGL()
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
index d0dfdc689..d228bd487 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -78,6 +78,7 @@ public:
virtual void move(const QPoint &screenPos) Q_DECL_OVERRIDE;
virtual void inputMethodStateChanged(bool editorVisible) Q_DECL_OVERRIDE;
virtual void setTooltip(const QString &tooltip) Q_DECL_OVERRIDE;
+ virtual void setClearColor(const QColor &color) Q_DECL_OVERRIDE;
protected:
bool event(QEvent *event) Q_DECL_OVERRIDE;
@@ -98,6 +99,7 @@ private:
QScopedPointer<QSGEngine> m_sgEngine;
QScopedPointer<QSGAbstractRenderer> m_sgRenderer;
bool m_isPopup;
+ QColor m_clearColor;
QList<QMetaObject::Connection> m_windowConnections;
};
diff --git a/src/webenginewidgets/webenginewidgets.pro b/src/webenginewidgets/webenginewidgets.pro
index 1f7974bd2..4622d0028 100644
--- a/src/webenginewidgets/webenginewidgets.pro
+++ b/src/webenginewidgets/webenginewidgets.pro
@@ -3,25 +3,22 @@ TARGET = QtWebEngineWidgets
# For our export macros
DEFINES += QT_BUILD_WEBENGINEWIDGETS_LIB
-QT += webengine widgets network quick
-QT_PRIVATE += webenginecore quick-private gui-private core-private
+QT += webengine webenginecore widgets network quick
+QT_PRIVATE += quick-private gui-private core-private
-QMAKE_DOCS = $$PWD/doc/qtwebenginewidgets.qdocconf
-
-INCLUDEPATH += $$PWD api ../core ../webengine/api
+INCLUDEPATH += $$PWD api ../core ../core/api ../webengine/api
SOURCES = \
api/qtwebenginewidgetsglobal.cpp \
api/qwebenginecertificateerror.cpp \
api/qwebenginedownloaditem.cpp \
+ api/qwebenginefullscreenrequest.cpp \
api/qwebenginehistory.cpp \
api/qwebenginepage.cpp \
api/qwebengineprofile.cpp \
api/qwebenginescript.cpp \
api/qwebenginescriptcollection.cpp \
api/qwebenginesettings.cpp \
- api/qwebengineurlrequestjob.cpp \
- api/qwebengineurlschemehandler.cpp \
api/qwebengineview.cpp \
render_widget_host_view_qt_delegate_widget.cpp
@@ -30,6 +27,7 @@ HEADERS = \
api/qwebenginedownloaditem.h \
api/qwebenginedownloaditem_p.h \
api/qwebenginecertificateerror.h \
+ api/qwebenginefullscreenrequest.h \
api/qwebenginehistory.h \
api/qwebenginepage.h \
api/qwebenginepage_p.h \
@@ -38,9 +36,6 @@ HEADERS = \
api/qwebenginescriptcollection.h \
api/qwebenginescriptcollection_p.h \
api/qwebenginesettings.h \
- api/qwebengineurlrequestjob_p.h \
- api/qwebengineurlschemehandler_p.h \
- api/qwebengineurlschemehandler_p_p.h \
api/qwebengineview.h \
api/qwebengineview_p.h \
render_widget_host_view_qt_delegate_widget.h
diff --git a/sync.profile b/sync.profile
index 774941d56..11d7b0548 100644
--- a/sync.profile
+++ b/sync.profile
@@ -1,10 +1,12 @@
%modules = ( # path to module name map
"QtWebEngine" => "$basedir/src/webengine",
"QtWebEngineWidgets" => "$basedir/src/webenginewidgets",
+ "QtWebEngineCore" => "$basedir/src/core",
);
%moduleheaders = ( # restrict the module headers to those found in relative path
"QtWebEngine" => "api",
"QtWebEngineWidgets" => "api",
+ "QtWebEngineCore" => "api",
);
%classnames = (
);
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index f14305f72..06430cf8e 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -4,4 +4,6 @@ SUBDIRS = quick
qtHaveModule(webenginewidgets) {
SUBDIRS += widgets
+# core tests depend on widgets for now
+ SUBDIRS += core
}
diff --git a/tests/auto/core/core.pro b/tests/auto/core/core.pro
new file mode 100644
index 000000000..ed0a61532
--- /dev/null
+++ b/tests/auto/core/core.pro
@@ -0,0 +1,7 @@
+TEMPLATE = subdirs
+
+CONFIG += ordered
+
+SUBDIRS += \
+ qwebenginecookiestoreclient \
+ qwebengineurlrequestinterceptor \
diff --git a/tests/auto/core/qwebenginecookiestoreclient/qwebenginecookiestoreclient.pro b/tests/auto/core/qwebenginecookiestoreclient/qwebenginecookiestoreclient.pro
new file mode 100644
index 000000000..e99c7f493
--- /dev/null
+++ b/tests/auto/core/qwebenginecookiestoreclient/qwebenginecookiestoreclient.pro
@@ -0,0 +1 @@
+include(../tests.pri)
diff --git a/tests/auto/core/qwebenginecookiestoreclient/resources/content.html b/tests/auto/core/qwebenginecookiestoreclient/resources/content.html
new file mode 100644
index 000000000..360ad65ef
--- /dev/null
+++ b/tests/auto/core/qwebenginecookiestoreclient/resources/content.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<a>This is test content</a>
+</body>
+</html>
diff --git a/tests/auto/core/qwebenginecookiestoreclient/resources/index.html b/tests/auto/core/qwebenginecookiestoreclient/resources/index.html
new file mode 100644
index 000000000..d41866712
--- /dev/null
+++ b/tests/auto/core/qwebenginecookiestoreclient/resources/index.html
@@ -0,0 +1,38 @@
+<html>
+ <head>
+ <script type="text/javascript">
+ function generateCookieString(key, value, options) {
+ key = key.replace(/[^#$&+\^`|]/g, encodeURIComponent);
+ key = key.replace(/\(/g, '%28').replace(/\)/g, '%29');
+ value = (value + '').replace(/[^!#$&-+\--:<-\[\]-~]/g, encodeURIComponent);
+ options = options || {};
+
+ var cookieString = key + '=' + value;
+ cookieString += options.path ? '; Path=' + options.path : '';
+ cookieString += options.domain ? '; Domain=' + options.domain : '';
+ cookieString += options.expires ? '; Expires=' + options.expires.toUTCString() : '';
+ cookieString += options.secure ? '; Secure' : '';
+
+ console.log(cookieString)
+ return cookieString;
+};
+function setCookie() {
+ var name = "SessionCookie"
+ var value = "QtWebEngineCookieTest"
+ document.cookie = generateCookieString(name, value, {})
+
+ name = "CookieWithExpiresField"
+ value = "QtWebEngineCookieTest"
+ var daysValid = 10;
+ var date = new Date();
+ date.setTime(date.getTime() + (daysValid*24*60*60*1000));
+ var expires = date;
+ var options = {};
+ options.expires = expires;
+ document.cookie = generateCookieString(name, value, options)
+}
+</script>
+ </head>
+ <body onload="setCookie()">
+ </body>
+</html>
diff --git a/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp b/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp
new file mode 100644
index 000000000..d78a81c21
--- /dev/null
+++ b/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../../widgets/util.h"
+#include <QtTest/QtTest>
+#include <QtWebEngineCore/qwebenginecallback.h>
+#include <QtWebEngineCore/qwebenginecookiestoreclient.h>
+#include <QtWebEngineWidgets/qwebenginepage.h>
+#include <QtWebEngineWidgets/qwebengineprofile.h>
+#include <QtWebEngineWidgets/qwebengineview.h>
+
+class tst_QWebEngineCookieStoreClient : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QWebEngineCookieStoreClient();
+ ~tst_QWebEngineCookieStoreClient();
+
+public Q_SLOTS:
+ void init();
+ void cleanup();
+
+private Q_SLOTS:
+ void initTestCase();
+ void cleanupTestCase();
+ void cookieSignals();
+ void setAndDeleteCookie();
+ void batchCookieTasks();
+};
+
+tst_QWebEngineCookieStoreClient::tst_QWebEngineCookieStoreClient()
+{
+}
+
+tst_QWebEngineCookieStoreClient::~tst_QWebEngineCookieStoreClient()
+{
+}
+
+void tst_QWebEngineCookieStoreClient::init()
+{
+}
+
+void tst_QWebEngineCookieStoreClient::cleanup()
+{
+}
+
+void tst_QWebEngineCookieStoreClient::initTestCase()
+{
+}
+
+void tst_QWebEngineCookieStoreClient::cleanupTestCase()
+{
+}
+
+void tst_QWebEngineCookieStoreClient::cookieSignals()
+{
+ QWebEngineView view;
+ QWebEngineCookieStoreClient *client = view.page()->profile()->cookieStoreClient();
+
+ QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
+ QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(const QNetworkCookie &)));
+ QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(const QNetworkCookie &)));
+
+ view.load(QUrl("qrc:///resources/index.html"));
+
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QVariant success = loadSpy.takeFirst().takeFirst();
+ QVERIFY(success.toBool());
+ QTRY_COMPARE(cookieAddedSpy.count(), 2);
+
+ // try whether updating a cookie to be expired results in that cookie being removed.
+ QNetworkCookie expiredCookie(QNetworkCookie::parseCookies(QByteArrayLiteral("SessionCookie=delete; expires=Thu, 01-Jan-1970 00:00:00 GMT; path=///resources")).first());
+ client->setCookie(expiredCookie, QUrl("qrc:///resources/index.html"));
+ QTRY_COMPARE(cookieRemovedSpy.count(), 1);
+ cookieRemovedSpy.clear();
+
+ // try removing the other cookie.
+ QNetworkCookie nonSessionCookie(QNetworkCookie::parseCookies(QByteArrayLiteral("CookieWithExpiresField=QtWebEngineCookieTest; path=///resources")).first());
+ client->deleteCookie(nonSessionCookie, QUrl("qrc:///resources/index.html"));
+ QTRY_COMPARE(cookieRemovedSpy.count(), 1);
+}
+
+void tst_QWebEngineCookieStoreClient::setAndDeleteCookie()
+{
+ QWebEngineView view;
+ QWebEngineCookieStoreClient *client = view.page()->profile()->cookieStoreClient();
+
+ QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
+ QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(const QNetworkCookie &)));
+ QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(const QNetworkCookie &)));
+
+ QNetworkCookie cookie1(QNetworkCookie::parseCookies(QByteArrayLiteral("khaos=I9GX8CWI; Domain=.example.com; Path=/docs")).first());
+ QNetworkCookie cookie2(QNetworkCookie::parseCookies(QByteArrayLiteral("Test%20Cookie=foobar; domain=example.com; Path=/")).first());
+ QNetworkCookie cookie3(QNetworkCookie::parseCookies(QByteArrayLiteral("SessionCookie=QtWebEngineCookieTest; Path=///resources")).first());
+ QNetworkCookie expiredCookie3(QNetworkCookie::parseCookies(QByteArrayLiteral("SessionCookie=delete; expires=Thu, 01-Jan-1970 00:00:00 GMT; path=///resources")).first());
+
+ // check if pending cookies are set and removed
+ client->setCookieWithCallback(cookie1, [](bool success) { QVERIFY(success); });
+ client->setCookieWithCallback(cookie2, [](bool success) { QVERIFY(success); });
+ client->deleteCookie(cookie1);
+
+ view.load(QUrl("qrc:///resources/content.html"));
+
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QVariant success = loadSpy.takeFirst().takeFirst();
+ QVERIFY(success.toBool());
+ QTRY_COMPARE(cookieAddedSpy.count(), 2);
+ QTRY_COMPARE(cookieRemovedSpy.count(), 1);
+ cookieAddedSpy.clear();
+ cookieRemovedSpy.clear();
+
+ client->setCookieWithCallback(cookie3, [](bool success) { QVERIFY(success); });
+ // updating a cookie with an expired 'expires' field should remove the cookie with the same name
+ client->setCookieWithCallback(expiredCookie3, [](bool success) { QVERIFY(success); });
+ client->deleteCookie(cookie2);
+ QTRY_COMPARE(cookieAddedSpy.count(), 1);
+ QTRY_COMPARE(cookieRemovedSpy.count(), 2);
+}
+
+void tst_QWebEngineCookieStoreClient::batchCookieTasks()
+{
+ QWebEngineView view;
+ QWebEngineCookieStoreClient *client = view.page()->profile()->cookieStoreClient();
+
+ QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
+ QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(const QNetworkCookie &)));
+ QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(const QNetworkCookie &)));
+
+ QNetworkCookie cookie1(QNetworkCookie::parseCookies(QByteArrayLiteral("khaos=I9GX8CWI; Domain=.example.com; Path=/docs")).first());
+ QNetworkCookie cookie2(QNetworkCookie::parseCookies(QByteArrayLiteral("Test%20Cookie=foobar; domain=example.com; Path=/")).first());
+
+ int capture = 0;
+
+ client->setCookieWithCallback(cookie1, [&capture](bool success) { QVERIFY(success); ++capture; });
+ client->setCookieWithCallback(cookie2, [&capture](bool success) { QVERIFY(success); ++capture; });
+
+ view.load(QUrl("qrc:///resources/index.html"));
+
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QVariant success = loadSpy.takeFirst().takeFirst();
+ QVERIFY(success.toBool());
+ QTRY_COMPARE(cookieAddedSpy.count(), 4);
+ QTRY_COMPARE(cookieRemovedSpy.count(), 0);
+ QTRY_COMPARE(capture, 2);
+ capture = 0;
+
+ cookieAddedSpy.clear();
+ cookieRemovedSpy.clear();
+
+ client->getAllCookies([&capture](const QByteArray& cookieLine) {
+ ++capture;
+ QCOMPARE(QNetworkCookie::parseCookies(cookieLine).count(), 4);
+ });
+
+ client->deleteSessionCookiesWithCallback([&capture](int numDeleted) {
+ ++capture;
+ QCOMPARE(numDeleted, 3);
+ });
+
+ client->deleteAllCookiesWithCallback([&capture](int numDeleted) {
+ ++capture;
+ QCOMPARE(numDeleted, 1);
+ });
+
+ QTRY_COMPARE(capture, 3);
+}
+
+QTEST_MAIN(tst_QWebEngineCookieStoreClient)
+#include "tst_qwebenginecookiestoreclient.moc"
diff --git a/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.qrc b/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.qrc
new file mode 100644
index 000000000..afeae268b
--- /dev/null
+++ b/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>resources/index.html</file>
+ <file>resources/content.html</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro b/tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro
new file mode 100644
index 000000000..e99c7f493
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro
@@ -0,0 +1 @@
+include(../tests.pri)
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/content.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/content.html
new file mode 100644
index 000000000..360ad65ef
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/content.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<a>This is test content</a>
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/firstparty.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/firstparty.html
new file mode 100644
index 000000000..8bc540c08
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/firstparty.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<iframe src="qrc:///resources/content.html"></iframe>
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/index.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/index.html
new file mode 100644
index 000000000..a744dbd99
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/index.html
@@ -0,0 +1,16 @@
+<html>
+ <head>
+ <script type="text/javascript">
+ function post() {
+ var form = document.createElement("form");
+ form.setAttribute("method", "POST");
+ document.body.appendChild(form);
+ form.submit();
+ return true;
+ }
+</script>
+ </head>
+ <body>
+ <h1>Test page</h1>
+ </body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
new file mode 100644
index 000000000..4891cafd0
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../../widgets/util.h"
+#include <QtTest/QtTest>
+#include <QtWebEngineCore/qwebengineurlrequestinterceptor.h>
+#include <QtWebEngineWidgets/qwebenginepage.h>
+#include <QtWebEngineWidgets/qwebengineprofile.h>
+#include <QtWebEngineWidgets/qwebenginesettings.h>
+#include <QtWebEngineWidgets/qwebengineview.h>
+
+class tst_QWebEngineUrlRequestInterceptor : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QWebEngineUrlRequestInterceptor();
+ ~tst_QWebEngineUrlRequestInterceptor();
+
+public Q_SLOTS:
+ void init();
+ void cleanup();
+
+private Q_SLOTS:
+ void initTestCase();
+ void cleanupTestCase();
+ void interceptRequest();
+ void ipv6HostEncoding();
+ void requestedUrl();
+ void setUrlSameUrl();
+ void firstPartyUrl();
+};
+
+tst_QWebEngineUrlRequestInterceptor::tst_QWebEngineUrlRequestInterceptor()
+{
+}
+
+tst_QWebEngineUrlRequestInterceptor::~tst_QWebEngineUrlRequestInterceptor()
+{
+}
+
+void tst_QWebEngineUrlRequestInterceptor::init()
+{
+}
+
+void tst_QWebEngineUrlRequestInterceptor::cleanup()
+{
+}
+
+void tst_QWebEngineUrlRequestInterceptor::initTestCase()
+{
+}
+
+void tst_QWebEngineUrlRequestInterceptor::cleanupTestCase()
+{
+}
+
+class TestRequestInterceptor : public QWebEngineUrlRequestInterceptor
+{
+public:
+ QList<QUrl> observedUrls;
+ QList<QUrl> firstPartyUrls;
+ bool shouldIntercept;
+
+ bool interceptRequest(QWebEngineUrlRequestInfo &info) override
+ {
+ info.block(info.requestMethod() != QByteArrayLiteral("GET"));
+ if (info.requestUrl().toString().endsWith(QLatin1String("__placeholder__")))
+ info.redirect(QUrl("qrc:///resources/content.html"));
+
+ observedUrls.append(info.requestUrl());
+ firstPartyUrls.append(info.firstPartyUrl());
+ return shouldIntercept;
+ }
+ TestRequestInterceptor(bool intercept)
+ : shouldIntercept(intercept)
+ {
+ }
+};
+
+void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
+{
+ QWebEngineView view;
+ TestRequestInterceptor interceptor(/* intercept */ true);
+
+ QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
+ view.page()->profile()->setRequestInterceptor(&interceptor);
+ view.load(QUrl("qrc:///resources/index.html"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QVariant success = loadSpy.takeFirst().takeFirst();
+ QVERIFY(success.toBool());
+ loadSpy.clear();
+ QVariant ok;
+
+ view.page()->runJavaScript("post();", [&ok](const QVariant result){ ok = result; });
+ QTRY_VERIFY(ok.toBool());
+ QTRY_COMPARE(loadSpy.count(), 1);
+ success = loadSpy.takeFirst().takeFirst();
+ // We block non-GET requests, so this should not succeed.
+ QVERIFY(!success.toBool());
+ loadSpy.clear();
+
+ view.load(QUrl("qrc:///resources/__placeholder__"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ success = loadSpy.takeFirst().takeFirst();
+ // The redirection for __placeholder__ should succeed.
+ QVERIFY(success.toBool());
+ loadSpy.clear();
+ QCOMPARE(interceptor.observedUrls.count(), 4);
+
+
+ // Make sure that registering an observer does not modify the request.
+ TestRequestInterceptor observer(/* intercept */ false);
+ view.page()->profile()->setRequestInterceptor(&observer);
+ view.load(QUrl("qrc:///resources/__placeholder__"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ success = loadSpy.takeFirst().takeFirst();
+ // Since we do not intercept, loading an invalid path should not succeed.
+ QVERIFY(!success.toBool());
+ QCOMPARE(observer.observedUrls.count(), 1);
+}
+
+class LocalhostContentProvider : public QWebEngineUrlRequestInterceptor
+{
+public:
+ LocalhostContentProvider() { }
+
+ bool interceptRequest(QWebEngineUrlRequestInfo &info) override
+ {
+ requestedUrls.append(info.requestUrl());
+ info.redirect(QUrl("data:text/html,<p>hello"));
+ return true;
+ }
+
+ QList<QUrl> requestedUrls;
+};
+
+void tst_QWebEngineUrlRequestInterceptor::ipv6HostEncoding()
+{
+ QWebEngineView view;
+ QWebEnginePage *page = view.page();
+ LocalhostContentProvider contentProvider;
+ QSignalSpy spyLoadFinished(page, SIGNAL(loadFinished(bool)));
+
+ page->profile()->setRequestInterceptor(&contentProvider);
+
+ page->setHtml("<p>Hi", QUrl::fromEncoded("http://[::1]/index.html"));
+ QTRY_COMPARE(spyLoadFinished.count(), 1);
+ QCOMPARE(contentProvider.requestedUrls.count(), 0);
+
+ evaluateJavaScriptSync(page, "var r = new XMLHttpRequest();"
+ "r.open('GET', 'http://[::1]/test.xml', false);"
+ "r.send(null);"
+ );
+
+ QCOMPARE(contentProvider.requestedUrls.count(), 1);
+ QCOMPARE(contentProvider.requestedUrls.at(0), QUrl::fromEncoded("http://[::1]/test.xml"));
+}
+
+void tst_QWebEngineUrlRequestInterceptor::requestedUrl()
+{
+ QWebEnginePage page;
+ page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+ TestRequestInterceptor interceptor(/* intercept */ true);
+ page.profile()->setRequestInterceptor(&interceptor);
+
+ page.setUrl(QUrl("qrc:///resources/__placeholder__"));
+ waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(interceptor.observedUrls.at(0), QUrl("qrc:///resources/content.html"));
+ QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
+ QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
+
+ page.setUrl(QUrl("qrc:/non-existent.html"));
+ waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QCOMPARE(spy.count(), 2);
+ QCOMPARE(interceptor.observedUrls.at(2), QUrl("qrc:/non-existent.html"));
+ QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
+ QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
+
+ page.setUrl(QUrl("http://abcdef.abcdef"));
+ waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QCOMPARE(spy.count(), 3);
+ QCOMPARE(interceptor.observedUrls.at(3), QUrl("http://abcdef.abcdef/"));
+ QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
+ QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
+}
+
+void tst_QWebEngineUrlRequestInterceptor::setUrlSameUrl()
+{
+ QWebEnginePage page;
+ TestRequestInterceptor interceptor(/* intercept */ true);
+ page.profile()->setRequestInterceptor(&interceptor);
+
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+
+ page.setUrl(QUrl("qrc:///resources/__placeholder__"));
+ waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
+ QCOMPARE(spy.count(), 1);
+
+ page.setUrl(QUrl("qrc:///resources/__placeholder__"));
+ waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
+ QCOMPARE(spy.count(), 2);
+
+ // Now a case without redirect.
+ page.setUrl(QUrl("qrc:///resources/content.html"));
+ waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
+ QCOMPARE(spy.count(), 3);
+
+ page.setUrl(QUrl("qrc:///resources/__placeholder__"));
+ waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
+ QCOMPARE(spy.count(), 4);
+}
+
+void tst_QWebEngineUrlRequestInterceptor::firstPartyUrl()
+{
+ QWebEnginePage page;
+ TestRequestInterceptor interceptor(/* intercept */ false);
+ page.profile()->setRequestInterceptor(&interceptor);
+
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+
+ page.setUrl(QUrl("qrc:///resources/firstparty.html"));
+ waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QCOMPARE(interceptor.observedUrls.at(0), QUrl("qrc:///resources/firstparty.html"));
+ QCOMPARE(interceptor.observedUrls.at(1), QUrl("qrc:///resources/content.html"));
+ QCOMPARE(interceptor.firstPartyUrls.at(0), QUrl("qrc:///resources/firstparty.html"));
+ QCOMPARE(interceptor.firstPartyUrls.at(1), QUrl("qrc:///resources/firstparty.html"));
+ QCOMPARE(spy.count(), 1);
+}
+
+QTEST_MAIN(tst_QWebEngineUrlRequestInterceptor)
+#include "tst_qwebengineurlrequestinterceptor.moc"
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc
new file mode 100644
index 000000000..ca045e7fc
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc
@@ -0,0 +1,7 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>resources/index.html</file>
+ <file>resources/content.html</file>
+ <file>resources/firstparty.html</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/core/tests.pri b/tests/auto/core/tests.pri
new file mode 100644
index 000000000..cd6ef8615
--- /dev/null
+++ b/tests/auto/core/tests.pri
@@ -0,0 +1,17 @@
+TEMPLATE = app
+
+# FIXME: Re-enable once we want to run tests on the CI
+# CONFIG += testcase
+
+CONFIG += c++11
+
+VPATH += $$_PRO_FILE_PWD_
+TARGET = tst_$$TARGET
+
+SOURCES += $${TARGET}.cpp
+INCLUDEPATH += $$PWD
+
+exists($$_PRO_FILE_PWD_/$${TARGET}.qrc): RESOURCES += $${TARGET}.qrc
+
+QT += testlib network webenginewidgets widgets
+osx: CONFIG -= app_bundle
diff --git a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp
index 28a77d8cd..b5894a248 100644
--- a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp
+++ b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp
@@ -86,7 +86,7 @@ void tst_InspectorServer::prepareWebViewComponent()
m_component.reset(new QQmlComponent(engine, this));
m_component->setData(QByteArrayLiteral("import QtQuick 2.0\n"
- "import QtWebEngine 1.1\n"
+ "import QtWebEngine 1.2\n"
"WebEngineView { }")
, QUrl());
}
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index 8f0c2f6ec..bf0192e42 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -56,6 +56,7 @@
#include <private/qquickwebengineprofile_p.h>
#include <private/qquickwebenginescript_p.h>
#include <private/qquickwebenginesettings_p.h>
+#include <private/qquickwebenginesingleton_p.h>
class tst_publicapi : public QObject {
Q_OBJECT
@@ -76,6 +77,7 @@ static QList<const QMetaObject *> typesToCheck = QList<const QMetaObject *>()
<< &QQuickWebEngineScript::staticMetaObject
<< &QQuickWebEngineSettings::staticMetaObject
<< &QQuickWebEngineFullScreenRequest::staticMetaObject
+ << &QQuickWebEngineSingleton::staticMetaObject
;
static QList<const char *> knownEnumNames = QList<const char *>();
@@ -87,28 +89,22 @@ static QStringList hardcodedTypes = QStringList()
// Ignore the testSupport types without making a fuss.
<< "QQuickWebEngineTestSupport*"
<< "QQuickWebEngineErrorPage*"
+ << "QWebEngineCookieStoreClient*"
;
static QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.AcceptRequest --> NavigationRequestAction"
<< "QQuickWebEngineView.IgnoreRequest --> NavigationRequestAction"
+ << "QQuickWebEngineView.LinkClickedNavigation --> NavigationType"
+ << "QQuickWebEngineView.TypedNavigation --> NavigationType"
+ << "QQuickWebEngineView.FormSubmittedNavigation --> NavigationType"
+ << "QQuickWebEngineView.BackForwardNavigation --> NavigationType"
+ << "QQuickWebEngineView.ReloadNavigation --> NavigationType"
+ << "QQuickWebEngineView.OtherNavigation --> NavigationType"
<< "QQuickWebEngineView.LoadStartedStatus --> LoadStatus"
<< "QQuickWebEngineView.LoadStoppedStatus --> LoadStatus"
<< "QQuickWebEngineView.LoadSucceededStatus --> LoadStatus"
<< "QQuickWebEngineView.LoadFailedStatus --> LoadStatus"
- << "QQuickWebEngineCertificateError.SslPinnedKeyNotInCertificateChain --> Error"
- << "QQuickWebEngineCertificateError.CertificateCommonNameInvalid --> Error"
- << "QQuickWebEngineCertificateError.CertificateDateInvalid --> Error"
- << "QQuickWebEngineCertificateError.CertificateAuthorityInvalid --> Error"
- << "QQuickWebEngineCertificateError.CertificateContainsErrors --> Error"
- << "QQuickWebEngineCertificateError.CertificateNoRevocationMechanism --> Error"
- << "QQuickWebEngineCertificateError.CertificateUnableToCheckRevocation --> Error"
- << "QQuickWebEngineCertificateError.CertificateRevoked --> Error"
- << "QQuickWebEngineCertificateError.CertificateInvalid --> Error"
- << "QQuickWebEngineCertificateError.CertificateWeakSignatureAlgorithm --> Error"
- << "QQuickWebEngineCertificateError.CertificateNonUniqueName --> Error"
- << "QQuickWebEngineCertificateError.CertificateWeakKey --> Error"
- << "QQuickWebEngineCertificateError.CertificateNameConstraintViolation --> Error"
<< "QQuickWebEngineView.NoErrorDomain --> ErrorDomain"
<< "QQuickWebEngineView.InternalErrorDomain --> ErrorDomain"
<< "QQuickWebEngineView.ConnectionErrorDomain --> ErrorDomain"
@@ -116,14 +112,6 @@ static QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.HttpErrorDomain --> ErrorDomain"
<< "QQuickWebEngineView.FtpErrorDomain --> ErrorDomain"
<< "QQuickWebEngineView.DnsErrorDomain --> ErrorDomain"
- << "QQuickWebEngineView.FindBackward --> FindFlags"
- << "QQuickWebEngineView.FindCaseSensitively --> FindFlags"
- << "QQuickWebEngineView.LinkClickedNavigation --> NavigationType"
- << "QQuickWebEngineView.TypedNavigation --> NavigationType"
- << "QQuickWebEngineView.FormSubmittedNavigation --> NavigationType"
- << "QQuickWebEngineView.BackForwardNavigation --> NavigationType"
- << "QQuickWebEngineView.ReloadNavigation --> NavigationType"
- << "QQuickWebEngineView.OtherNavigation --> NavigationType"
<< "QQuickWebEngineView.NewViewInWindow --> NewViewDestination"
<< "QQuickWebEngineView.NewViewInTab --> NewViewDestination"
<< "QQuickWebEngineView.NewViewInDialog --> NewViewDestination"
@@ -132,31 +120,81 @@ static QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.MediaVideoCapture --> Feature"
<< "QQuickWebEngineView.MediaAudioVideoCapture --> Feature"
<< "QQuickWebEngineView.Geolocation --> Feature"
+ << "QQuickWebEngineView.NoWebAction --> WebAction"
+ << "QQuickWebEngineView.Back --> WebAction"
+ << "QQuickWebEngineView.Forward --> WebAction"
+ << "QQuickWebEngineView.Stop --> WebAction"
+ << "QQuickWebEngineView.Reload --> WebAction"
+ << "QQuickWebEngineView.Cut --> WebAction"
+ << "QQuickWebEngineView.Copy --> WebAction"
+ << "QQuickWebEngineView.Paste --> WebAction"
+ << "QQuickWebEngineView.Undo --> WebAction"
+ << "QQuickWebEngineView.Redo --> WebAction"
+ << "QQuickWebEngineView.SelectAll --> WebAction"
+ << "QQuickWebEngineView.ReloadAndBypassCache --> WebAction"
+ << "QQuickWebEngineView.PasteAndMatchStyle --> WebAction"
+ << "QQuickWebEngineView.OpenLinkInThisWindow --> WebAction"
+ << "QQuickWebEngineView.OpenLinkInNewWindow --> WebAction"
+ << "QQuickWebEngineView.OpenLinkInNewTab --> WebAction"
+ << "QQuickWebEngineView.CopyLinkToClipboard --> WebAction"
+ << "QQuickWebEngineView.DownloadLinkToDisk --> WebAction"
+ << "QQuickWebEngineView.CopyImageToClipboard --> WebAction"
+ << "QQuickWebEngineView.CopyImageUrlToClipboard --> WebAction"
+ << "QQuickWebEngineView.DownloadImageToDisk --> WebAction"
+ << "QQuickWebEngineView.CopyMediaUrlToClipboard --> WebAction"
+ << "QQuickWebEngineView.ToggleMediaControls --> WebAction"
+ << "QQuickWebEngineView.ToggleMediaLoop --> WebAction"
+ << "QQuickWebEngineView.ToggleMediaPlayPause --> WebAction"
+ << "QQuickWebEngineView.ToggleMediaMute --> WebAction"
+ << "QQuickWebEngineView.DownloadMediaToDisk --> WebAction"
+ << "QQuickWebEngineView.InspectElement --> WebAction"
+ << "QQuickWebEngineView.ExitFullScreen --> WebAction"
+ << "QQuickWebEngineView.WebActionCount --> WebAction"
<< "QQuickWebEngineView.InfoMessageLevel --> JavaScriptConsoleMessageLevel"
<< "QQuickWebEngineView.WarningMessageLevel --> JavaScriptConsoleMessageLevel"
<< "QQuickWebEngineView.ErrorMessageLevel --> JavaScriptConsoleMessageLevel"
- << "QQuickWebEngineView.title --> QString"
+ << "QQuickWebEngineView.NormalTerminationStatus --> RenderProcessTerminationStatus"
+ << "QQuickWebEngineView.AbnormalTerminationStatus --> RenderProcessTerminationStatus"
+ << "QQuickWebEngineView.CrashedTerminationStatus --> RenderProcessTerminationStatus"
+ << "QQuickWebEngineView.KilledTerminationStatus --> RenderProcessTerminationStatus"
+ << "QQuickWebEngineView.FindBackward --> FindFlags"
+ << "QQuickWebEngineView.FindCaseSensitively --> FindFlags"
<< "QQuickWebEngineView.url --> QUrl"
<< "QQuickWebEngineView.icon --> QUrl"
+ << "QQuickWebEngineView.loading --> bool"
+ << "QQuickWebEngineView.loadProgress --> int"
+ << "QQuickWebEngineView.title --> QString"
<< "QQuickWebEngineView.canGoBack --> bool"
<< "QQuickWebEngineView.canGoForward --> bool"
<< "QQuickWebEngineView.isFullScreen --> bool"
- << "QQuickWebEngineView.loading --> bool"
- << "QQuickWebEngineView.loadProgress --> int"
+ << "QQuickWebEngineView.zoomFactor --> double"
+ << "QQuickWebEngineView.profile --> QQuickWebEngineProfile*"
+ << "QQuickWebEngineView.settings --> QQuickWebEngineSettings*"
+ << "QQuickWebEngineView.navigationHistory --> QQuickWebEngineHistory*"
+ << "QQuickWebEngineView.webChannel --> QQmlWebChannel*"
+ << "QQuickWebEngineView.userScripts --> QQmlListProperty<QQuickWebEngineScript>"
+ << "QQuickWebEngineView.activeFocusOnPress --> bool"
+ << "QQuickWebEngineView.backgroundColor --> QColor"
+ << "QQuickWebEngineView.testSupport --> QQuickWebEngineTestSupport*"
<< "QQuickWebEngineView.titleChanged() --> void"
- << "QQuickWebEngineView.loadingChanged(QQuickWebEngineLoadRequest*) --> void"
- << "QQuickWebEngineView.certificateError(QQuickWebEngineCertificateError*) --> void"
- << "QQuickWebEngineView.loadProgressChanged() --> void"
- << "QQuickWebEngineView.javaScriptConsoleMessage(JavaScriptConsoleMessageLevel,QString,int,QString) --> void"
<< "QQuickWebEngineView.urlChanged() --> void"
<< "QQuickWebEngineView.iconChanged() --> void"
+ << "QQuickWebEngineView.loadingChanged(QQuickWebEngineLoadRequest*) --> void"
+ << "QQuickWebEngineView.loadProgressChanged() --> void"
<< "QQuickWebEngineView.linkHovered(QUrl) --> void"
<< "QQuickWebEngineView.navigationRequested(QQuickWebEngineNavigationRequest*) --> void"
+ << "QQuickWebEngineView.javaScriptConsoleMessage(JavaScriptConsoleMessageLevel,QString,int,QString) --> void"
+ << "QQuickWebEngineView.certificateError(QQuickWebEngineCertificateError*) --> void"
<< "QQuickWebEngineView.fullScreenRequested(QQuickWebEngineFullScreenRequest) --> void"
<< "QQuickWebEngineView.isFullScreenChanged() --> void"
- << "QQuickWebEngineView.fullScreenCancelled() --> void"
<< "QQuickWebEngineView.featurePermissionRequested(QUrl,Feature) --> void"
- << "QQuickWebEngineView.grantFeaturePermission(QUrl,Feature,bool) --> void"
+ << "QQuickWebEngineView.newViewRequested(QQuickWebEngineNewViewRequest*) --> void"
+ << "QQuickWebEngineView.zoomFactorChanged(double) --> void"
+ << "QQuickWebEngineView.profileChanged() --> void"
+ << "QQuickWebEngineView.webChannelChanged() --> void"
+ << "QQuickWebEngineView.activeFocusOnPressChanged(bool) --> void"
+ << "QQuickWebEngineView.backgroundColorChanged() --> void"
+ << "QQuickWebEngineView.renderProcessTerminated(RenderProcessTerminationStatus,int) --> void"
<< "QQuickWebEngineView.runJavaScript(QString,QJSValue) --> void"
<< "QQuickWebEngineView.runJavaScript(QString) --> void"
<< "QQuickWebEngineView.loadHtml(QString,QUrl) --> void"
@@ -164,37 +202,50 @@ static QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.goBack() --> void"
<< "QQuickWebEngineView.goForward() --> void"
<< "QQuickWebEngineView.goBackOrForward(int) --> void"
- << "QQuickWebEngineView.stop() --> void"
<< "QQuickWebEngineView.reload() --> void"
- << "QQuickWebEngineView.zoomFactor --> double"
- << "QQuickWebEngineView.zoomFactorChanged(double) --> void"
- << "QQuickWebEngineView.profile --> QQuickWebEngineProfile*"
- << "QQuickWebEngineView.profileChanged() --> void"
- << "QQuickWebEngineView.navigationHistory --> QQuickWebEngineHistory*"
- << "QQuickWebEngineView.newViewRequested(QQuickWebEngineNewViewRequest*) --> void"
- << "QQuickWebEngineView.userScripts --> QQmlListProperty<QQuickWebEngineScript>"
- << "QQuickWebEngineView.settings --> QQuickWebEngineSettings*"
- << "QQuickWebEngineView.testSupport --> QQuickWebEngineTestSupport*"
- << "QQuickWebEngineView.webChannel --> QQmlWebChannel*"
- << "QQuickWebEngineView.webChannelChanged() --> void"
<< "QQuickWebEngineView.reloadAndBypassCache() --> void"
+ << "QQuickWebEngineView.stop() --> void"
<< "QQuickWebEngineView.findText(QString,FindFlags,QJSValue) --> void"
<< "QQuickWebEngineView.findText(QString,FindFlags) --> void"
<< "QQuickWebEngineView.findText(QString) --> void"
- << "QQuickWebEngineDownloadItem.id --> uint"
- << "QQuickWebEngineDownloadItem.state --> DownloadState"
- << "QQuickWebEngineDownloadItem.path --> QString"
- << "QQuickWebEngineDownloadItem.totalBytes --> qlonglong"
- << "QQuickWebEngineDownloadItem.receivedBytes --> qlonglong"
+ << "QQuickWebEngineView.fullScreenCancelled() --> void"
+ << "QQuickWebEngineView.grantFeaturePermission(QUrl,Feature,bool) --> void"
+ << "QQuickWebEngineView.setActiveFocusOnPress(bool) --> void"
+ << "QQuickWebEngineView.triggerWebAction(WebAction) --> void"
+ << "QQuickWebEngineCertificateError.SslPinnedKeyNotInCertificateChain --> Error"
+ << "QQuickWebEngineCertificateError.CertificateCommonNameInvalid --> Error"
+ << "QQuickWebEngineCertificateError.CertificateDateInvalid --> Error"
+ << "QQuickWebEngineCertificateError.CertificateAuthorityInvalid --> Error"
+ << "QQuickWebEngineCertificateError.CertificateContainsErrors --> Error"
+ << "QQuickWebEngineCertificateError.CertificateNoRevocationMechanism --> Error"
+ << "QQuickWebEngineCertificateError.CertificateUnableToCheckRevocation --> Error"
+ << "QQuickWebEngineCertificateError.CertificateRevoked --> Error"
+ << "QQuickWebEngineCertificateError.CertificateInvalid --> Error"
+ << "QQuickWebEngineCertificateError.CertificateWeakSignatureAlgorithm --> Error"
+ << "QQuickWebEngineCertificateError.CertificateNonUniqueName --> Error"
+ << "QQuickWebEngineCertificateError.CertificateWeakKey --> Error"
+ << "QQuickWebEngineCertificateError.CertificateNameConstraintViolation --> Error"
+ << "QQuickWebEngineCertificateError.url --> QUrl"
+ << "QQuickWebEngineCertificateError.error --> Error"
+ << "QQuickWebEngineCertificateError.description --> QString"
+ << "QQuickWebEngineCertificateError.overridable --> bool"
+ << "QQuickWebEngineCertificateError.defer() --> void"
+ << "QQuickWebEngineCertificateError.ignoreCertificateError() --> void"
+ << "QQuickWebEngineCertificateError.rejectCertificate() --> void"
<< "QQuickWebEngineDownloadItem.DownloadRequested --> DownloadState"
<< "QQuickWebEngineDownloadItem.DownloadInProgress --> DownloadState"
<< "QQuickWebEngineDownloadItem.DownloadCompleted --> DownloadState"
<< "QQuickWebEngineDownloadItem.DownloadCancelled --> DownloadState"
<< "QQuickWebEngineDownloadItem.DownloadInterrupted --> DownloadState"
+ << "QQuickWebEngineDownloadItem.id --> uint"
+ << "QQuickWebEngineDownloadItem.state --> DownloadState"
+ << "QQuickWebEngineDownloadItem.totalBytes --> qlonglong"
+ << "QQuickWebEngineDownloadItem.receivedBytes --> qlonglong"
+ << "QQuickWebEngineDownloadItem.path --> QString"
<< "QQuickWebEngineDownloadItem.stateChanged() --> void"
- << "QQuickWebEngineDownloadItem.pathChanged() --> void"
<< "QQuickWebEngineDownloadItem.receivedBytesChanged() --> void"
<< "QQuickWebEngineDownloadItem.totalBytesChanged() --> void"
+ << "QQuickWebEngineDownloadItem.pathChanged() --> void"
<< "QQuickWebEngineDownloadItem.accept() --> void"
<< "QQuickWebEngineDownloadItem.cancel() --> void"
<< "QQuickWebEngineHistory.items --> QQuickWebEngineHistoryListModel*"
@@ -224,6 +275,7 @@ static QStringList expectedAPI = QStringList()
<< "QQuickWebEngineProfile.cachePath --> QString"
<< "QQuickWebEngineProfile.httpUserAgent --> QString"
<< "QQuickWebEngineProfile.httpCacheType --> HttpCacheType"
+ << "QQuickWebEngineProfile.httpAcceptLanguage --> QString"
<< "QQuickWebEngineProfile.persistentCookiesPolicy --> PersistentCookiesPolicy"
<< "QQuickWebEngineProfile.httpCacheMaximumSize --> int"
<< "QQuickWebEngineProfile.storageNameChanged() --> void"
@@ -234,39 +286,10 @@ static QStringList expectedAPI = QStringList()
<< "QQuickWebEngineProfile.httpCacheTypeChanged() --> void"
<< "QQuickWebEngineProfile.persistentCookiesPolicyChanged() --> void"
<< "QQuickWebEngineProfile.httpCacheMaximumSizeChanged() --> void"
+ << "QQuickWebEngineProfile.httpAcceptLanguageChanged() --> void"
<< "QQuickWebEngineProfile.downloadRequested(QQuickWebEngineDownloadItem*) --> void"
<< "QQuickWebEngineProfile.downloadFinished(QQuickWebEngineDownloadItem*) --> void"
- << "QQuickWebEngineSettings.autoLoadImages --> bool"
- << "QQuickWebEngineSettings.javascriptEnabled --> bool"
- << "QQuickWebEngineSettings.javascriptCanOpenWindows --> bool"
- << "QQuickWebEngineSettings.javascriptCanAccessClipboard --> bool"
- << "QQuickWebEngineSettings.linksIncludedInFocusChain --> bool"
- << "QQuickWebEngineSettings.localStorageEnabled --> bool"
- << "QQuickWebEngineSettings.localContentCanAccessRemoteUrls --> bool"
- << "QQuickWebEngineSettings.spatialNavigationEnabled --> bool"
- << "QQuickWebEngineSettings.localContentCanAccessFileUrls --> bool"
- << "QQuickWebEngineSettings.hyperlinkAuditingEnabled --> bool"
- << "QQuickWebEngineSettings.errorPageEnabled --> bool"
- << "QQuickWebEngineSettings.defaultTextEncoding --> QString"
- << "QQuickWebEngineSettings.autoLoadImagesChanged() --> void"
- << "QQuickWebEngineSettings.javascriptEnabledChanged() --> void"
- << "QQuickWebEngineSettings.javascriptCanOpenWindowsChanged() --> void"
- << "QQuickWebEngineSettings.javascriptCanAccessClipboardChanged() --> void"
- << "QQuickWebEngineSettings.linksIncludedInFocusChainChanged() --> void"
- << "QQuickWebEngineSettings.localStorageEnabledChanged() --> void"
- << "QQuickWebEngineSettings.localContentCanAccessRemoteUrlsChanged() --> void"
- << "QQuickWebEngineSettings.spatialNavigationEnabledChanged() --> void"
- << "QQuickWebEngineSettings.localContentCanAccessFileUrlsChanged() --> void"
- << "QQuickWebEngineSettings.hyperlinkAuditingEnabledChanged() --> void"
- << "QQuickWebEngineSettings.errorPageEnabledChanged() --> void"
- << "QQuickWebEngineSettings.defaultTextEncodingChanged() --> void"
- << "QQuickWebEngineCertificateError.ignoreCertificateError() --> void"
- << "QQuickWebEngineCertificateError.rejectCertificate() --> void"
- << "QQuickWebEngineCertificateError.defer() --> void"
- << "QQuickWebEngineCertificateError.url --> QUrl"
- << "QQuickWebEngineCertificateError.error --> Error"
- << "QQuickWebEngineCertificateError.description --> QString"
- << "QQuickWebEngineCertificateError.overridable --> bool"
+ << "QQuickWebEngineProfile.setCookieStoreClient(QWebEngineCookieStoreClient*) --> void"
<< "QQuickWebEngineScript.Deferred --> InjectionPoint"
<< "QQuickWebEngineScript.DocumentReady --> InjectionPoint"
<< "QQuickWebEngineScript.DocumentCreation --> InjectionPoint"
@@ -292,8 +315,38 @@ static QStringList expectedAPI = QStringList()
<< "QQuickWebEngineScript.setWorldId(ScriptWorldId) --> void"
<< "QQuickWebEngineScript.setRunOnSubframes(bool) --> void"
<< "QQuickWebEngineScript.toString() --> QString"
+ << "QQuickWebEngineSettings.autoLoadImages --> bool"
+ << "QQuickWebEngineSettings.javascriptEnabled --> bool"
+ << "QQuickWebEngineSettings.javascriptCanOpenWindows --> bool"
+ << "QQuickWebEngineSettings.javascriptCanAccessClipboard --> bool"
+ << "QQuickWebEngineSettings.linksIncludedInFocusChain --> bool"
+ << "QQuickWebEngineSettings.localStorageEnabled --> bool"
+ << "QQuickWebEngineSettings.localContentCanAccessRemoteUrls --> bool"
+ << "QQuickWebEngineSettings.spatialNavigationEnabled --> bool"
+ << "QQuickWebEngineSettings.localContentCanAccessFileUrls --> bool"
+ << "QQuickWebEngineSettings.hyperlinkAuditingEnabled --> bool"
+ << "QQuickWebEngineSettings.errorPageEnabled --> bool"
+ << "QQuickWebEngineSettings.pluginsEnabled --> bool"
+ << "QQuickWebEngineSettings.fullScreenSupportEnabled --> bool"
+ << "QQuickWebEngineSettings.defaultTextEncoding --> QString"
+ << "QQuickWebEngineSettings.autoLoadImagesChanged() --> void"
+ << "QQuickWebEngineSettings.javascriptEnabledChanged() --> void"
+ << "QQuickWebEngineSettings.javascriptCanOpenWindowsChanged() --> void"
+ << "QQuickWebEngineSettings.javascriptCanAccessClipboardChanged() --> void"
+ << "QQuickWebEngineSettings.linksIncludedInFocusChainChanged() --> void"
+ << "QQuickWebEngineSettings.localStorageEnabledChanged() --> void"
+ << "QQuickWebEngineSettings.localContentCanAccessRemoteUrlsChanged() --> void"
+ << "QQuickWebEngineSettings.spatialNavigationEnabledChanged() --> void"
+ << "QQuickWebEngineSettings.localContentCanAccessFileUrlsChanged() --> void"
+ << "QQuickWebEngineSettings.hyperlinkAuditingEnabledChanged() --> void"
+ << "QQuickWebEngineSettings.errorPageEnabledChanged() --> void"
+ << "QQuickWebEngineSettings.pluginsEnabledChanged() --> void"
+ << "QQuickWebEngineSettings.fullScreenSupportEnabledChanged() --> void"
+ << "QQuickWebEngineSettings.defaultTextEncodingChanged() --> void"
<< "QQuickWebEngineFullScreenRequest.toggleOn --> bool"
<< "QQuickWebEngineFullScreenRequest.accept() --> void"
+ << "QQuickWebEngineSingleton.settings --> QQuickWebEngineSettings*"
+ << "QQuickWebEngineSingleton.defaultProfile --> QQuickWebEngineProfile*"
;
static bool isCheckedEnum(const QByteArray &typeName)
diff --git a/tests/auto/quick/qmltests/data/TestWebEngineView.qml b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
index a97739404..e2c5c9009 100644
--- a/tests/auto/quick/qmltests/data/TestWebEngineView.qml
+++ b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
@@ -41,12 +41,13 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
import QtWebEngine.experimental 1.0
WebEngineView {
property var loadStatus: null
property var viewportReady: false
+ property bool windowCloseRequestedSignalEmitted: false
function waitForLoadSucceeded() {
var success = _waitFor(function() { return loadStatus == WebEngineView.LoadSucceededStatus })
@@ -69,6 +70,9 @@ WebEngineView {
loadStatus = null
return stop
}
+ function waitForWindowCloseRequested() {
+ return _waitFor(function() { return windowCloseRequestedSignalEmitted; });
+ }
function _waitFor(predicate) {
var timeout = 5000
var i = 0
@@ -87,5 +91,8 @@ WebEngineView {
viewportReady = false
}
+ onWindowCloseRequested: {
+ windowCloseRequestedSignalEmitted = true;
+ }
}
diff --git a/tests/auto/quick/qmltests/data/confirmclose.html b/tests/auto/quick/qmltests/data/confirmclose.html
new file mode 100644
index 000000000..ba11da7a4
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/confirmclose.html
@@ -0,0 +1,5 @@
+<html>
+<body onbeforeunload="return 'You are about to miss out on some awesome content.';">
+ Be greeted, precious viewer!
+</body>
+</html>
diff --git a/tests/auto/quick/qmltests/data/directoryupload.html b/tests/auto/quick/qmltests/data/directoryupload.html
new file mode 100644
index 000000000..6a6e4580c
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/directoryupload.html
@@ -0,0 +1,16 @@
+<html>
+<head>
+<meta name="viewport" initial-scale=1">
+<title> Directory Upload </title>
+<script src = "./titleupdate.js">
+</script>
+
+<body>
+<input type="file" id="upfile" webkitdirectory="" directory="" onchange="updateTitle()">
+<script>
+window.onload = function() {
+document.getElementById("upfile").focus()
+}
+</script>
+</body>
+</html>
diff --git a/tests/auto/quick/qmltests/data/forms.html b/tests/auto/quick/qmltests/data/forms.html
new file mode 100644
index 000000000..8dc3472f2
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/forms.html
@@ -0,0 +1,40 @@
+<html>
+<head>
+ <title>Forms</title>
+ <script type="text/javascript">
+ function updateFocus() {
+ var name = window.location.hash.substring(1);
+ var element = document.getElementsByName(name)[0];
+
+ element.focus();
+ }
+ </script>
+</head>
+<body onload="updateFocus();">
+ <form>
+ <input type="url" required/>
+ <input type="submit" name="url_empty"/>
+ </form>
+ <form>
+ <input type="url" value="invalid" required/>
+ <input type="submit" name="url_invalid"/>
+ </form>
+ <form>
+ <input type="url" value="invalid" title="url_title" required/>
+ <input type="submit" name="url_title"/>
+ </form>
+
+ <form>
+ <input type="email" required/>
+ <input type="submit" name="email_empty"/>
+ </form>
+ <form>
+ <input type="email" value="invalid" required/>
+ <input type="submit" name="email_invalid"/>
+ </form>
+ <form>
+ <input type="email" value="invalid" title="email_title" required/>
+ <input type="submit" name="email_title"/>
+ </form>
+</body>
+</html>
diff --git a/tests/auto/quick/qmltests/data/multifileupload.html b/tests/auto/quick/qmltests/data/multifileupload.html
new file mode 100644
index 000000000..cc87d8f41
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/multifileupload.html
@@ -0,0 +1,17 @@
+<html>
+<head>
+<meta name="viewport" initial-scale=1">
+<title> Mutli-file Upload </title>
+<script src = "./titleupdate.js">
+</script>
+
+<body>
+<input type="file" name="file" id="upfile" onchange="updateTitle()" multiple/>
+
+<script>
+window.onload = function() {
+document.getElementById("upfile").focus()
+}
+</script>
+</body>
+</html>
diff --git a/tests/auto/quick/qmltests/data/singlefileupload.html b/tests/auto/quick/qmltests/data/singlefileupload.html
new file mode 100644
index 000000000..8469aa128
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/singlefileupload.html
@@ -0,0 +1,17 @@
+<html>
+<head>
+<meta name="viewport" initial-scale=1">
+<title> Single File Upload </title>
+<script src = "./titleupdate.js">
+</script>
+
+<body>
+<input type="file" name="file" id="upfile" onchange="updateTitle()"/>
+
+<script>
+window.onload = function() {
+document.getElementById("upfile").focus()
+}
+</script>
+</body>
+</html>
diff --git a/tests/auto/quick/qmltests/data/titleupdate.js b/tests/auto/quick/qmltests/data/titleupdate.js
new file mode 100644
index 000000000..cfcc52c60
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/titleupdate.js
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+function updateTitle()
+{
+ var inp = document.getElementById("upfile");
+ var allfiles = new String("");
+ var name = new String("");
+ for (var i = 0; i < inp.files.length; ++i) {
+ name = inp.files.item(i).name;
+ if (allfiles.length == 0)
+ allfiles = name;
+ else
+ allfiles = allfiles + "," + name;
+ }
+ document.title = allfiles;
+}
diff --git a/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
new file mode 100644
index 000000000..eaca8822b
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+import QtTest 1.0
+
+Item {
+ id: root
+ width: 300
+ height: 400
+ TextInput {
+ id: textInput
+ anchors {
+ top: parent.top
+ left: parent.left
+ right: parent.right
+ }
+ focus: true
+ text: "foo"
+ }
+
+ TestWebEngineView {
+ id: webEngineView
+ activeFocusOnPress: false
+ anchors {
+ top: textInput.bottom
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ }
+
+ TestCase {
+ name: "ActiveFocusOnPress"
+ when:windowShown
+
+ function test_activeFocusOnPress() {
+ textInput.forceActiveFocus()
+ verify(textInput.activeFocus)
+ mouseClick(root, 150, 300, Qt.LeftButton)
+ verify(textInput.activeFocus)
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml b/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml
index dfb983c43..51c1d5580 100644
--- a/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml
+++ b/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
TestWebEngineView {
id: webEngineView
diff --git a/tests/auto/quick/qmltests/data/tst_favIconLoad.qml b/tests/auto/quick/qmltests/data/tst_favIconLoad.qml
index 73190f1bd..df5479eec 100644
--- a/tests/auto/quick/qmltests/data/tst_favIconLoad.qml
+++ b/tests/auto/quick/qmltests/data/tst_favIconLoad.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
TestWebEngineView {
id: webEngineView
diff --git a/tests/auto/quick/qmltests/data/tst_filePicker.qml b/tests/auto/quick/qmltests/data/tst_filePicker.qml
new file mode 100644
index 000000000..02b2dd024
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_filePicker.qml
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtTest 1.0
+import QtWebEngine 1.2
+import "../mock-delegates/TestParams" 1.0
+
+TestWebEngineView {
+ id: webEngineView
+ width: 400
+ height: 300
+
+ SignalSpy {
+ id: titleSpy
+ target: webEngineView
+ signalName: "titleChanged"
+ }
+
+ TestCase {
+ name: "WebEngineViewSingleFileUpload"
+ when: windowShown
+
+ function init() {
+ FilePickerParams.filePickerOpened = false
+ FilePickerParams.selectFiles = false
+ FilePickerParams.selectedFilesUrl = []
+ titleSpy.clear()
+ }
+
+ // FIXME: Almost every second url loading progress does get stuck at about 90 percent, so the loadFinished signal won't arrive.
+ // This cleanup function is a workaround for this problem.
+ function cleanup() {
+ webEngineView.url = Qt.resolvedUrl("about:blank")
+ webEngineView.waitForLoadSucceeded()
+ }
+
+ function test_acceptSingleFileSelection() {
+ webEngineView.url = Qt.resolvedUrl("singlefileupload.html")
+ verify(webEngineView.waitForLoadSucceeded())
+
+ FilePickerParams.selectFiles = true
+ FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("test1.html"))
+
+ keyPress(Qt.Key_Enter) // Focus is on the button. Open FileDialog.
+ wait(100) // The ui delegate is invoked asynchronously
+ verify(FilePickerParams.filePickerOpened)
+ titleSpy.wait()
+ compare(webEngineView.title, "test1.html")
+ }
+
+ function test_acceptMultipleFilesSelection() {
+ webEngineView.url = Qt.resolvedUrl("multifileupload.html")
+ verify(webEngineView.waitForLoadSucceeded())
+
+ FilePickerParams.selectFiles = true
+ FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("test1.html"))
+ FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("test2.html"))
+
+ keyPress(Qt.Key_Enter) // Focus is on the button. Open FileDialog.
+ wait(100)
+ verify(FilePickerParams.filePickerOpened)
+ titleSpy.wait()
+ compare(webEngineView.title, "test1.html,test2.html")
+ }
+
+ function test_acceptDirectory() {
+ webEngineView.url = Qt.resolvedUrl("directoryupload.html")
+ verify(webEngineView.waitForLoadSucceeded())
+
+ FilePickerParams.selectFiles = true
+ FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("../data"))
+
+ keyPress(Qt.Key_Enter) // Focus is on the button. Open FileDialog.
+ wait(100) // The ui delegate is invoked asynchronously
+ verify(FilePickerParams.filePickerOpened)
+ titleSpy.wait()
+ compare(webEngineView.title, "data")
+ }
+
+ function test_reject() {
+ webEngineView.url = Qt.resolvedUrl("singlefileupload.html")
+ verify(webEngineView.waitForLoadSucceeded())
+
+ titleSpy.clear()
+ keyPress(Qt.Key_Enter) // Focus is on the button. Open FileDialog.
+ wait(100)
+ compare(titleSpy.count, 0)
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml
index b51da0b2e..9c4aa48c1 100644
--- a/tests/auto/quick/qmltests/data/tst_findText.qml
+++ b/tests/auto/quick/qmltests/data/tst_findText.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
TestWebEngineView {
id: webEngineView
diff --git a/tests/auto/quick/qmltests/data/tst_formValidation.qml b/tests/auto/quick/qmltests/data/tst_formValidation.qml
new file mode 100644
index 000000000..4acb7ce63
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_formValidation.qml
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtTest 1.0
+import QtWebEngine 1.2
+import QtWebEngine.testsupport 1.0
+
+TestWebEngineView {
+ id: webEngineView
+ width: 400
+ height: 300
+
+ testSupport: WebEngineTestSupport {
+ id: testSupportAPI
+ }
+
+ SignalSpy {
+ id: showSpy
+ target: testSupportAPI
+ signalName: "validationMessageShown"
+ }
+
+ TestCase {
+ name: "WebEngineViewFormValidation"
+ when: windowShown
+
+ function init() {
+ webEngineView.url = Qt.resolvedUrl("about:blank")
+ verify(webEngineView.waitForLoadSucceeded())
+ showSpy.clear()
+ }
+
+ function test_urlForm() {
+ webEngineView.url = Qt.resolvedUrl("forms.html#url_empty")
+ verify(webEngineView.waitForLoadSucceeded())
+ keyPress(Qt.Key_Enter)
+ showSpy.wait()
+ compare(showSpy.signalArguments[0][0], "Please fill out this field.")
+
+ webEngineView.url = Qt.resolvedUrl("about:blank")
+ verify(webEngineView.waitForLoadSucceeded())
+
+ webEngineView.url = Qt.resolvedUrl("forms.html#url_invalid")
+ verify(webEngineView.waitForLoadSucceeded())
+ keyPress(Qt.Key_Enter)
+ showSpy.wait()
+ compare(showSpy.signalArguments[1][0], "Please enter a URL.")
+
+ webEngineView.url = Qt.resolvedUrl("about:blank")
+ verify(webEngineView.waitForLoadSucceeded())
+
+ webEngineView.url = Qt.resolvedUrl("forms.html#url_title")
+ verify(webEngineView.waitForLoadSucceeded())
+ keyPress(Qt.Key_Enter)
+ showSpy.wait()
+ compare(showSpy.signalArguments[2][1], "url_title")
+ }
+
+ function test_emailForm() {
+ webEngineView.url = Qt.resolvedUrl("forms.html#email_empty")
+ verify(webEngineView.waitForLoadSucceeded())
+ keyPress(Qt.Key_Enter)
+ showSpy.wait()
+ compare(showSpy.signalArguments[0][0], "Please fill out this field.")
+
+ webEngineView.url = Qt.resolvedUrl("about:blank")
+ verify(webEngineView.waitForLoadSucceeded())
+
+ webEngineView.url = Qt.resolvedUrl("forms.html#email_invalid")
+ verify(webEngineView.waitForLoadSucceeded())
+ keyPress(Qt.Key_Enter)
+ showSpy.wait()
+ compare(showSpy.signalArguments[1][0], "Please include an '@' in the email address. 'invalid' is missing an '@'.")
+
+ webEngineView.url = Qt.resolvedUrl("about:blank")
+ verify(webEngineView.waitForLoadSucceeded())
+
+ webEngineView.url = Qt.resolvedUrl("forms.html#email_title")
+ verify(webEngineView.waitForLoadSucceeded())
+ keyPress(Qt.Key_Enter)
+ showSpy.wait()
+ compare(showSpy.signalArguments[2][1], "email_title")
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml b/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml
index 58a49da5a..4294c5ba3 100644
--- a/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml
+++ b/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml
@@ -41,12 +41,27 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.0
+import QtWebEngine 1.2
+import QtWebEngine.testsupport 1.0
import "../mock-delegates/TestParams" 1.0
TestWebEngineView {
id: webEngineView
+ testSupport: WebEngineTestSupport {
+ property bool windowCloseRejectedSignalEmitted: false
+
+ function waitForWindowCloseRejected() {
+ return _waitFor(function () {
+ return testSupport.windowCloseRejectedSignalEmitted;
+ });
+ }
+
+ onWindowCloseRejected: {
+ windowCloseRejectedSignalEmitted = true;
+ }
+ }
+
TestCase {
id: test
name: "WebEngineViewJavaScriptDialogs"
@@ -80,6 +95,24 @@ TestWebEngineView {
}
+ function test_confirmClose() {
+ webEngineView.url = Qt.resolvedUrl("confirmclose.html");
+ verify(webEngineView.waitForLoadSucceeded());
+ webEngineView.windowCloseRequestedSignalEmitted = false;
+ JSDialogParams.shouldAcceptDialog = true;
+ webEngineView.triggerWebAction(WebEngineView.RequestClose);
+ verify(webEngineView.waitForWindowCloseRequested());
+ }
+
+ function test_rejectClose() {
+ webEngineView.url = Qt.resolvedUrl("confirmclose.html");
+ verify(webEngineView.waitForLoadSucceeded());
+ webEngineView.testSupport.windowCloseRejectedSignalEmitted = false;
+ JSDialogParams.shouldAcceptDialog = false;
+ webEngineView.triggerWebAction(WebEngineView.RequestClose);
+ verify(webEngineView.testSupport.waitForWindowCloseRejected());
+ }
+
function test_prompt() {
JSDialogParams.inputForPrompt = "tQ olleH"
webEngineView.url = Qt.resolvedUrl("prompt.html")
diff --git a/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml b/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml
index 230ee9635..c127d7391 100644
--- a/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml
+++ b/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
TestWebEngineView {
id: webEngineView
diff --git a/tests/auto/quick/qmltests/data/tst_linkHovered.qml b/tests/auto/quick/qmltests/data/tst_linkHovered.qml
index c9fbd5520..31d90615b 100644
--- a/tests/auto/quick/qmltests/data/tst_linkHovered.qml
+++ b/tests/auto/quick/qmltests/data/tst_linkHovered.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
TestWebEngineView {
id: webEngineView
diff --git a/tests/auto/quick/qmltests/data/tst_loadFail.qml b/tests/auto/quick/qmltests/data/tst_loadFail.qml
index 0885fc193..c2a4b6e13 100644
--- a/tests/auto/quick/qmltests/data/tst_loadFail.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadFail.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
import QtWebEngine.experimental 1.0
import QtWebEngine.testsupport 1.0
diff --git a/tests/auto/quick/qmltests/data/tst_loadHtml.qml b/tests/auto/quick/qmltests/data/tst_loadHtml.qml
index b8acd0dd7..ee1149b16 100644
--- a/tests/auto/quick/qmltests/data/tst_loadHtml.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadHtml.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
TestWebEngineView {
id: webEngineView
diff --git a/tests/auto/quick/qmltests/data/tst_loadProgress.qml b/tests/auto/quick/qmltests/data/tst_loadProgress.qml
index 9f8b6f6f7..096861c4d 100644
--- a/tests/auto/quick/qmltests/data/tst_loadProgress.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadProgress.qml
@@ -41,22 +41,39 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
TestWebEngineView {
id: webEngineView
width: 400
height: 300
+ property var loadProgressArray: []
+
+ onLoadProgressChanged: {
+ loadProgressArray.push(webEngineView.loadProgress)
+ }
+
TestCase {
name: "WebEngineViewLoadProgress"
function test_loadProgress() {
compare(webEngineView.loadProgress, 0)
+ loadProgressArray = []
+
webEngineView.url = Qt.resolvedUrl("test1.html")
- compare(webEngineView.loadProgress, 0)
verify(webEngineView.waitForLoadSucceeded())
- compare(webEngineView.loadProgress, 100)
+
+ // Test whether the chromium emits progress numbers in ascending order
+ var loadProgressMin = 0
+ for (var i in loadProgressArray) {
+ var loadProgress = loadProgressArray[i]
+ verify(loadProgressMin <= loadProgress)
+ loadProgressMin = loadProgress
+ }
+
+ // The progress must be 100% at the end
+ compare(loadProgressArray[loadProgressArray.length - 1], 100)
}
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_loadProgressSignal.qml b/tests/auto/quick/qmltests/data/tst_loadProgressSignal.qml
index 8e2e99b64..7b0bac61b 100644
--- a/tests/auto/quick/qmltests/data/tst_loadProgressSignal.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadProgressSignal.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
TestWebEngineView {
id: webEngineView
diff --git a/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml b/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml
index 2400a5ed6..fb692c472 100644
--- a/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml
@@ -41,7 +41,7 @@
import QtQuick 2.3
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
Item {
width: 300
diff --git a/tests/auto/quick/qmltests/data/tst_loadUrl.qml b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
index 922925b48..c8abf2bb0 100644
--- a/tests/auto/quick/qmltests/data/tst_loadUrl.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
import QtWebEngine.experimental 1.0
TestWebEngineView {
diff --git a/tests/auto/quick/qmltests/data/tst_navigationHistory.qml b/tests/auto/quick/qmltests/data/tst_navigationHistory.qml
index 3acde3abc..f7875bb78 100644
--- a/tests/auto/quick/qmltests/data/tst_navigationHistory.qml
+++ b/tests/auto/quick/qmltests/data/tst_navigationHistory.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
TestWebEngineView {
id: webEngineView
diff --git a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
index 72eb0aac9..7d49cda90 100644
--- a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
+++ b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
TestWebEngineView {
id: webEngineView
diff --git a/tests/auto/quick/qmltests/data/tst_properties.qml b/tests/auto/quick/qmltests/data/tst_properties.qml
index 738ef532d..9418252cb 100644
--- a/tests/auto/quick/qmltests/data/tst_properties.qml
+++ b/tests/auto/quick/qmltests/data/tst_properties.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
TestWebEngineView {
id: webEngineView
diff --git a/tests/auto/quick/qmltests/data/tst_runJavaScript.qml b/tests/auto/quick/qmltests/data/tst_runJavaScript.qml
index 6cf3a71fb..07e7130c6 100644
--- a/tests/auto/quick/qmltests/data/tst_runJavaScript.qml
+++ b/tests/auto/quick/qmltests/data/tst_runJavaScript.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
TestWebEngineView {
id: webEngineView
diff --git a/tests/auto/quick/qmltests/data/tst_titleChanged.qml b/tests/auto/quick/qmltests/data/tst_titleChanged.qml
index adc8564c0..8d9dae0a4 100644
--- a/tests/auto/quick/qmltests/data/tst_titleChanged.qml
+++ b/tests/auto/quick/qmltests/data/tst_titleChanged.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
TestWebEngineView {
id: webEngineView
diff --git a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
index 1c32c73a9..5fefd0fe5 100644
--- a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
+++ b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
Item {
id: parentItem
diff --git a/tests/auto/quick/qmltests/data/tst_userScripts.qml b/tests/auto/quick/qmltests/data/tst_userScripts.qml
index a9ed933d9..8a3b8207f 100644
--- a/tests/auto/quick/qmltests/data/tst_userScripts.qml
+++ b/tests/auto/quick/qmltests/data/tst_userScripts.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
Item {
WebEngineScript {
diff --git a/tests/auto/quick/qmltests/data/tst_webchannel.qml b/tests/auto/quick/qmltests/data/tst_webchannel.qml
index dce585b67..51e37d50e 100644
--- a/tests/auto/quick/qmltests/data/tst_webchannel.qml
+++ b/tests/auto/quick/qmltests/data/tst_webchannel.qml
@@ -40,7 +40,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.1
+import QtWebEngine 1.2
import QtWebEngine.experimental 1.0
import QtWebChannel 1.0
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/FilePicker.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/FilePicker.qml
new file mode 100644
index 000000000..5ee231c19
--- /dev/null
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/FilePicker.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import "../../TestParams" 1.0
+
+QtObject {
+ property bool selectMultiple: false;
+ property bool selectExisting: false;
+ property bool selectFolder: false;
+
+ signal filesSelected(var fileList);
+ signal rejected();
+
+ function open() {
+ FilePickerParams.filePickerOpened = true;
+ if (FilePickerParams.selectFiles)
+ filesSelected(FilePickerParams.selectedFilesUrl)
+ else
+ rejected()
+ }
+}
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/qmldir b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/qmldir
index 1ebabd335..cf8ac0512 100644
--- a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/qmldir
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/qmldir
@@ -1,4 +1,5 @@
module QtWebEngine.UIDelegates
AlertDialog 1.0 AlertDialog.qml
ConfirmDialog 1.0 ConfirmDialog.qml
+FilePicker 1.0 FilePicker.qml
PromptDialog 1.0 PromptDialog.qml
diff --git a/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml b/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml
new file mode 100644
index 000000000..f0f2d9368
--- /dev/null
+++ b/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+pragma Singleton
+import QtQuick 2.0
+
+QtObject {
+ property var selectedFilesUrl: [];
+ property bool selectFiles: false;
+ property bool filePickerOpened: false;
+}
diff --git a/tests/auto/quick/qmltests/mock-delegates/TestParams/qmldir b/tests/auto/quick/qmltests/mock-delegates/TestParams/qmldir
index f2ed87a75..a21dd8236 100644
--- a/tests/auto/quick/qmltests/mock-delegates/TestParams/qmldir
+++ b/tests/auto/quick/qmltests/mock-delegates/TestParams/qmldir
@@ -1,4 +1,5 @@
# QML module so that the autotests can set testing parameters
module TestParams
+singleton FilePickerParams 1.0 FilePickerParams.qml
singleton JSDialogParams 1.0 JSDialogParams.qml
diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro
index 9f6f55275..57649384d 100644
--- a/tests/auto/quick/qmltests/qmltests.pro
+++ b/tests/auto/quick/qmltests/qmltests.pro
@@ -12,23 +12,31 @@ OTHER_FILES += \
$$PWD/data/change-document-title.js \
$$PWD/data/download.zip \
$$PWD/data/confirm.html \
+ $$PWD/data/confirmclose.html \
+ $$PWD/data/directoryupload.html \
$$PWD/data/favicon.html \
$$PWD/data/favicon.png \
$$PWD/data/favicon2.html \
+ $$PWD/data/forms.html \
$$PWD/data/geolocation.html \
$$PWD/data/javascript.html \
$$PWD/data/link.html \
$$PWD/data/prompt.html \
+ $$PWD/data/multifileupload.html \
$$PWD/data/redirect.html \
+ $$PWD/data/singlefileupload.html \
$$PWD/data/small-favicon.png \
$$PWD/data/test1.html \
$$PWD/data/test2.html \
$$PWD/data/test3.html \
$$PWD/data/test4.html \
$$PWD/data/keyboardModifierMapping.html \
+ $$PWD/data/titleupdate.js \
$$PWD/data/tst_desktopBehaviorLoadHtml.qml \
$$PWD/data/tst_download.qml \
$$PWD/data/tst_favIconLoad.qml \
+ $$PWD/data/tst_filePicker.qml \
+ $$PWD/data/tst_formValidation.qml \
$$PWD/data/tst_geopermission.qml \
$$PWD/data/tst_javaScriptDialogs.qml \
$$PWD/data/tst_linkHovered.qml \
@@ -49,12 +57,13 @@ OTHER_FILES += \
$$PWD/data/tst_keyboardModifierMapping.qml \
$$PWD/mock-delegates/QtWebEngine/UIDelegates/AlertDialog.qml \
$$PWD/mock-delegates/QtWebEngine/UIDelegates/ConfirmDialog.qml \
+ $$PWD/mock-delegates/QtWebEngine/UIDelegates/FilePicker.qml \
$$PWD/mock-delegates/QtWebEngine/UIDelegates/PromptDialog.qml \
$$PWD/mock-delegates/QtWebEngine/UIDelegates/qmldir \
+ $$PWD/mock-delegates/TestParams/FilePickerParams.qml \
$$PWD/mock-delegates/TestParams/JSDialogParams.qml \
$$PWD/mock-delegates/TestParams/qmldir \
-
load(qt_build_paths)
DEFINES += QUICK_TEST_SOURCE_DIR=\\\"$$re_escape($$PWD$${QMAKE_DIR_SEP}data)\\\"
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 2cbcf0979..40dc3cb61 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -73,7 +73,7 @@ tst_QQuickWebEngineView::tst_QQuickWebEngineView()
static QQmlEngine *engine = new QQmlEngine(this);
m_component.reset(new QQmlComponent(engine, this));
m_component->setData(QByteArrayLiteral("import QtQuick 2.0\n"
- "import QtWebEngine 1.1\n"
+ "import QtWebEngine 1.2\n"
"WebEngineView {}")
, QUrl());
}
@@ -335,12 +335,10 @@ void tst_QQuickWebEngineView::titleUpdate()
webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/file_that_does_not_exist.html")));
QVERIFY(waitForLoadFailed(webEngineView()));
QCOMPARE(titleSpy.size(), 0);
-
}
void tst_QQuickWebEngineView::transparentWebEngineViews()
{
-
showWebEngineView();
// This should not crash.
@@ -348,13 +346,10 @@ void tst_QQuickWebEngineView::transparentWebEngineViews()
webEngineView1->setParentItem(m_window->contentItem());
QScopedPointer<QQuickWebEngineView> webEngineView2(newWebEngineView());
webEngineView2->setParentItem(m_window->contentItem());
-#if !defined(QQUICKWEBENGINEVIEW_EXPERIMENTAL_TRANSPARENTBACKGROUND)
- QWARN("QQUICKWEBENGINEVIEW_EXPERIMENTAL_TRANSPARENTBACKGROUND");
-#else
- QVERIFY(!webEngineView1->experimental()->transparentBackground());
- webEngineView2->experimental()->setTransparentBackground(true);
- QVERIFY(webEngineView2->experimental()->transparentBackground());
-#endif
+
+ QVERIFY(webEngineView1->backgroundColor() != Qt::transparent);
+ webEngineView2->setBackgroundColor(Qt::transparent);
+ QVERIFY(webEngineView2->backgroundColor() == Qt::transparent);
webEngineView1->setSize(QSizeF(300, 400));
webEngineView1->loadHtml("<html><body bgcolor=\"red\"></body></html>");
@@ -367,7 +362,24 @@ void tst_QQuickWebEngineView::transparentWebEngineViews()
webEngineView2->setVisible(true);
QTest::qWait(200);
- // FIXME: test actual rendering results; https://bugs.webkit.org/show_bug.cgi?id=80609.
+
+ // Result image: black text on red background.
+ QImage grabbedWindow = m_window->grabWindow();
+
+ QSet<int> redComponents;
+ for (int i = 0, width = grabbedWindow.width(); i < width; i++) {
+ for (int j = 0, height = grabbedWindow.height(); j < height; j++) {
+ QColor color(grabbedWindow.pixel(i, j));
+ redComponents.insert(color.red());
+ // There are no green or blue components between red and black.
+ QVERIFY(color.green() == 0);
+ QVERIFY(color.blue() == 0);
+ }
+ }
+
+ QVERIFY(redComponents.count() > 1);
+ QVERIFY(redComponents.contains(0)); // black
+ QVERIFY(redComponents.contains(255)); // red
}
void tst_QQuickWebEngineView::inputMethod()
diff --git a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
index 5d15537b3..e0e876fc8 100644
--- a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
+++ b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
@@ -184,7 +184,7 @@ void tst_QQuickWebEngineViewGraphics::reparentToOtherWindow()
void tst_QQuickWebEngineViewGraphics::setHtml(const QString &html)
{
QString htmlData = QUrl::toPercentEncoding(html);
- QString qmlData = QUrl::toPercentEncoding(QStringLiteral("import QtQuick 2.0; import QtWebEngine 1.1; WebEngineView { width: 150; height: 150; url: loadUrl }"));
+ QString qmlData = QUrl::toPercentEncoding(QStringLiteral("import QtQuick 2.0; import QtWebEngine 1.2; WebEngineView { width: 150; height: 150; url: loadUrl }"));
m_view->rootContext()->setContextProperty("loadUrl", QUrl(QStringLiteral("data:text/html,%1").arg(htmlData)));
m_view->setSource(QUrl(QStringLiteral("data:text/plain,%1").arg(qmlData)));
m_view->create();
diff --git a/tests/auto/widgets/qwebengineaccessibility/qwebengineaccessibility.pro b/tests/auto/widgets/qwebengineaccessibility/qwebengineaccessibility.pro
index ff6c49628..e99c7f493 100644
--- a/tests/auto/widgets/qwebengineaccessibility/qwebengineaccessibility.pro
+++ b/tests/auto/widgets/qwebengineaccessibility/qwebengineaccessibility.pro
@@ -1,2 +1 @@
include(../tests.pri)
-exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
diff --git a/tests/auto/widgets/qwebengineframe/qwebengineframe.pro b/tests/auto/widgets/qwebengineframe/qwebengineframe.pro
deleted file mode 100644
index ff6c49628..000000000
--- a/tests/auto/widgets/qwebengineframe/qwebengineframe.pro
+++ /dev/null
@@ -1,2 +0,0 @@
-include(../tests.pri)
-exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
diff --git a/tests/auto/widgets/qwebengineframe/tst_qwebengineframe.cpp b/tests/auto/widgets/qwebengineframe/tst_qwebengineframe.cpp
deleted file mode 100644
index 00e1b1123..000000000
--- a/tests/auto/widgets/qwebengineframe/tst_qwebengineframe.cpp
+++ /dev/null
@@ -1,1654 +0,0 @@
-/*
- Copyright (C) 2008,2009 Nokia Corporation and/or its subsidiary(-ies)
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-
-
-#include <QtTest/QtTest>
-
-#include <qwebenginepage.h>
-#include <qwebengineview.h>
-#include <qwebenginehistory.h>
-#include <QAbstractItemView>
-#include <QApplication>
-#include <QComboBox>
-#include <QPaintEngine>
-#include <QPicture>
-#include <QRegExp>
-#include <QNetworkRequest>
-#include <QNetworkReply>
-#include <QTextCodec>
-#include <QWebEngineSettings>
-#ifndef QT_NO_OPENSSL
-#include <qsslerror.h>
-#endif
-#include "../util.h"
-
-class tst_QWebEngineFrame : public QObject
-{
- Q_OBJECT
-
-public:
- bool eventFilter(QObject* watched, QEvent* event);
-
-public Q_SLOTS:
- void initTestCase();
- void init();
- void cleanup();
-
-private Q_SLOTS:
- void horizontalScrollAfterBack();
- void symmetricUrl();
- void progressSignal();
- void urlChange();
- void requestedUrl();
- void requestedUrlAfterSetAndLoadFailures();
- void javaScriptWindowObjectCleared_data();
- void javaScriptWindowObjectCleared();
- void javaScriptWindowObjectClearedOnEvaluate();
- void asyncAndDelete();
- void earlyToHtml();
- void setHtml();
- void setHtmlWithImageResource();
- void setHtmlWithStylesheetResource();
- void setHtmlWithBaseURL();
- void setHtmlWithJSAlert();
- void ipv6HostEncoding();
- void metaData();
-#if !defined(QT_NO_COMBOBOX)
- void popupFocus();
-#endif
- void inputFieldFocus();
- void hitTestContent();
- void baseUrl_data();
- void baseUrl();
- void hasSetFocus();
- void renderGeometry();
- void renderHints();
- void scrollPosition();
- void scrollToAnchor();
- void scrollbarsOff();
- void evaluateWillCauseRepaint();
- void setContent_data();
- void setContent();
- void setCacheLoadControlAttribute();
- void setUrlWithPendingLoads();
- void setUrlToEmpty();
- void setUrlToInvalid();
- void setUrlHistory();
- void setUrlUsingStateObject();
- void setUrlSameUrl();
- void setUrlThenLoads_data();
- void setUrlThenLoads();
- void loadFinishedAfterNotFoundError();
- void loadInSignalHandlers_data();
- void loadInSignalHandlers();
-
-private:
- QWebEngineView* m_view;
- QWebEnginePage* m_page;
- QWebEngineView* m_inputFieldsTestView;
- int m_inputFieldTestPaintCount;
-};
-
-bool tst_QWebEngineFrame::eventFilter(QObject* watched, QEvent* event)
-{
- // used on the inputFieldFocus test
- if (watched == m_inputFieldsTestView) {
- if (event->type() == QEvent::Paint)
- m_inputFieldTestPaintCount++;
- }
- return QObject::eventFilter(watched, event);
-}
-
-void tst_QWebEngineFrame::initTestCase()
-{
-}
-
-void tst_QWebEngineFrame::init()
-{
- m_view = new QWebEngineView();
- m_page = m_view->page();
- m_page->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
-}
-
-void tst_QWebEngineFrame::cleanup()
-{
- delete m_view;
-}
-
-void tst_QWebEngineFrame::symmetricUrl()
-{
- QWebEngineView view;
- QSignalSpy loadFinishedSpy(view.page(), SIGNAL(loadFinished(bool)));
-
- QVERIFY(view.url().isEmpty());
-
- QCOMPARE(view.history()->count(), 0);
-
- QUrl dataUrl("data:text/html,<h1>Test");
-
- view.setUrl(dataUrl);
- QCOMPARE(view.url(), dataUrl);
- QCOMPARE(view.history()->count(), 0);
-
- // loading is _not_ immediate, so the text isn't set just yet.
- QVERIFY(toPlainTextSync(view.page()).isEmpty());
-
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
-
- QCOMPARE(view.history()->count(), 1);
- QCOMPARE(toPlainTextSync(view.page()), QString("Test"));
-
- QUrl dataUrl2("data:text/html,<h1>Test2");
- QUrl dataUrl3("data:text/html,<h1>Test3");
-
- view.setUrl(dataUrl2);
- view.setUrl(dataUrl3);
-
- QCOMPARE(view.url(), dataUrl3);
-
- QTRY_VERIFY(loadFinishedSpy.count() >= 2);
- QTRY_COMPARE(loadFinishedSpy.count(), 3);
-
- QCOMPARE(view.history()->count(), 2);
-
- QCOMPARE(toPlainTextSync(view.page()), QString("Test3"));
-}
-
-void tst_QWebEngineFrame::progressSignal()
-{
- QSignalSpy progressSpy(m_view, SIGNAL(loadProgress(int)));
-
- QUrl dataUrl("data:text/html,<h1>Test");
- m_view->setUrl(dataUrl);
-
- ::waitForSignal(m_view, SIGNAL(loadFinished(bool)));
-
- QVERIFY(progressSpy.size() >= 2);
- int previousValue = -1;
- for (QSignalSpy::ConstIterator it = progressSpy.begin(); it < progressSpy.end(); ++it) {
- int current = (*it).first().toInt();
- QVERIFY(current > previousValue);
- previousValue = current;
- }
-
- // But we always end at 100%
- QCOMPARE(progressSpy.last().first().toInt(), 100);
-}
-
-void tst_QWebEngineFrame::urlChange()
-{
- QSignalSpy urlSpy(m_page, SIGNAL(urlChanged(QUrl)));
-
- QUrl dataUrl("data:text/html,<h1>Test");
- m_view->setUrl(dataUrl);
-
- ::waitForSignal(m_page, SIGNAL(urlChanged(QUrl)));
-
- QCOMPARE(urlSpy.size(), 1);
-
- QUrl dataUrl2("data:text/html,<html><head><title>title</title></head><body><h1>Test</body></html>");
- m_view->setUrl(dataUrl2);
-
- ::waitForSignal(m_page, SIGNAL(urlChanged(QUrl)));
-
- QCOMPARE(urlSpy.size(), 2);
-}
-
-class FakeReply : public QNetworkReply {
- Q_OBJECT
-
-public:
- static const QUrl urlFor404ErrorWithoutContents;
-
- FakeReply(const QNetworkRequest& request, QObject* parent = 0)
- : QNetworkReply(parent)
- {
- setOperation(QNetworkAccessManager::GetOperation);
- setRequest(request);
- setUrl(request.url());
- if (request.url() == QUrl("qrc:/test1.html")) {
- setHeader(QNetworkRequest::LocationHeader, QString("qrc:/test2.html"));
- setAttribute(QNetworkRequest::RedirectionTargetAttribute, QUrl("qrc:/test2.html"));
- QTimer::singleShot(0, this, SLOT(continueRedirect()));
- }
-#ifndef QT_NO_OPENSSL
- else if (request.url() == QUrl("qrc:/fake-ssl-error.html")) {
- setError(QNetworkReply::SslHandshakeFailedError, tr("Fake error!"));
- QTimer::singleShot(0, this, SLOT(continueError()));
- }
-#endif
- else if (request.url().host() == QLatin1String("abcdef.abcdef")) {
- setError(QNetworkReply::HostNotFoundError, tr("Invalid URL"));
- QTimer::singleShot(0, this, SLOT(continueError()));
- } else if (request.url() == FakeReply::urlFor404ErrorWithoutContents) {
- setError(QNetworkReply::ContentNotFoundError, "Not found");
- setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 404);
- QTimer::singleShot(0, this, SLOT(continueError()));
- }
-
- open(QIODevice::ReadOnly);
- }
- ~FakeReply()
- {
- close();
- }
- virtual void abort() {}
- virtual void close() {}
-
-protected:
- qint64 readData(char*, qint64)
- {
- return 0;
- }
-
-private Q_SLOTS:
- void continueRedirect()
- {
- emit metaDataChanged();
- emit finished();
- }
-
- void continueError()
- {
- emit error(this->error());
- emit finished();
- }
-};
-
-const QUrl FakeReply::urlFor404ErrorWithoutContents = QUrl("http://this.will/return-http-404-error-without-contents.html");
-
-class FakeNetworkManager : public QNetworkAccessManager {
- Q_OBJECT
-
-public:
- FakeNetworkManager(QObject* parent) : QNetworkAccessManager(parent) { }
-
-protected:
- virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest& request, QIODevice* outgoingData)
- {
- QString url = request.url().toString();
- if (op == QNetworkAccessManager::GetOperation) {
-#ifndef QT_NO_OPENSSL
- if (url == "qrc:/fake-ssl-error.html") {
- FakeReply* reply = new FakeReply(request, this);
- QList<QSslError> errors;
- emit sslErrors(reply, errors << QSslError(QSslError::UnspecifiedError));
- return reply;
- }
-#endif
- if (url == "qrc:/test1.html" || url == "http://abcdef.abcdef/" || request.url() == FakeReply::urlFor404ErrorWithoutContents)
- return new FakeReply(request, this);
- }
-
- return QNetworkAccessManager::createRequest(op, request, outgoingData);
- }
-};
-
-void tst_QWebEngineFrame::requestedUrl()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- QWebEnginePage page;
-
- // in few seconds, the image should be completely loaded
- QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
- FakeNetworkManager* networkManager = new FakeNetworkManager(&page);
- page.setNetworkAccessManager(networkManager);
-
- page.setUrl(QUrl("qrc:/test1.html"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
- QCOMPARE(spy.count(), 1);
- QCOMPARE(page.requestedUrl(), QUrl("qrc:/test1.html"));
- QCOMPARE(page.url(), QUrl("qrc:/test2.html"));
-
- page.setUrl(QUrl("qrc:/non-existent.html"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
- QCOMPARE(spy.count(), 2);
- QCOMPARE(page.requestedUrl(), QUrl("qrc:/non-existent.html"));
- QCOMPARE(page.url(), QUrl("qrc:/non-existent.html"));
-
- page.setUrl(QUrl("http://abcdef.abcdef"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
- QCOMPARE(spy.count(), 3);
- QCOMPARE(page.requestedUrl(), QUrl("http://abcdef.abcdef/"));
- QCOMPARE(page.url(), QUrl("http://abcdef.abcdef/"));
-
-#ifndef QT_NO_OPENSSL
- qRegisterMetaType<QList<QSslError> >("QList<QSslError>");
- qRegisterMetaType<QNetworkReply* >("QNetworkReply*");
-
- QSignalSpy spy2(page.networkAccessManager(), SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)));
- page.setUrl(QUrl("qrc:/fake-ssl-error.html"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
- QCOMPARE(spy2.count(), 1);
- QCOMPARE(page.requestedUrl(), QUrl("qrc:/fake-ssl-error.html"));
- QCOMPARE(page.url(), QUrl("qrc:/fake-ssl-error.html"));
-#endif
-#endif
-}
-
-void tst_QWebEngineFrame::requestedUrlAfterSetAndLoadFailures()
-{
- QWebEnginePage page;
- page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
- QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
-
- const QUrl first("http://abcdef.abcdef/");
- page.setUrl(first);
- ::waitForSignal(&page, SIGNAL(loadFinished(bool)));
- QCOMPARE(spy.count(), 1);
- QCOMPARE(page.url(), first);
- QCOMPARE(page.requestedUrl(), first);
- QVERIFY(!spy.at(0).first().toBool());
-
- const QUrl second("http://abcdef.abcdef/another_page.html");
- QVERIFY(first != second);
-
- page.load(second);
- ::waitForSignal(&page, SIGNAL(loadFinished(bool)));
- QCOMPARE(spy.count(), 2);
- QCOMPARE(page.url(), first);
- QCOMPARE(page.requestedUrl(), second);
- QVERIFY(!spy.at(1).first().toBool());
-}
-
-void tst_QWebEngineFrame::javaScriptWindowObjectCleared_data()
-{
- QTest::addColumn<QString>("html");
- QTest::addColumn<int>("signalCount");
- QTest::newRow("with <script>") << "<html><body><script>i=0</script><p>hello world</p></body></html>" << 1;
- // NOTE: Empty scripts no longer cause this signal to be emitted.
- QTest::newRow("with empty <script>") << "<html><body><script></script><p>hello world</p></body></html>" << 0;
- QTest::newRow("without <script>") << "<html><body><p>hello world</p></body></html>" << 0;
-}
-
-void tst_QWebEngineFrame::javaScriptWindowObjectCleared()
-{
-#if !defined(QWEBENGINEPAGE_JAVASCRIPTWINDOWOBJECTCLEARED)
- QSKIP("QWEBENGINEPAGE_JAVASCRIPTWINDOWOBJECTCLEARED");
-#else
- QWebEnginePage page;
- QSignalSpy spy(&page, SIGNAL(javaScriptWindowObjectCleared()));
- QFETCH(QString, html);
- page.setHtml(html);
-
- QFETCH(int, signalCount);
- QCOMPARE(spy.count(), signalCount);
-#endif
-}
-
-void tst_QWebEngineFrame::javaScriptWindowObjectClearedOnEvaluate()
-{
-#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
- QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
-#else
- QWebEnginePage page;
- QSignalSpy spy(&page, SIGNAL(javaScriptWindowObjectCleared()));
- page.setHtml("<html></html>");
- QCOMPARE(spy.count(), 0);
- page.evaluateJavaScript("var a = 'a';");
- QCOMPARE(spy.count(), 1);
- // no new clear for a new script:
- page.evaluateJavaScript("var a = 1;");
- QCOMPARE(spy.count(), 1);
-#endif
-}
-
-void tst_QWebEngineFrame::asyncAndDelete()
-{
- QWebEnginePage *page = new QWebEnginePage;
- CallbackSpy<QString> plainTextSpy;
- CallbackSpy<QString> htmlSpy;
- page->toPlainText(plainTextSpy.ref());
- page->toHtml(htmlSpy.ref());
-
- delete page;
- // Pending callbacks should be called with an empty value in the page's destructor.
- QCOMPARE(plainTextSpy.waitForResult(), QString());
- QVERIFY(plainTextSpy.wasCalled());
- QCOMPARE(htmlSpy.waitForResult(), QString());
- QVERIFY(htmlSpy.wasCalled());
-}
-
-void tst_QWebEngineFrame::earlyToHtml()
-{
- QString html("<html><head></head><body></body></html>");
- QCOMPARE(toHtmlSync(m_view->page()), html);
-}
-
-void tst_QWebEngineFrame::setHtml()
-{
- QString html("<html><head></head><body><p>hello world</p></body></html>");
- QSignalSpy spy(m_view->page(), SIGNAL(loadFinished(bool)));
- m_view->page()->setHtml(html);
- QVERIFY(spy.wait());
- QCOMPARE(toHtmlSync(m_view->page()), html);
-}
-
-void tst_QWebEngineFrame::setHtmlWithImageResource()
-{
- // By default, only security origins of local files can load local resources.
- // So we should specify baseUrl to be a local file in order to get a proper origin and load the local image.
-
- QLatin1String html("<html><body><p>hello world</p><img src='qrc:/image.png'/></body></html>");
- QWebEnginePage page;
-
- page.setHtml(html, QUrl(QLatin1String("file:///path/to/file")));
- waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
-
- QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
- QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128);
- QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 128);
-
- // Now we test the opposite: without a baseUrl as a local file, we cannot request local resources.
-
- page.setHtml(html);
- waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
- QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
- QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118659", Continue);
- QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 0);
- QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118659", Continue);
- QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 0);
-}
-
-void tst_QWebEngineFrame::setHtmlWithStylesheetResource()
-{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
- // By default, only security origins of local files can load local resources.
- // So we should specify baseUrl to be a local file in order to be able to download the local stylesheet.
-
- const char* htmlData =
- "<html>"
- "<head>"
- "<link rel='stylesheet' href='qrc:/style.css' type='text/css' />"
- "</head>"
- "<body>"
- "<p id='idP'>some text</p>"
- "</body>"
- "</html>";
- QLatin1String html(htmlData);
- QWebEnginePage page;
- QWebEngineElement webElement;
-
- page.setHtml(html, QUrl(QLatin1String("qrc:///file")));
- waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
- webElement = page.documentElement().findFirst("p");
- QCOMPARE(webElement.styleProperty("color", QWebEngineElement::CascadedStyle), QLatin1String("red"));
-
- // Now we test the opposite: without a baseUrl as a local file, we cannot request local resources.
-
- page.setHtml(html, QUrl(QLatin1String("http://www.example.com/")));
- waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
- webElement = page.documentElement().findFirst("p");
- QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118659", Continue);
- QCOMPARE(webElement.styleProperty("color", QWebEngineElement::CascadedStyle), QString());
-#endif
-}
-
-void tst_QWebEngineFrame::setHtmlWithBaseURL()
-{
- // This tests if baseUrl is indeed affecting the relative paths from resources.
- // As we are using a local file as baseUrl, its security origin should be able to load local resources.
-
- if (!QDir(TESTS_SOURCE_DIR).exists())
- W_QSKIP(QString("This test requires access to resources found in '%1'").arg(TESTS_SOURCE_DIR).toLatin1().constData(), SkipAll);
-
- QDir::setCurrent(TESTS_SOURCE_DIR);
-
- QString html("<html><body><p>hello world</p><img src='resources/image2.png'/></body></html>");
-
- QWebEnginePage page;
-
- // in few seconds, the image should be completey loaded
- QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
-
- page.setHtml(html, QUrl::fromLocalFile(TESTS_SOURCE_DIR));
- waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
- QCOMPARE(spy.count(), 1);
-
- QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
- QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128);
- QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 128);
-
- // no history item has to be added.
- QCOMPARE(m_view->page()->history()->count(), 0);
-}
-
-class MyPage : public QWebEnginePage
-{
-public:
- MyPage() : QWebEnginePage(), alerts(0) {}
- int alerts;
-
-protected:
- virtual void javaScriptAlert(const QUrl &securityOrigin, const QString &msg)
- {
- alerts++;
- QCOMPARE(securityOrigin, QUrl(QStringLiteral("http://test.origin.com/")));
- QCOMPARE(msg, QString("foo"));
- }
-};
-
-void tst_QWebEngineFrame::setHtmlWithJSAlert()
-{
- QString html("<html><head></head><body><script>alert('foo');</script><p>hello world</p></body></html>");
- MyPage page;
- page.setHtml(html, QUrl(QStringLiteral("http://test.origin.com/path#fragment")));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
- QCOMPARE(page.alerts, 1);
- QCOMPARE(toHtmlSync(&page), html);
-}
-
-class TestNetworkManager : public QNetworkAccessManager
-{
-public:
- TestNetworkManager(QObject* parent) : QNetworkAccessManager(parent) {}
-
- QList<QUrl> requestedUrls;
-
-protected:
- virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest &request, QIODevice* outgoingData) {
- requestedUrls.append(request.url());
- QNetworkRequest redirectedRequest = request;
- redirectedRequest.setUrl(QUrl("data:text/html,<p>hello"));
- return QNetworkAccessManager::createRequest(op, redirectedRequest, outgoingData);
- }
-};
-
-void tst_QWebEngineFrame::ipv6HostEncoding()
-{
-#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
- QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
-#else
- TestNetworkManager* networkManager = new TestNetworkManager(m_page);
- m_page->setNetworkAccessManager(networkManager);
- networkManager->requestedUrls.clear();
-
- QUrl baseUrl = QUrl::fromEncoded("http://[::1]/index.html");
- m_view->setHtml("<p>Hi", baseUrl);
- m_view->page()->evaluateJavaScript("var r = new XMLHttpRequest();"
- "r.open('GET', 'http://[::1]/test.xml', false);"
- "r.send(null);"
- );
- QCOMPARE(networkManager->requestedUrls.count(), 1);
- QCOMPARE(networkManager->requestedUrls.at(0), QUrl::fromEncoded("http://[::1]/test.xml"));
-#endif
-}
-
-void tst_QWebEngineFrame::metaData()
-{
-#if !defined(QWEBENGINEPAGE_METADATA)
- QSKIP("QWEBENGINEPAGE_METADATA");
-#else
- m_view->setHtml("<html>"
- " <head>"
- " <meta name=\"description\" content=\"Test description\">"
- " <meta name=\"keywords\" content=\"HTML, JavaScript, Css\">"
- " </head>"
- "</html>");
-
- QMultiMap<QString, QString> metaData = m_view->page()->metaData();
-
- QCOMPARE(metaData.count(), 2);
-
- QCOMPARE(metaData.value("description"), QString("Test description"));
- QCOMPARE(metaData.value("keywords"), QString("HTML, JavaScript, Css"));
- QCOMPARE(metaData.value("nonexistent"), QString());
-
- m_view->setHtml("<html>"
- " <head>"
- " <meta name=\"samekey\" content=\"FirstValue\">"
- " <meta name=\"samekey\" content=\"SecondValue\">"
- " </head>"
- "</html>");
-
- metaData = m_view->page()->metaData();
-
- QCOMPARE(metaData.count(), 2);
-
- QStringList values = metaData.values("samekey");
- QCOMPARE(values.count(), 2);
-
- QVERIFY(values.contains("FirstValue"));
- QVERIFY(values.contains("SecondValue"));
-
- QCOMPARE(metaData.value("nonexistent"), QString());
-#endif
-}
-
-#if !defined(QT_NO_COMBOBOX)
-void tst_QWebEngineFrame::popupFocus()
-{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
- QWebEngineView view;
- view.setHtml("<html>"
- " <body>"
- " <select name=\"select\">"
- " <option>1</option>"
- " <option>2</option>"
- " </select>"
- " <input type=\"text\"> </input>"
- " <textarea name=\"text_area\" rows=\"3\" cols=\"40\">"
- "This test checks whether showing and hiding a popup"
- "takes the focus away from the webpage."
- " </textarea>"
- " </body>"
- "</html>");
- view.resize(400, 100);
- // Call setFocus before show to work around http://bugreports.qt.nokia.com/browse/QTBUG-14762
- view.setFocus();
- view.show();
- QTest::qWaitForWindowExposed(&view);
- view.activateWindow();
- QTRY_VERIFY(view.hasFocus());
-
- // open the popup by clicking. check if focus is on the popup
- const QWebEngineElement webCombo = view.page()->documentElement().findFirst(QLatin1String("select[name=select]"));
- QTest::mouseClick(&view, Qt::LeftButton, 0, webCombo.geometry().center());
-
- QComboBox* combo = view.findChild<QComboBox*>();
- QVERIFY(combo != 0);
- QTRY_VERIFY(!view.hasFocus() && combo->view()->hasFocus()); // Focus should be on the popup
-
- // hide the popup and check if focus is on the page
- combo->hidePopup();
- QTRY_VERIFY(view.hasFocus()); // Focus should be back on the WebView
-#endif
-}
-#endif
-
-void tst_QWebEngineFrame::inputFieldFocus()
-{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
- QWebEngineView view;
- view.setHtml("<html><body><input type=\"text\"></input></body></html>");
- view.resize(400, 100);
- view.show();
- QTest::qWaitForWindowExposed(&view);
- view.activateWindow();
- view.setFocus();
- QTRY_VERIFY(view.hasFocus());
-
- // double the flashing time, should at least blink once already
- int delay = qApp->cursorFlashTime() * 2;
-
- // focus the lineedit and check if it blinks
- bool autoSipEnabled = qApp->autoSipEnabled();
- qApp->setAutoSipEnabled(false);
- const QWebEngineElement inputElement = view.page()->documentElement().findFirst(QLatin1String("input[type=text]"));
- QTest::mouseClick(&view, Qt::LeftButton, 0, inputElement.geometry().center());
- m_inputFieldsTestView = &view;
- view.installEventFilter( this );
- QTest::qWait(delay);
- QVERIFY2(m_inputFieldTestPaintCount >= 3,
- "The input field should have a blinking caret");
- qApp->setAutoSipEnabled(autoSipEnabled);
-#endif
-}
-
-void tst_QWebEngineFrame::hitTestContent()
-{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
- QString html("<html><body><p>A paragraph</p><br/><br/><br/><a href=\"about:blank\" target=\"_foo\" id=\"link\">link text</a></body></html>");
-
- QWebEnginePage page;
- page.setHtml(html);
- page.setViewportSize(QSize(200, 0)); //no height so link is not visible
- const QWebEngineElement linkElement = page.documentElement().findFirst(QLatin1String("a#link"));
- QWebEngineHitTestResult result = page.hitTestContent(linkElement.geometry().center());
- QCOMPARE(result.linkText(), QString("link text"));
- QWebEngineElement link = result.linkElement();
- QCOMPARE(link.attribute("target"), QString("_foo"));
-#endif
-}
-
-void tst_QWebEngineFrame::baseUrl_data()
-{
- QTest::addColumn<QString>("html");
- QTest::addColumn<QUrl>("loadUrl");
- QTest::addColumn<QUrl>("url");
- QTest::addColumn<QUrl>("baseUrl");
-
- QTest::newRow("null") << QString() << QUrl()
- << QUrl("about:blank") << QUrl("about:blank");
-
- QTest::newRow("foo") << QString() << QUrl("http://foobar.baz/")
- << QUrl("http://foobar.baz/") << QUrl("http://foobar.baz/");
-
- QString html = "<html>"
- "<head>"
- "<base href=\"http://foobaz.bar/\" />"
- "</head>"
- "</html>";
- QTest::newRow("customBaseUrl") << html << QUrl("http://foobar.baz/")
- << QUrl("http://foobar.baz/") << QUrl("http://foobaz.bar/");
-}
-
-void tst_QWebEngineFrame::baseUrl()
-{
- QFETCH(QString, html);
- QFETCH(QUrl, loadUrl);
- QFETCH(QUrl, url);
- QFETCH(QUrl, baseUrl);
-
- QSignalSpy loadSpy(m_page, SIGNAL(loadFinished(bool)));
- m_page->setHtml(html, loadUrl);
- QTRY_COMPARE(loadSpy.count(), 1);
- QCOMPARE(m_page->url(), url);
- QEXPECT_FAIL("null", "Slight change: We now translate QUrl() to about:blank for the virtual url, but not for the baseUrl", Continue);
- QCOMPARE(baseUrlSync(m_page), baseUrl);
-}
-
-void tst_QWebEngineFrame::hasSetFocus()
-{
-#if !defined(QWEBENGINEFRAME)
- QSKIP("QWEBENGINEFRAME");
-#else
- QString html("<html><body><p>top</p>" \
- "<iframe width='80%' height='30%'/>" \
- "</body></html>");
-
- QSignalSpy loadSpy(m_page, SIGNAL(loadFinished(bool)));
- m_page->setHtml(html);
-
- waitForSignal(m_page, SIGNAL(loadFinished(bool)), 200);
- QCOMPARE(loadSpy.size(), 1);
-
- QList<QWebEngineFrame*> children = m_page->childFrames();
- QWebEngineFrame* frame = children.at(0);
- QString innerHtml("<html><body><p>another iframe</p>" \
- "<iframe width='80%' height='30%'/>" \
- "</body></html>");
- frame->setHtml(innerHtml);
-
- waitForSignal(frame, SIGNAL(loadFinished(bool)), 200);
- QCOMPARE(loadSpy.size(), 2);
-
- m_page->setFocus();
- QTRY_VERIFY(m_page->hasFocus());
-
- for (int i = 0; i < children.size(); ++i) {
- children.at(i)->setFocus();
- QTRY_VERIFY(children.at(i)->hasFocus());
- QVERIFY(!m_page->hasFocus());
- }
-
- m_page->setFocus();
- QTRY_VERIFY(m_page->hasFocus());
-#endif
-}
-
-void tst_QWebEngineFrame::renderGeometry()
-{
-#if !defined(QWEBENGINEFRAME)
- QSKIP("QWEBENGINEFRAME");
-#else
- QString html("<html>" \
- "<head><style>" \
- "body, iframe { margin: 0px; border: none; }" \
- "</style></head>" \
- "<body><iframe width='100px' height='100px'/></body>" \
- "</html>");
-
- QWebEnginePage page;
- page.setHtml(html);
-
- QList<QWebEngineFrame*> frames = page.childFrames();
- QWebEngineFrame *frame = frames.at(0);
- QString innerHtml("<body style='margin: 0px;'><img src='qrc:/image.png'/></body>");
-
- // By default, only security origins of local files can load local resources.
- // So we should specify baseUrl to be a local file in order to get a proper origin.
- frame->setHtml(innerHtml, QUrl("file:///path/to/file"));
- waitForSignal(frame, SIGNAL(loadFinished(bool)), 200);
-
- QPicture picture;
-
- QSize size = page.contentsSize();
- page.setViewportSize(size);
-
- // render contents layer only (the iframe is smaller than the image, so it will have scrollbars)
- QPainter painter1(&picture);
- frame->render(&painter1, QWebEngineFrame::ContentsLayer);
- painter1.end();
-
- QCOMPARE(size.width(), picture.boundingRect().width() + frame->scrollBarGeometry(Qt::Vertical).width());
- QCOMPARE(size.height(), picture.boundingRect().height() + frame->scrollBarGeometry(Qt::Horizontal).height());
-
- // render everything, should be the size of the iframe
- QPainter painter2(&picture);
- frame->render(&painter2, QWebEngineFrame::AllLayers);
- painter2.end();
-
- QCOMPARE(size.width(), picture.boundingRect().width()); // width: 100px
- QCOMPARE(size.height(), picture.boundingRect().height()); // height: 100px
-#endif
-}
-
-
-class DummyPaintEngine: public QPaintEngine {
-public:
-
- DummyPaintEngine()
- : QPaintEngine(QPaintEngine::AllFeatures)
- , renderHints(0)
- {
- }
-
- bool begin(QPaintDevice*)
- {
- setActive(true);
- return true;
- }
-
- bool end()
- {
- setActive(false);
- return false;
- }
-
- void updateState(const QPaintEngineState& state)
- {
- renderHints = state.renderHints();
- }
-
- void drawPath(const QPainterPath&) { }
- void drawPixmap(const QRectF&, const QPixmap&, const QRectF&) { }
-
- QPaintEngine::Type type() const
- {
- return static_cast<QPaintEngine::Type>(QPaintEngine::User + 2);
- }
-
- QPainter::RenderHints renderHints;
-};
-
-class DummyPaintDevice: public QPaintDevice {
-public:
- DummyPaintDevice()
- : QPaintDevice()
- , m_engine(new DummyPaintEngine)
- {
- }
-
- ~DummyPaintDevice()
- {
- delete m_engine;
- }
-
- QPaintEngine* paintEngine() const
- {
- return m_engine;
- }
-
- QPainter::RenderHints renderHints() const
- {
- return m_engine->renderHints;
- }
-
-protected:
- int metric(PaintDeviceMetric metric) const;
-
-private:
- DummyPaintEngine* m_engine;
- friend class DummyPaintEngine;
-};
-
-
-int DummyPaintDevice::metric(PaintDeviceMetric metric) const
-{
- switch (metric) {
- case PdmWidth:
- return 400;
- break;
-
- case PdmHeight:
- return 200;
- break;
-
- case PdmNumColors:
- return INT_MAX;
- break;
-
- case PdmDepth:
- return 32;
- break;
-
- default:
- break;
- }
- return 0;
-}
-
-void tst_QWebEngineFrame::renderHints()
-{
-#if !defined(QWEBENGINEPAGE_RENDER)
- QSKIP("QWEBENGINEPAGE_RENDER");
-#else
- QString html("<html><body><p>Hello, world!</p></body></html>");
-
- QWebEnginePage page;
- page.setHtml(html);
- page.setViewportSize(page.contentsSize());
-
- // We will call frame->render and trap the paint engine state changes
- // to ensure that GraphicsContext does not clobber the render hints.
- DummyPaintDevice buffer;
- QPainter painter(&buffer);
-
- painter.setRenderHint(QPainter::TextAntialiasing, false);
- page.render(&painter);
- QVERIFY(!(buffer.renderHints() & QPainter::TextAntialiasing));
- QVERIFY(!(buffer.renderHints() & QPainter::SmoothPixmapTransform));
- QVERIFY(!(buffer.renderHints() & QPainter::HighQualityAntialiasing));
-
- painter.setRenderHint(QPainter::TextAntialiasing, true);
- page.render(&painter);
- QVERIFY(buffer.renderHints() & QPainter::TextAntialiasing);
- QVERIFY(!(buffer.renderHints() & QPainter::SmoothPixmapTransform));
- QVERIFY(!(buffer.renderHints() & QPainter::HighQualityAntialiasing));
-
- painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
- page.render(&painter);
- QVERIFY(buffer.renderHints() & QPainter::TextAntialiasing);
- QVERIFY(buffer.renderHints() & QPainter::SmoothPixmapTransform);
- QVERIFY(!(buffer.renderHints() & QPainter::HighQualityAntialiasing));
-
- painter.setRenderHint(QPainter::HighQualityAntialiasing, true);
- page.render(&painter);
- QVERIFY(buffer.renderHints() & QPainter::TextAntialiasing);
- QVERIFY(buffer.renderHints() & QPainter::SmoothPixmapTransform);
- QVERIFY(buffer.renderHints() & QPainter::HighQualityAntialiasing);
-#endif
-}
-
-void tst_QWebEngineFrame::scrollPosition()
-{
-#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
- QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
-#else
- // enlarged image in a small viewport, to provoke the scrollbars to appear
- QString html("<html><body><img src='qrc:/image.png' height=500 width=500/></body></html>");
-
- QWebEnginePage page;
- page.setViewportSize(QSize(200, 200));
-
- page.setHtml(html);
- page.setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
- page.setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
-
- // try to set the scroll offset programmatically
- page.setScrollPosition(QPoint(23, 29));
- QCOMPARE(page.scrollPosition().x(), 23);
- QCOMPARE(page.scrollPosition().y(), 29);
-
- int x = page.evaluateJavaScript("window.scrollX").toInt();
- int y = page.evaluateJavaScript("window.scrollY").toInt();
- QCOMPARE(x, 23);
- QCOMPARE(y, 29);
-#endif
-}
-
-void tst_QWebEngineFrame::scrollToAnchor()
-{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
- QWebEnginePage page;
- page.setViewportSize(QSize(480, 800));
-
- QString html("<html><body><p style=\"margin-bottom: 1500px;\">Hello.</p>"
- "<p><a id=\"foo\">This</a> is an anchor</p>"
- "<p style=\"margin-bottom: 1500px;\"><a id=\"bar\">This</a> is another anchor</p>"
- "</body></html>");
- page.setHtml(html);
- page.setScrollPosition(QPoint(0, 0));
- QCOMPARE(page.scrollPosition().x(), 0);
- QCOMPARE(page.scrollPosition().y(), 0);
-
- QWebEngineElement fooAnchor = page.findFirstElement("a[id=foo]");
-
- page.scrollToAnchor("foo");
- QCOMPARE(page.scrollPosition().y(), fooAnchor.geometry().top());
-
- page.scrollToAnchor("bar");
- page.scrollToAnchor("foo");
- QCOMPARE(page.scrollPosition().y(), fooAnchor.geometry().top());
-
- page.scrollToAnchor("top");
- QCOMPARE(page.scrollPosition().y(), 0);
-
- page.scrollToAnchor("bar");
- page.scrollToAnchor("notexist");
- QVERIFY(page.scrollPosition().y() != 0);
-#endif
-}
-
-
-void tst_QWebEngineFrame::scrollbarsOff()
-{
-#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
- QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
-#else
- QWebEngineView view;
- QWebEngineFrame* mainFrame = view.page();
-
- mainFrame->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
- mainFrame->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
-
- QString html("<script>" \
- " function checkScrollbar() {" \
- " if (innerWidth === document.documentElement.offsetWidth)" \
- " document.getElementById('span1').innerText = 'SUCCESS';" \
- " else" \
- " document.getElementById('span1').innerText = 'FAIL';" \
- " }" \
- "</script>" \
- "<body>" \
- " <div style='margin-top:1000px ; margin-left:1000px'>" \
- " <a id='offscreen' href='a'>End</a>" \
- " </div>" \
- "<span id='span1'></span>" \
- "</body>");
-
-
- QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
- view.setHtml(html);
- ::waitForSignal(&view, SIGNAL(loadFinished(bool)), 200);
- QCOMPARE(loadSpy.count(), 1);
-
- mainFrame->evaluateJavaScript("checkScrollbar();");
- QCOMPARE(mainFrame->documentElement().findAll("span").at(0).toPlainText(), QString("SUCCESS"));
-#endif
-}
-
-void tst_QWebEngineFrame::horizontalScrollAfterBack()
-{
-#if !defined(QWEBENGINESETTINGS)
- QSKIP("QWEBENGINESETTINGS");
-#else
- QWebEngineView view;
- QSignalSpy loadSpy(view.page(), SIGNAL(loadFinished(bool)));
-
- view.page()->settings()->setMaximumPagesInCache(2);
- view.page()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAsNeeded);
- view.page()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAsNeeded);
-
- view.load(QUrl("qrc:/testiframe2.html"));
- view.resize(200, 200);
- QTRY_COMPARE(loadSpy.count(), 1);
- QTRY_VERIFY((view.page()->scrollBarGeometry(Qt::Horizontal)).height());
-
- view.load(QUrl("qrc:/testiframe.html"));
- QTRY_COMPARE(loadSpy.count(), 2);
-
- view.page()->triggerAction(QWebEnginePage::Back);
- QTRY_COMPARE(loadSpy.count(), 3);
- QTRY_VERIFY((view.page()->scrollBarGeometry(Qt::Horizontal)).height());
-#endif
-}
-
-void tst_QWebEngineFrame::evaluateWillCauseRepaint()
-{
-#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
- QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
-#else
- QWebEngineView view;
- QString html("<html><body>top<div id=\"junk\" style=\"display: block;\">"
- "junk</div>bottom</body></html>");
- view.setHtml(html);
- view.show();
-
- QTest::qWaitForWindowExposed(&view);
- view.page()->evaluateJavaScript(
- "document.getElementById('junk').style.display = 'none';");
-
- ::waitForSignal(view.page(), SIGNAL(repaintRequested(QRect)));
-#endif
-}
-
-void tst_QWebEngineFrame::setContent_data()
-{
- QTest::addColumn<QString>("mimeType");
- QTest::addColumn<QByteArray>("testContents");
- QTest::addColumn<QString>("expected");
-
- QString str = QString::fromUtf8("ὕαλον ϕαγεῖν δύναμαι· τοῦτο οὔ με βλάπτει");
- QTest::newRow("UTF-8 plain text") << "text/plain; charset=utf-8" << str.toUtf8() << str;
-
- QTextCodec *utf16 = QTextCodec::codecForName("UTF-16");
- if (utf16)
- QTest::newRow("UTF-16 plain text") << "text/plain; charset=utf-16" << utf16->fromUnicode(str) << str;
-
- str = QString::fromUtf8("Une chaîne de caractères à sa façon.");
- QTest::newRow("latin-1 plain text") << "text/plain; charset=iso-8859-1" << str.toLatin1() << str;
-
-
-}
-
-void tst_QWebEngineFrame::setContent()
-{
- QFETCH(QString, mimeType);
- QFETCH(QByteArray, testContents);
- QFETCH(QString, expected);
- QSignalSpy loadSpy(m_page, SIGNAL(loadFinished(bool)));
- m_view->setContent(testContents, mimeType);
- QVERIFY(loadSpy.wait());
- QCOMPARE(toPlainTextSync(m_view->page()), expected);
-}
-
-class CacheNetworkAccessManager : public QNetworkAccessManager {
-public:
- CacheNetworkAccessManager(QObject* parent = 0)
- : QNetworkAccessManager(parent)
- , m_lastCacheLoad(QNetworkRequest::PreferNetwork)
- {
- }
-
- virtual QNetworkReply* createRequest(Operation, const QNetworkRequest& request, QIODevice*)
- {
- QVariant cacheLoad = request.attribute(QNetworkRequest::CacheLoadControlAttribute);
- if (cacheLoad.isValid())
- m_lastCacheLoad = static_cast<QNetworkRequest::CacheLoadControl>(cacheLoad.toUInt());
- else
- m_lastCacheLoad = QNetworkRequest::PreferNetwork; // default value
- return new FakeReply(request, this);
- }
-
- QNetworkRequest::CacheLoadControl lastCacheLoad() const
- {
- return m_lastCacheLoad;
- }
-
-private:
- QNetworkRequest::CacheLoadControl m_lastCacheLoad;
-};
-
-void tst_QWebEngineFrame::setCacheLoadControlAttribute()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- QWebEnginePage page;
- CacheNetworkAccessManager* manager = new CacheNetworkAccessManager(&page);
- page.setNetworkAccessManager(manager);
-
- QNetworkRequest request(QUrl("http://abcdef.abcdef/"));
-
- request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache);
- page.load(request);
- QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::AlwaysCache);
-
- request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
- page.load(request);
- QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::PreferCache);
-
- request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
- page.load(request);
- QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::AlwaysNetwork);
-
- request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork);
- page.load(request);
- QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::PreferNetwork);
-#endif
-}
-
-void tst_QWebEngineFrame::setUrlWithPendingLoads()
-{
- QWebEnginePage page;
- page.setHtml("<img src='dummy:'/>");
- page.setUrl(QUrl("about:blank"));
-}
-
-void tst_QWebEngineFrame::setUrlToEmpty()
-{
- int expectedLoadFinishedCount = 0;
- const QUrl aboutBlank("about:blank");
- const QUrl url("qrc:/test2.html");
-
- QWebEnginePage page;
- QCOMPARE(page.url(), QUrl());
- QCOMPARE(page.requestedUrl(), QUrl());
- QCOMPARE(baseUrlSync(&page), QUrl());
-
- QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
-
- // Set existing url
- page.setUrl(url);
- expectedLoadFinishedCount++;
- ::waitForSignal(&page, SIGNAL(loadFinished(bool)));
-
- QCOMPARE(spy.count(), expectedLoadFinishedCount);
- QCOMPARE(page.url(), url);
- QCOMPARE(page.requestedUrl(), url);
- QCOMPARE(baseUrlSync(&page), url);
-
- // Set empty url
- page.setUrl(QUrl());
- expectedLoadFinishedCount++;
-
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
- QCOMPARE(page.url(), aboutBlank);
- QCOMPARE(page.requestedUrl(), QUrl());
- QCOMPARE(baseUrlSync(&page), aboutBlank);
-
- // Set existing url
- page.setUrl(url);
- expectedLoadFinishedCount++;
-
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
- QCOMPARE(page.url(), url);
- QCOMPARE(page.requestedUrl(), url);
- QCOMPARE(baseUrlSync(&page), url);
-
- // Load empty url
- page.load(QUrl());
- expectedLoadFinishedCount++;
-
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
- QCOMPARE(page.url(), aboutBlank);
- QCOMPARE(page.requestedUrl(), QUrl());
- QCOMPARE(baseUrlSync(&page), aboutBlank);
-}
-
-void tst_QWebEngineFrame::setUrlToInvalid()
-{
- QEXPECT_FAIL("", "Unsupported: QtWebEngine doesn't adjust invalid URLs.", Abort);
- QVERIFY(false);
-
- QWebEnginePage page;
-
- const QUrl invalidUrl("http:/example.com");
- QVERIFY(!invalidUrl.isEmpty());
- QVERIFY(invalidUrl != QUrl());
-
- // QWebEngineFrame will do its best to accept the URL, possible converting it to a valid equivalent URL.
- const QUrl validUrl("http://example.com/");
- page.setUrl(invalidUrl);
- QCOMPARE(page.url(), validUrl);
- QCOMPARE(page.requestedUrl(), validUrl);
- QCOMPARE(baseUrlSync(&page), validUrl);
-
- // QUrls equivalent to QUrl() will be treated as such.
- const QUrl aboutBlank("about:blank");
- const QUrl anotherInvalidUrl("1http://bugs.webkit.org");
- QVERIFY(!anotherInvalidUrl.isEmpty()); // and they are not necessarily empty.
- QVERIFY(!anotherInvalidUrl.isValid());
- QCOMPARE(anotherInvalidUrl.toEncoded(), QUrl().toEncoded());
-
- page.setUrl(anotherInvalidUrl);
- QCOMPARE(page.url(), aboutBlank);
- QCOMPARE(page.requestedUrl().toEncoded(), anotherInvalidUrl.toEncoded());
- QCOMPARE(baseUrlSync(&page), aboutBlank);
-}
-
-static QStringList collectHistoryUrls(QWebEngineHistory *history)
-{
- QStringList urls;
- foreach (const QWebEngineHistoryItem &i, history->items())
- urls << i.url().toString();
- return urls;
-}
-
-void tst_QWebEngineFrame::setUrlHistory()
-{
- const QUrl aboutBlank("about:blank");
- QUrl url;
- int expectedLoadFinishedCount = 0;
- QSignalSpy spy(m_page, SIGNAL(loadFinished(bool)));
-
- QCOMPARE(m_page->history()->count(), 0);
-
- m_page->setUrl(QUrl());
- expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
- QCOMPARE(m_page->url(), aboutBlank);
- QCOMPARE(m_page->requestedUrl(), QUrl());
- // Chromium stores navigation entry for every successful loads. The load of the empty page is committed and stored as about:blank.
- QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString());
-
- url = QUrl("http://non.existent/");
- m_page->setUrl(url);
- expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
- // When error page is disabled in case of LoadFail the entry of the unavailable page is not stored.
- // We expect the url of the previously loaded page here.
- QCOMPARE(m_page->url(), aboutBlank);
- QCOMPARE(m_page->requestedUrl(), QUrl());
- // Since the entry of the unavailable page is not stored it will not available in the history.
- QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString());
-
- url = QUrl("qrc:/test1.html");
- m_page->setUrl(url);
- expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
- QCOMPARE(m_page->url(), url);
- QCOMPARE(m_page->requestedUrl(), url);
- QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString() << QStringLiteral("qrc:/test1.html"));
-
- m_page->setUrl(QUrl());
- expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
- QCOMPARE(m_page->url(), aboutBlank);
- QCOMPARE(m_page->requestedUrl(), QUrl());
- // Chromium stores navigation entry for every successful loads. The load of the empty page is committed and stored as about:blank.
- QCOMPARE(collectHistoryUrls(m_page->history()), QStringList()
- << aboutBlank.toString()
- << QStringLiteral("qrc:/test1.html")
- << aboutBlank.toString());
-
- url = QUrl("qrc:/test1.html");
- m_page->setUrl(url);
- expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
- QCOMPARE(m_page->url(), url);
- QCOMPARE(m_page->requestedUrl(), url);
- // The history count DOES change since the about:blank is in the list.
- QCOMPARE(collectHistoryUrls(m_page->history()), QStringList()
- << aboutBlank.toString()
- << QStringLiteral("qrc:/test1.html")
- << aboutBlank.toString()
- << QStringLiteral("qrc:/test1.html"));
-
- url = QUrl("qrc:/test2.html");
- m_page->setUrl(url);
- expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
- QCOMPARE(m_page->url(), url);
- QCOMPARE(m_page->requestedUrl(), url);
- QCOMPARE(collectHistoryUrls(m_page->history()), QStringList()
- << aboutBlank.toString()
- << QStringLiteral("qrc:/test1.html")
- << aboutBlank.toString()
- << QStringLiteral("qrc:/test1.html")
- << QStringLiteral("qrc:/test2.html"));
-}
-
-void tst_QWebEngineFrame::setUrlUsingStateObject()
-{
- const QUrl aboutBlank("about:blank");
- QUrl url;
- QSignalSpy urlChangedSpy(m_page, SIGNAL(urlChanged(QUrl)));
- int expectedUrlChangeCount = 0;
-
- QCOMPARE(m_page->history()->count(), 0);
-
- url = QUrl("qrc:/test1.html");
- m_page->setUrl(url);
- waitForSignal(m_page, SIGNAL(loadFinished(bool)));
- expectedUrlChangeCount++;
- QCOMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
- QCOMPARE(m_page->url(), url);
- QCOMPARE(m_page->history()->count(), 1);
-
- evaluateJavaScriptSync(m_page, "window.history.pushState(null, 'push', 'navigate/to/here')");
- expectedUrlChangeCount++;
- QCOMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
- QCOMPARE(m_page->url(), QUrl("qrc:/navigate/to/here"));
- QCOMPARE(m_page->history()->count(), 2);
- QVERIFY(m_page->history()->canGoBack());
-
- evaluateJavaScriptSync(m_page, "window.history.replaceState(null, 'replace', 'another/location')");
- expectedUrlChangeCount++;
- QCOMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
- QCOMPARE(m_page->url(), QUrl("qrc:/navigate/to/another/location"));
- QCOMPARE(m_page->history()->count(), 2);
- QVERIFY(!m_page->history()->canGoForward());
- QVERIFY(m_page->history()->canGoBack());
-
- evaluateJavaScriptSync(m_page, "window.history.back()");
- QTest::qWait(100);
- expectedUrlChangeCount++;
- QCOMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
- QCOMPARE(m_page->url(), QUrl("qrc:/test1.html"));
- QVERIFY(m_page->history()->canGoForward());
- QVERIFY(!m_page->history()->canGoBack());
-}
-
-void tst_QWebEngineFrame::setUrlSameUrl()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- const QUrl url1("qrc:/test1.html");
- const QUrl url2("qrc:/test2.html");
-
- QWebEnginePage page;
- FakeNetworkManager* networkManager = new FakeNetworkManager(&page);
- page.setNetworkAccessManager(networkManager);
-
- QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
-
- page.setUrl(url1);
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
- QVERIFY(page.url() != url1); // Nota bene: our QNAM redirects url1 to url2
- QCOMPARE(page.url(), url2);
- QCOMPARE(spy.count(), 1);
-
- page.setUrl(url1);
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
- QVERIFY(page.url() != url1);
- QCOMPARE(page.url(), url2);
- QCOMPARE(spy.count(), 2);
-
- // Now a case without redirect. The existing behavior we have for setUrl()
- // is more like a "clear(); load()", so the page will be loaded again, even
- // if urlToBeLoaded == url(). This test should be changed if we want to
- // make setUrl() early return in this case.
- page.setUrl(url2);
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
- QCOMPARE(page.url(), url2);
- QCOMPARE(spy.count(), 3);
-
- page.setUrl(url1);
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
- QCOMPARE(page.url(), url2);
- QCOMPARE(spy.count(), 4);
-#endif
-}
-
-static inline QUrl extractBaseUrl(const QUrl& url)
-{
- return url.resolved(QUrl());
-}
-
-void tst_QWebEngineFrame::setUrlThenLoads_data()
-{
- QTest::addColumn<QUrl>("url");
- QTest::addColumn<QUrl>("baseUrl");
-
- QTest::newRow("resource file") << QUrl("qrc:/test1.html") << extractBaseUrl(QUrl("qrc:/test1.html"));
- QTest::newRow("base specified in HTML") << QUrl("data:text/html,<head><base href=\"http://different.base/\"></head>") << QUrl("http://different.base/");
-}
-
-void tst_QWebEngineFrame::setUrlThenLoads()
-{
- QFETCH(QUrl, url);
- QFETCH(QUrl, baseUrl);
- QSignalSpy urlChangedSpy(m_page, SIGNAL(urlChanged(QUrl)));
- QSignalSpy startedSpy(m_page, SIGNAL(loadStarted()));
- QSignalSpy finishedSpy(m_page, SIGNAL(loadFinished(bool)));
-
- m_page->setUrl(url);
- QTRY_COMPARE(startedSpy.count(), 1);
- QTRY_COMPARE(urlChangedSpy.count(), 1);
- QTRY_COMPARE(finishedSpy.count(), 1);
- QVERIFY(finishedSpy.at(0).first().toBool());
- QCOMPARE(m_page->url(), url);
- QCOMPARE(m_page->requestedUrl(), url);
- QCOMPARE(baseUrlSync(m_page), baseUrl);
-
- const QUrl urlToLoad1("qrc:/test2.html");
- const QUrl urlToLoad2("qrc:/test1.html");
-
- // Just after first load. URL didn't changed yet.
- m_page->load(urlToLoad1);
- QCOMPARE(m_page->url(), url);
- QCOMPARE(m_page->requestedUrl(), urlToLoad1);
- // baseUrlSync spins an event loop and this sometimes return the next result.
- // QCOMPARE(baseUrlSync(m_page), baseUrl);
- QTRY_COMPARE(startedSpy.count(), 2);
-
- // After first URL changed.
- QTRY_COMPARE(urlChangedSpy.count(), 2);
- QTRY_COMPARE(finishedSpy.count(), 2);
- QVERIFY(finishedSpy.at(1).first().toBool());
- QCOMPARE(m_page->url(), urlToLoad1);
- QCOMPARE(m_page->requestedUrl(), urlToLoad1);
- QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad1));
-
- // Just after second load. URL didn't changed yet.
- m_page->load(urlToLoad2);
- QCOMPARE(m_page->url(), urlToLoad1);
- QCOMPARE(m_page->requestedUrl(), urlToLoad2);
- QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad1));
- QTRY_COMPARE(startedSpy.count(), 3);
-
- // After second URL changed.
- QTRY_COMPARE(urlChangedSpy.count(), 3);
- QTRY_COMPARE(finishedSpy.count(), 3);
- QVERIFY(finishedSpy.at(2).first().toBool());
- QCOMPARE(m_page->url(), urlToLoad2);
- QCOMPARE(m_page->requestedUrl(), urlToLoad2);
- QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad2));
-}
-
-void tst_QWebEngineFrame::loadFinishedAfterNotFoundError()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- QWebEnginePage page;
-
- QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
- FakeNetworkManager* networkManager = new FakeNetworkManager(&page);
- page.setNetworkAccessManager(networkManager);
-
- page.setUrl(FakeReply::urlFor404ErrorWithoutContents);
- QTRY_COMPARE(spy.count(), 1);
- const bool wasLoadOk = spy.at(0).at(0).toBool();
- QVERIFY(!wasLoadOk);
-#endif
-}
-
-class URLSetter : public QObject {
- Q_OBJECT
-
-public:
- enum Signal {
- LoadStarted,
- LoadFinished,
- ProvisionalLoad
- };
-
- enum Type {
- UseLoad,
- UseSetUrl
- };
-
- URLSetter(QWebEnginePage*, Signal, Type, const QUrl&);
-
-public Q_SLOTS:
- void execute();
-
-Q_SIGNALS:
- void finished();
-
-private:
- QWebEnginePage* m_page;
- QUrl m_url;
- Type m_type;
-};
-
-Q_DECLARE_METATYPE(URLSetter::Signal)
-Q_DECLARE_METATYPE(URLSetter::Type)
-
-URLSetter::URLSetter(QWebEnginePage* page, Signal signal, URLSetter::Type type, const QUrl& url)
- : m_page(page), m_url(url), m_type(type)
-{
- if (signal == LoadStarted)
- connect(m_page, SIGNAL(loadStarted()), SLOT(execute()));
- else if (signal == LoadFinished)
- connect(m_page, SIGNAL(loadFinished(bool)), SLOT(execute()));
- else
- connect(m_page, SIGNAL(provisionalLoad()), SLOT(execute()));
-}
-
-void URLSetter::execute()
-{
- // We track only the first emission.
- m_page->disconnect(this);
- if (m_type == URLSetter::UseLoad)
- m_page->load(m_url);
- else
- m_page->setUrl(m_url);
- connect(m_page, SIGNAL(loadFinished(bool)), SIGNAL(finished()));
-}
-
-void tst_QWebEngineFrame::loadInSignalHandlers_data()
-{
- QSKIP("FIXME: This crashes in content::WebContentsImpl::NavigateToEntry because of reentrancy. Should we require QueuedConnections or do it ourselves to support this?");
-
- QTest::addColumn<URLSetter::Type>("type");
- QTest::addColumn<URLSetter::Signal>("signal");
- QTest::addColumn<QUrl>("url");
-
- const QUrl validUrl("qrc:/test2.html");
- const QUrl invalidUrl("qrc:/invalid");
-
- QTest::newRow("call load() in loadStarted() after valid url") << URLSetter::UseLoad << URLSetter::LoadStarted << validUrl;
- QTest::newRow("call load() in loadStarted() after invalid url") << URLSetter::UseLoad << URLSetter::LoadStarted << invalidUrl;
- QTest::newRow("call load() in loadFinished() after valid url") << URLSetter::UseLoad << URLSetter::LoadFinished << validUrl;
- QTest::newRow("call load() in loadFinished() after invalid url") << URLSetter::UseLoad << URLSetter::LoadFinished << invalidUrl;
- QTest::newRow("call load() in provisionalLoad() after valid url") << URLSetter::UseLoad << URLSetter::ProvisionalLoad << validUrl;
- QTest::newRow("call load() in provisionalLoad() after invalid url") << URLSetter::UseLoad << URLSetter::ProvisionalLoad << invalidUrl;
-
- QTest::newRow("call setUrl() in loadStarted() after valid url") << URLSetter::UseSetUrl << URLSetter::LoadStarted << validUrl;
- QTest::newRow("call setUrl() in loadStarted() after invalid url") << URLSetter::UseSetUrl << URLSetter::LoadStarted << invalidUrl;
- QTest::newRow("call setUrl() in loadFinished() after valid url") << URLSetter::UseSetUrl << URLSetter::LoadFinished << validUrl;
- QTest::newRow("call setUrl() in loadFinished() after invalid url") << URLSetter::UseSetUrl << URLSetter::LoadFinished << invalidUrl;
- QTest::newRow("call setUrl() in provisionalLoad() after valid url") << URLSetter::UseSetUrl << URLSetter::ProvisionalLoad << validUrl;
- QTest::newRow("call setUrl() in provisionalLoad() after invalid url") << URLSetter::UseSetUrl << URLSetter::ProvisionalLoad << invalidUrl;
-}
-
-void tst_QWebEngineFrame::loadInSignalHandlers()
-{
- QFETCH(URLSetter::Type, type);
- QFETCH(URLSetter::Signal, signal);
- QFETCH(QUrl, url);
-
- const QUrl urlForSetter("qrc:/test1.html");
- URLSetter setter(m_page, signal, type, urlForSetter);
-
- m_page->load(url);
- waitForSignal(&setter, SIGNAL(finished()), 200);
- QCOMPARE(m_page->url(), urlForSetter);
-}
-
-QTEST_MAIN(tst_QWebEngineFrame)
-#include "tst_qwebengineframe.moc"
diff --git a/tests/auto/widgets/qwebengineframe/tst_qwebengineframe.qrc b/tests/auto/widgets/qwebengineframe/tst_qwebengineframe.qrc
deleted file mode 100644
index 2a7d0b9c2..000000000
--- a/tests/auto/widgets/qwebengineframe/tst_qwebengineframe.qrc
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/">
-<file alias="image.png">resources/image.png</file>
-<file alias="style.css">resources/style.css</file>
-<file alias="test1.html">resources/test1.html</file>
-<file alias="test2.html">resources/test2.html</file>
-<file alias="testiframe.html">resources/testiframe.html</file>
-<file alias="testiframe2.html">resources/testiframe2.html</file>
-</qresource>
-</RCC>
diff --git a/tests/auto/widgets/qwebenginehistory/qwebenginehistory.pro b/tests/auto/widgets/qwebenginehistory/qwebenginehistory.pro
index ff6c49628..e99c7f493 100644
--- a/tests/auto/widgets/qwebenginehistory/qwebenginehistory.pro
+++ b/tests/auto/widgets/qwebenginehistory/qwebenginehistory.pro
@@ -1,2 +1 @@
include(../tests.pri)
-exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
diff --git a/tests/auto/widgets/qwebenginehistoryinterface/qwebenginehistoryinterface.pro b/tests/auto/widgets/qwebenginehistoryinterface/qwebenginehistoryinterface.pro
index ff6c49628..e99c7f493 100644
--- a/tests/auto/widgets/qwebenginehistoryinterface/qwebenginehistoryinterface.pro
+++ b/tests/auto/widgets/qwebenginehistoryinterface/qwebenginehistoryinterface.pro
@@ -1,2 +1 @@
include(../tests.pri)
-exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
diff --git a/tests/auto/widgets/qwebengineinspector/qwebengineinspector.pro b/tests/auto/widgets/qwebengineinspector/qwebengineinspector.pro
index ff6c49628..e99c7f493 100644
--- a/tests/auto/widgets/qwebengineinspector/qwebengineinspector.pro
+++ b/tests/auto/widgets/qwebengineinspector/qwebengineinspector.pro
@@ -1,2 +1 @@
include(../tests.pri)
-exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
diff --git a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
index e56bbe8f7..70786e70f 100644
--- a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
+++ b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
@@ -1,3 +1,2 @@
include(../tests.pri)
-exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
QT *= core-private gui-private
diff --git a/tests/auto/widgets/qwebenginepage/resources/fullscreen.html b/tests/auto/widgets/qwebenginepage/resources/fullscreen.html
new file mode 100644
index 000000000..84771ca85
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/fullscreen.html
@@ -0,0 +1,10 @@
+<html>
+<body onkeypress='onKeyPress()'>
+<a>This is test content</a>
+<script>
+function onKeyPress() {
+ document.documentElement.webkitRequestFullScreen();
+}
+</script>
+</body>
+</html>
diff --git a/tests/auto/widgets/qwebengineframe/resources/image.png b/tests/auto/widgets/qwebenginepage/resources/image.png
index 8d703640c..8d703640c 100644
--- a/tests/auto/widgets/qwebengineframe/resources/image.png
+++ b/tests/auto/widgets/qwebenginepage/resources/image.png
Binary files differ
diff --git a/tests/auto/widgets/qwebengineframe/resources/style.css b/tests/auto/widgets/qwebenginepage/resources/style.css
index c05b747f1..c05b747f1 100644
--- a/tests/auto/widgets/qwebengineframe/resources/style.css
+++ b/tests/auto/widgets/qwebenginepage/resources/style.css
diff --git a/tests/auto/widgets/qwebengineframe/resources/test1.html b/tests/auto/widgets/qwebenginepage/resources/test1.html
index b323f966e..b323f966e 100644
--- a/tests/auto/widgets/qwebengineframe/resources/test1.html
+++ b/tests/auto/widgets/qwebenginepage/resources/test1.html
diff --git a/tests/auto/widgets/qwebengineframe/resources/test2.html b/tests/auto/widgets/qwebenginepage/resources/test2.html
index 63ac1f6ec..63ac1f6ec 100644
--- a/tests/auto/widgets/qwebengineframe/resources/test2.html
+++ b/tests/auto/widgets/qwebenginepage/resources/test2.html
diff --git a/tests/auto/widgets/qwebengineframe/resources/testiframe.html b/tests/auto/widgets/qwebenginepage/resources/testiframe.html
index 4b0e30ca5..4b0e30ca5 100644
--- a/tests/auto/widgets/qwebengineframe/resources/testiframe.html
+++ b/tests/auto/widgets/qwebenginepage/resources/testiframe.html
diff --git a/tests/auto/widgets/qwebengineframe/resources/testiframe2.html b/tests/auto/widgets/qwebenginepage/resources/testiframe2.html
index 8957a5d8a..8957a5d8a 100644
--- a/tests/auto/widgets/qwebengineframe/resources/testiframe2.html
+++ b/tests/auto/widgets/qwebenginepage/resources/testiframe2.html
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 9562871b3..ffd8ccba7 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -27,6 +27,7 @@
#include <QMainWindow>
#include <QMenu>
#include <QMimeDatabase>
+#include <QPaintEngine>
#include <QPushButton>
#include <QStateMachine>
#include <QStyle>
@@ -37,8 +38,10 @@
#include <qnetworkreply.h>
#include <qnetworkrequest.h>
#include <qpa/qplatforminputcontext.h>
+#include <qwebenginefullscreenrequest.h>
#include <qwebenginehistory.h>
#include <qwebenginepage.h>
+#include <qwebengineprofile.h>
#include <qwebenginesettings.h>
#include <qwebengineview.h>
#include <qimagewriter.h>
@@ -95,6 +98,8 @@ public:
tst_QWebEnginePage();
virtual ~tst_QWebEnginePage();
+ bool eventFilter(QObject *watched, QEvent *event);
+
public Q_SLOTS:
void init();
void cleanup();
@@ -108,6 +113,7 @@ private Q_SLOTS:
void contextMenuPopulatedOnce();
void acceptNavigationRequest();
void acceptNavigationRequestNavigationType();
+ void geolocationRequestJS_data();
void geolocationRequestJS();
void loadFinished();
void actionStates();
@@ -132,7 +138,6 @@ private Q_SLOTS:
void textSelection();
void textEditing();
void backActionUpdate();
- void frameAt();
void protectBindingsRuntimeObjectsFromCollector();
void localURLSchemes();
void testOptionalJSObjects();
@@ -145,10 +150,7 @@ private Q_SLOTS:
void inputMethodsTextFormat();
void defaultTextEncoding();
void errorPageExtension();
- void errorPageExtensionInIFrames();
- void errorPageExtensionInFrameset();
void errorPageExtensionLoadFinished();
- void userAgentApplicationName();
void userAgentNewlineStripping();
void undoActionHaveCustomText();
void renderWidgetHostViewNotShowTopLevel();
@@ -166,9 +168,6 @@ private Q_SLOTS:
void unacceleratedWebGLScreenshotWithoutView();
#endif
- void originatingObjectInNetworkRequests();
- void networkReplyParentDidntChange();
- void destroyQNAMBeforeAbortDoesntCrash();
void testJSPrompt();
void testStopScheduledPageRefresh();
void findText();
@@ -192,10 +191,57 @@ private Q_SLOTS:
#endif
void runJavaScript();
+ void fullScreenRequested();
+
+
+ // Tests from tst_QWebEngineFrame
+ void horizontalScrollAfterBack();
+ void symmetricUrl();
+ void progressSignal();
+ void urlChange();
+ void requestedUrlAfterSetAndLoadFailures();
+ void javaScriptWindowObjectCleared_data();
+ void javaScriptWindowObjectCleared();
+ void javaScriptWindowObjectClearedOnEvaluate();
+ void asyncAndDelete();
+ void earlyToHtml();
+ void setHtml();
+ void setHtmlWithImageResource();
+ void setHtmlWithStylesheetResource();
+ void setHtmlWithBaseURL();
+ void setHtmlWithJSAlert();
+ void metaData();
+#if !defined(QT_NO_COMBOBOX)
+ void popupFocus();
+#endif
+ void inputFieldFocus();
+ void hitTestContent();
+ void baseUrl_data();
+ void baseUrl();
+ void renderHints();
+ void scrollPosition();
+ void scrollToAnchor();
+ void scrollbarsOff();
+ void evaluateWillCauseRepaint();
+ void setContent_data();
+ void setContent();
+ void setCacheLoadControlAttribute();
+ void setUrlWithPendingLoads();
+ void setUrlToEmpty();
+ void setUrlToInvalid();
+ void setUrlHistory();
+ void setUrlUsingStateObject();
+ void setUrlThenLoads_data();
+ void setUrlThenLoads();
+ void loadFinishedAfterNotFoundError();
+ void loadInSignalHandlers_data();
+ void loadInSignalHandlers();
private:
QWebEngineView* m_view;
QWebEnginePage* m_page;
+ QWebEngineView* m_inputFieldsTestView;
+ int m_inputFieldTestPaintCount;
QString tmpDirPath() const
{
static QString tmpd = QDir::tempPath() + "/tst_qwebenginepage-"
@@ -212,10 +258,21 @@ tst_QWebEnginePage::~tst_QWebEnginePage()
{
}
+bool tst_QWebEnginePage::eventFilter(QObject* watched, QEvent* event)
+{
+ // used on the inputFieldFocus test
+ if (watched == m_inputFieldsTestView) {
+ if (event->type() == QEvent::Paint)
+ m_inputFieldTestPaintCount++;
+ }
+ return QObject::eventFilter(watched, event);
+}
+
void tst_QWebEnginePage::init()
{
m_view = new QWebEngineView();
m_page = m_view->page();
+ m_page->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
}
void tst_QWebEnginePage::cleanup()
@@ -278,7 +335,6 @@ void tst_QWebEnginePage::acceptNavigationRequest()
m_view->setPage(0);
}
-#if defined(QWEBENGINEPAGE_SETFEATUREPERMISSION)
class JSTestPage : public QWebEnginePage
{
Q_OBJECT
@@ -291,12 +347,12 @@ public:
return true;
}
public Q_SLOTS:
- void requestPermission(QWebEngineFrame* frame, QWebEnginePage::Feature feature)
+ void requestPermission(const QUrl &origin, QWebEnginePage::Feature feature)
{
if (m_allowGeolocation)
- setFeaturePermission(frame, feature, PermissionGrantedByUser);
+ setFeaturePermission(origin, feature, PermissionGrantedByUser);
else
- setFeaturePermission(frame, feature, PermissionDeniedByUser);
+ setFeaturePermission(origin, feature, PermissionDeniedByUser);
}
public:
@@ -308,7 +364,6 @@ public:
private:
bool m_allowGeolocation;
};
-#endif
// [Qt] tst_QWebEnginePage::infiniteLoopJS() timeouts with DFG JIT
// https://bugs.webkit.org/show_bug.cgi?id=79040
@@ -323,40 +378,38 @@ void tst_QWebEnginePage::infiniteLoopJS()
}
*/
-void tst_QWebEnginePage::geolocationRequestJS()
+void tst_QWebEnginePage::geolocationRequestJS_data()
{
-#if !defined(QWEBENGINEPAGE_SETFEATUREPERMISSION)
- QSKIP("QWEBENGINEPAGE_SETFEATUREPERMISSION");
-#else
- JSTestPage* newPage = new JSTestPage(m_view);
+ QTest::addColumn<bool>("allowed");
+ QTest::addColumn<int>("errorCode");
+ QTest::newRow("allowed") << true << 0;
+ QTest::newRow("not allowed") << false << 1;
+}
+void tst_QWebEnginePage::geolocationRequestJS()
+{
+ QFETCH(bool, allowed);
+ QFETCH(int, errorCode);
+ QWebEngineView *view = new QWebEngineView;
+ JSTestPage *newPage = new JSTestPage(view);
+ newPage->setView(view);
+ newPage->setGeolocationPermission(allowed);
+
+ connect(newPage, SIGNAL(featurePermissionRequested(const QUrl&, QWebEnginePage::Feature)),
+ newPage, SLOT(requestPermission(const QUrl&, QWebEnginePage::Feature)));
+
+ QSignalSpy spyLoadFinished(newPage, SIGNAL(loadFinished(bool)));
+ newPage->setHtml(QString("<html><body>test</body></html>"), QUrl());
+ QTRY_COMPARE(spyLoadFinished.count(), 1);
if (evaluateJavaScriptSync(newPage, QLatin1String("!navigator.geolocation")).toBool()) {
- delete newPage;
+ delete view;
W_QSKIP("Geolocation is not supported.", SkipSingle);
}
- connect(newPage, SIGNAL(featurePermissionRequested(QWebEngineFrame*, QWebEnginePage::Feature)),
- newPage, SLOT(requestPermission(QWebEngineFrame*, QWebEnginePage::Feature)));
-
- newPage->setGeolocationPermission(false);
- m_view->setPage(newPage);
- m_view->setHtml(QString("<html><body>test</body></html>"), QUrl());
- evaluateJavaScriptSync(m_view->page(), "var errorCode = 0; function error(err) { errorCode = err.code; } function success(pos) { } navigator.geolocation.getCurrentPosition(success, error)");
- QTest::qWait(2000);
- QVariant empty = evaluateJavaScriptSync(m_view->page(), "errorCode");
-
- QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=102235", Continue);
- QVERIFY(empty.type() == QVariant::Double && empty.toInt() != 0);
+ evaluateJavaScriptSync(newPage, "var errorCode = 0; function error(err) { errorCode = err.code; } function success(pos) { } navigator.geolocation.getCurrentPosition(success, error)");
- newPage->setGeolocationPermission(true);
- evaluateJavaScriptSync(m_view->page(), "errorCode = 0; navigator.geolocation.getCurrentPosition(success, error);");
- empty = evaluateJavaScriptSync(m_view->page(), "errorCode");
-
- //http://dev.w3.org/geo/api/spec-source.html#position
- //PositionError: const unsigned short PERMISSION_DENIED = 1;
- QVERIFY(empty.type() == QVariant::Double && empty.toInt() != 1);
- delete newPage;
-#endif
+ QTRY_COMPARE(evaluateJavaScriptSync(newPage, "errorCode").toInt(), errorCode);
+ delete view;
}
void tst_QWebEnginePage::loadFinished()
@@ -1176,6 +1229,10 @@ public:
int isSelectionCollapsed() {
return evaluateJavaScriptSync(this, "window.getSelection().getRangeAt(0).collapsed").toBool();
}
+ bool hasSelection()
+ {
+ return !selectedText().isEmpty();
+ }
};
void tst_QWebEnginePage::cursorMovements()
@@ -1380,17 +1437,19 @@ void tst_QWebEnginePage::cursorMovements()
void tst_QWebEnginePage::textSelection()
{
-#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
- QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
-#else
- CursorTrackedPage* page = new CursorTrackedPage;
+ QWebEngineView *view = new QWebEngineView;
+ CursorTrackedPage *page = new CursorTrackedPage;
QString content("<html><body><p id=one>The quick brown fox</p>" \
"<p id=two>jumps over the lazy dog</p>" \
"<p>May the source<br/>be with you!</p></body></html>");
+ page->setView(view);
+ QSignalSpy loadSpy(view, SIGNAL(loadFinished(bool)));
page->setHtml(content);
+ QTRY_COMPARE(loadSpy.count(), 1);
// these actions must exist
QVERIFY(page->action(QWebEnginePage::SelectAll) != 0);
+#if defined(QWEBENGINEPAGE_SELECTACTIONS)
QVERIFY(page->action(QWebEnginePage::SelectNextChar) != 0);
QVERIFY(page->action(QWebEnginePage::SelectPreviousChar) != 0);
QVERIFY(page->action(QWebEnginePage::SelectNextWord) != 0);
@@ -1418,6 +1477,7 @@ void tst_QWebEnginePage::textSelection()
QCOMPARE(page->action(QWebEnginePage::SelectEndOfBlock)->isEnabled(), false);
QCOMPARE(page->action(QWebEnginePage::SelectStartOfDocument)->isEnabled(), false);
QCOMPARE(page->action(QWebEnginePage::SelectEndOfDocument)->isEnabled(), false);
+#endif
// ..but SelectAll is awalys enabled
QCOMPARE(page->action(QWebEnginePage::SelectAll)->isEnabled(), true);
@@ -1432,13 +1492,15 @@ void tst_QWebEnginePage::textSelection()
"getSelection().addRange(range);";
evaluateJavaScriptSync(page, selectScript);
QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox"));
+#if defined(QWEBENGINEPAGE_SELECTEDHTML)
QRegExp regExp(" style=\".*\"");
regExp.setMinimal(true);
QCOMPARE(page->selectedHtml().trimmed().replace(regExp, ""), QString::fromLatin1("<p id=\"one\">The quick brown fox</p>"));
-
+#endif
// Make sure hasSelection returns true, since there is selected text now...
QCOMPARE(page->hasSelection(), true);
+#if defined(QWEBENGINEPAGE_SELECTACTIONS)
// here the actions are enabled after a selection has been created
QCOMPARE(page->action(QWebEnginePage::SelectNextChar)->isEnabled(), true);
QCOMPARE(page->action(QWebEnginePage::SelectPreviousChar)->isEnabled(), true);
@@ -1474,9 +1536,10 @@ void tst_QWebEnginePage::textSelection()
QCOMPARE(page->action(QWebEnginePage::SelectEndOfBlock)->isEnabled(), true);
QCOMPARE(page->action(QWebEnginePage::SelectStartOfDocument)->isEnabled(), true);
QCOMPARE(page->action(QWebEnginePage::SelectEndOfDocument)->isEnabled(), true);
+#endif
delete page;
-#endif
+ delete view;
}
void tst_QWebEnginePage::textEditing()
@@ -1621,39 +1684,6 @@ void tst_QWebEnginePage::backActionUpdate()
QVERIFY(action->isEnabled());
}
-#if defined(QWEBENGINEFRAME)
-void frameAtHelper(QWebEnginePage* webPage, QWebEngineFrame* webFrame, QPoint framePosition)
-{
- if (!webFrame)
- return;
-
- framePosition += QPoint(webFrame->pos());
- QList<QWebEngineFrame*> children = webFrame->childFrames();
- for (int i = 0; i < children.size(); ++i) {
- if (children.at(i)->childFrames().size() > 0)
- frameAtHelper(webPage, children.at(i), framePosition);
-
- QRect frameRect(children.at(i)->pos() + framePosition, children.at(i)->geometry().size());
- QVERIFY(children.at(i) == webPage->frameAt(frameRect.topLeft()));
- }
-}
-#endif
-
-void tst_QWebEnginePage::frameAt()
-{
-#if !defined(QWEBENGINEFRAME)
- QSKIP("QWEBENGINEFRAME");
-#else
- QWebEngineView webView;
- QWebEnginePage* webPage = webView.page();
- QSignalSpy loadSpy(webPage, SIGNAL(loadFinished(bool)));
- QUrl url = QUrl("qrc:///resources/iframe.html");
- webPage->load(url);
- QTRY_COMPARE(loadSpy.count(), 1);
- frameAtHelper(webPage, webPage->mainFrame(), webPage->mainFrame()->pos());
-#endif
-}
-
void tst_QWebEnginePage::inputMethods_data()
{
QTest::addColumn<QString>("viewType");
@@ -2726,47 +2756,6 @@ void tst_QWebEnginePage::errorPageExtension()
#endif
}
-void tst_QWebEnginePage::errorPageExtensionInIFrames()
-{
-#if !defined(QWEBENGINEFRAME)
- QSKIP("QWEBENGINEFRAME");
-#else
- ErrorPage page;
- m_view->setPage(&page);
-
- m_view->page()->load(QUrl(
- "data:text/html,"
- "<h1>h1</h1>"
- "<iframe src='data:text/html,<p/>p'></iframe>"
- "<iframe src='http://non.existent/url'></iframe>"));
- QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool)));
- QTRY_COMPARE(spyLoadFinished.count(), 1);
-
- QCOMPARE(page.mainFrame()->childFrames()[1]->toPlainText(), QString("error"));
-
- m_view->setPage(0);
-#endif
-}
-
-void tst_QWebEnginePage::errorPageExtensionInFrameset()
-{
-#if !defined(QWEBENGINEFRAME)
- QSKIP("QWEBENGINEFRAME");
-#else
- ErrorPage page;
- m_view->setPage(&page);
-
- m_view->load(QUrl("qrc:///resources/index.html"));
-
- QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool)));
- QTRY_COMPARE(spyLoadFinished.count(), 1);
- QCOMPARE(page.mainFrame()->childFrames().count(), 2);
- QCOMPARE(page.mainFrame()->childFrames()[1]->toPlainText(), QString("error"));
-
- m_view->setPage(0);
-#endif
-}
-
void tst_QWebEnginePage::errorPageExtensionLoadFinished()
{
#if !defined(QWEBENGINEPAGE_ERRORPAGEEXTENSION)
@@ -2800,50 +2789,16 @@ void tst_QWebEnginePage::errorPageExtensionLoadFinished()
#endif
}
-class FriendlyWebPage : public QWebEnginePage
-{
-public:
- friend class tst_QWebEnginePage;
-};
-
-void tst_QWebEnginePage::userAgentApplicationName()
+void tst_QWebEnginePage::userAgentNewlineStripping()
{
-#if !defined(QWEBENGINEPAGE_USERAGENTFORURL)
- QSKIP("QWEBENGINEPAGE_USERAGENTFORURL");
-#else
- const QString oldApplicationName = QCoreApplication::applicationName();
- FriendlyWebPage page;
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
- const QString applicationNameMarker = QString::fromUtf8("StrangeName\342\210\236");
- QCoreApplication::setApplicationName(applicationNameMarker);
- QVERIFY(page.userAgentForUrl(QUrl()).contains(applicationNameMarker));
+ profile.setHttpUserAgent(QStringLiteral("My User Agent\nX-New-Http-Header: Oh Noes!"));
+ // The user agent will be updated after a page load.
+ page.load(QUrl("about:blank"));
- QCoreApplication::setApplicationName(oldApplicationName);
-#endif
-}
-
-class CustomUserAgentWebPage : public QWebEnginePage
-{
-public:
- static const QLatin1String filteredUserAgent;
-protected:
- virtual QString userAgentForUrl(const QUrl& url) const
- {
- Q_UNUSED(url);
- return QString("My User Agent\nX-New-Http-Header: Oh Noes!");
- }
-};
-const QLatin1String CustomUserAgentWebPage::filteredUserAgent("My User AgentX-New-Http-Header: Oh Noes!");
-
-void tst_QWebEnginePage::userAgentNewlineStripping()
-{
-#if !defined(QWEBENGINEPAGE_USERAGENTFORURL)
- QSKIP("QWEBENGINEPAGE_USERAGENTFORURL");
-#else
- CustomUserAgentWebPage page;
- page.setHtml("<html><body></body></html>");
- QCOMPARE(evaluateJavaScriptSync(&page, "navigator.userAgent").toString(), CustomUserAgentWebPage::filteredUserAgent);
-#endif
+ QCOMPARE(evaluateJavaScriptSync(&page, "navigator.userAgent").toString(), QStringLiteral("My User Agent X-New-Http-Header: Oh Noes!"));
}
void tst_QWebEnginePage::crashTests_LazyInitializationOfMainFrame()
@@ -2951,65 +2906,6 @@ void tst_QWebEnginePage::unacceleratedWebGLScreenshotWithoutView()
}
#endif
-void tst_QWebEnginePage::originatingObjectInNetworkRequests()
-{
-#if !defined(QWEBENGINEFRAME)
- QSKIP("QWEBENGINEFRAME");
-#else
- TestNetworkManager* networkManager = new TestNetworkManager(m_page);
- m_page->setNetworkAccessManager(networkManager);
- networkManager->requests.clear();
-
- m_view->setHtml(QString("<frameset cols=\"25%,75%\"><frame src=\"data:text/html,"
- "<head><meta http-equiv='refresh' content='1'></head>foo \">"
- "<frame src=\"data:text/html,bar\"></frameset>"), QUrl());
- QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool))));
-
- QCOMPARE(networkManager->requests.count(), 2);
-
- QList<QWebEngineFrame*> childFrames = m_page->mainFrame()->childFrames();
- QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118660", Continue);
- QCOMPARE(childFrames.count(), 2);
-
- for (int i = 0; i < 2; ++i)
- QVERIFY(qobject_cast<QWebEngineFrame*>(networkManager->requests.at(i).originatingObject()) == childFrames.at(i));
-#endif
-}
-
-void tst_QWebEnginePage::networkReplyParentDidntChange()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- TestNetworkManager* networkManager = new TestNetworkManager(m_page);
- m_page->setNetworkAccessManager(networkManager);
- networkManager->requests.clear();
-
- // Trigger a load and check that pending QNetworkReplies haven't been reparented before returning to the event loop.
- m_view->load(QUrl("qrc:///resources/content.html"));
-
- QVERIFY(networkManager->requests.count() > 0);
- QVERIFY(networkManager->findChildren<QNetworkReply*>().size() > 0);
-#endif
-}
-
-void tst_QWebEnginePage::destroyQNAMBeforeAbortDoesntCrash()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- QNetworkAccessManager* networkManager = new QNetworkAccessManager;
- m_page->setNetworkAccessManager(networkManager);
-
- m_view->load(QUrl("qrc:///resources/content.html"));
- delete networkManager;
- // This simulates what PingLoader does with its QNetworkReply when it times out.
- // PingLoader isn't attached to a QWebEnginePage and can be kept alive
- // for 60000 seconds (~16.7 hours) to then cancel its ResourceHandle.
- m_view->stop();
-#endif
-}
-
/**
* Test fixups for https://bugs.webkit.org/show_bug.cgi?id=30914
*
@@ -3109,13 +3005,16 @@ void tst_QWebEnginePage::testStopScheduledPageRefresh()
void tst_QWebEnginePage::findText()
{
- m_view->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>"));
-#if defined(QWEBENGINEPAGE_TRIGGERACTION_SELECTALL)
+ QSignalSpy loadSpy(m_page, SIGNAL(loadFinished(bool)));
+ m_page->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>"));
+ QTRY_COMPARE(loadSpy.count(), 1);
m_page->triggerAction(QWebEnginePage::SelectAll);
- QVERIFY(!m_page->selectedText().isEmpty());
+ QTRY_COMPARE(m_page->hasSelection(), true);
+#if defined(QWEBENGINEPAGE_SELECTEDHTML)
QVERIFY(!m_page->selectedHtml().isEmpty());
#endif
m_page->findText("");
+ QEXPECT_FAIL("", "Unsupported: findText only highlights and doesn't update the selection.", Continue);
QVERIFY(m_page->selectedText().isEmpty());
#if defined(QWEBENGINEPAGE_SELECTEDHTML)
QVERIFY(m_page->selectedHtml().isEmpty());
@@ -3129,6 +3028,7 @@ void tst_QWebEnginePage::findText()
QVERIFY(m_page->selectedHtml().contains(subString));
#endif
m_page->findText("");
+ QEXPECT_FAIL("", "Unsupported: findText only highlights and doesn't update the selection.", Continue);
QVERIFY(m_page->selectedText().isEmpty());
#if defined(QWEBENGINEPAGE_SELECTEDHTML)
QVERIFY(m_page->selectedHtml().isEmpty());
@@ -3674,41 +3574,115 @@ void tst_QWebEnginePage::cssMediaTypePageSetting()
#endif
}
-class JavaScriptCallback
+class JavaScriptCallbackBase
+{
+public:
+ JavaScriptCallbackBase()
+ {
+ if (watcher)
+ QMetaObject::invokeMethod(watcher, "add");
+ }
+
+ void operator() (const QVariant &result)
+ {
+ check(result);
+ if (watcher)
+ QMetaObject::invokeMethod(watcher, "notify");
+ }
+
+protected:
+ virtual void check(const QVariant &result) = 0;
+
+private:
+ friend class JavaScriptCallbackWatcher;
+ static QPointer<QObject> watcher;
+};
+
+QPointer<QObject> JavaScriptCallbackBase::watcher = 0;
+
+class JavaScriptCallback : public JavaScriptCallbackBase
{
public:
JavaScriptCallback() { }
JavaScriptCallback(const QVariant& _expected) : expected(_expected) { }
- virtual void operator() (const QVariant& result) {
+
+ void check(const QVariant& result) Q_DECL_OVERRIDE
+ {
QVERIFY(result.isValid());
QCOMPARE(result, expected);
}
+
private:
QVariant expected;
};
-class JavaScriptCallbackNull
+class JavaScriptCallbackNull : public JavaScriptCallbackBase
{
public:
- virtual void operator() (const QVariant& result) {
+ void check(const QVariant& result) Q_DECL_OVERRIDE
+ {
QVERIFY(result.isNull());
// FIXME: Returned null values are currently invalid QVariants.
// QVERIFY(result.isValid());
}
};
-class JavaScriptCallbackUndefined
+class JavaScriptCallbackUndefined : public JavaScriptCallbackBase
{
public:
- virtual void operator() (const QVariant& result) {
+ void check(const QVariant& result) Q_DECL_OVERRIDE
+ {
QVERIFY(result.isNull());
QVERIFY(!result.isValid());
}
};
+class JavaScriptCallbackWatcher : public QObject
+{
+ Q_OBJECT
+public:
+ JavaScriptCallbackWatcher()
+ {
+ Q_ASSERT(!JavaScriptCallbackBase::watcher);
+ JavaScriptCallbackBase::watcher = this;
+ }
+
+ Q_INVOKABLE void add()
+ {
+ available++;
+ }
+
+ Q_INVOKABLE void notify()
+ {
+ called++;
+ if (called == available)
+ emit allCalled();
+ }
+
+ bool wait(int maxSeconds = 30)
+ {
+ if (called == available)
+ return true;
+
+ QTestEventLoop loop;
+ connect(this, SIGNAL(allCalled()), &loop, SLOT(exitLoop()));
+ loop.enterLoop(maxSeconds);
+ return !loop.timeout();
+ }
+
+signals:
+ void allCalled();
+
+private:
+ int available = 0;
+ int called = 0;
+};
+
+
void tst_QWebEnginePage::runJavaScript()
{
TestPage page;
+ JavaScriptCallbackWatcher watcher;
JavaScriptCallback callbackBool(QVariant(false));
page.runJavaScript("false", QWebEngineCallback<const QVariant&>(callbackBool));
@@ -3734,10 +3708,1363 @@ void tst_QWebEnginePage::runJavaScript()
JavaScriptCallbackNull callbackNull;
page.runJavaScript("null", QWebEngineCallback<const QVariant&>(callbackNull));
- JavaScriptCallbackNull callbackUndefined;
+ JavaScriptCallbackUndefined callbackUndefined;
page.runJavaScript("undefined", QWebEngineCallback<const QVariant&>(callbackUndefined));
+ QVERIFY(watcher.wait());
+}
+
+void tst_QWebEnginePage::fullScreenRequested()
+{
+ JavaScriptCallbackWatcher watcher;
+ QWebEnginePage* page = new QWebEnginePage;
+ QWebEngineView* view = new QWebEngineView;
+ view->setPage(page);
+ view->show();
+
+ page->settings()->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true);
+
+ QSignalSpy loadSpy(view, SIGNAL(loadFinished(bool)));
+ page->load(QUrl("qrc:///resources/fullscreen.html"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ page->runJavaScript("document.webkitFullscreenEnabled", JavaScriptCallback(true));
+ page->runJavaScript("document.webkitIsFullScreen", JavaScriptCallback(false));
+ QVERIFY(watcher.wait());
+
+ // FullscreenRequest must be a user gesture
+ bool acceptRequest = true;
+ connect(page, &QWebEnginePage::fullScreenRequested,
+ [&acceptRequest](const QWebEngineFullScreenRequest &request) {
+ if (acceptRequest) request.accept(); else request.reject();
+ });
+
+ QTest::keyPress(qApp->focusWindow(), Qt::Key_Space);
+ QTest::qWait(100);
+ page->runJavaScript("document.webkitIsFullScreen", JavaScriptCallback(true));
+ page->runJavaScript("document.webkitExitFullscreen()", JavaScriptCallbackUndefined());
+ QVERIFY(watcher.wait());
+
+ acceptRequest = false;
+
+ page->runJavaScript("document.webkitFullscreenEnabled", JavaScriptCallback(true));
+ QTest::keyPress(qApp->focusWindow(), Qt::Key_Space);
+ QVERIFY(watcher.wait());
+ page->runJavaScript("document.webkitIsFullScreen", JavaScriptCallback(false));
+ QVERIFY(watcher.wait());
+
+ delete view;
+ delete page;
+}
+
+void tst_QWebEnginePage::symmetricUrl()
+{
+ QWebEngineView view;
+ QSignalSpy loadFinishedSpy(view.page(), SIGNAL(loadFinished(bool)));
+
+ QVERIFY(view.url().isEmpty());
+
+ QCOMPARE(view.history()->count(), 0);
+
+ QUrl dataUrl("data:text/html,<h1>Test");
+
+ view.setUrl(dataUrl);
+ QCOMPARE(view.url(), dataUrl);
+ QCOMPARE(view.history()->count(), 0);
+
+ // loading is _not_ immediate, so the text isn't set just yet.
+ QVERIFY(toPlainTextSync(view.page()).isEmpty());
+
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+
+ QCOMPARE(view.history()->count(), 1);
+ QCOMPARE(toPlainTextSync(view.page()), QString("Test"));
+
+ QUrl dataUrl2("data:text/html,<h1>Test2");
+ QUrl dataUrl3("data:text/html,<h1>Test3");
+
+ view.setUrl(dataUrl2);
+ view.setUrl(dataUrl3);
+
+ QCOMPARE(view.url(), dataUrl3);
+
+ QTRY_VERIFY(loadFinishedSpy.count() >= 2);
+ QTRY_COMPARE(loadFinishedSpy.count(), 3);
+
+ QCOMPARE(view.history()->count(), 2);
+
+ QCOMPARE(toPlainTextSync(view.page()), QString("Test3"));
+}
+
+void tst_QWebEnginePage::progressSignal()
+{
+ QSignalSpy progressSpy(m_view, SIGNAL(loadProgress(int)));
+
+ QUrl dataUrl("data:text/html,<h1>Test");
+ m_view->setUrl(dataUrl);
+
+ ::waitForSignal(m_view, SIGNAL(loadFinished(bool)));
+
+ QVERIFY(progressSpy.size() >= 2);
+ int previousValue = -1;
+ for (QSignalSpy::ConstIterator it = progressSpy.begin(); it < progressSpy.end(); ++it) {
+ int current = (*it).first().toInt();
+ QVERIFY(current >= previousValue);
+ previousValue = current;
+ }
+
+ // But we always end at 100%
+ QCOMPARE(progressSpy.last().first().toInt(), 100);
+}
+
+void tst_QWebEnginePage::urlChange()
+{
+ QSignalSpy urlSpy(m_page, SIGNAL(urlChanged(QUrl)));
+
+ QUrl dataUrl("data:text/html,<h1>Test");
+ m_view->setUrl(dataUrl);
+
+ ::waitForSignal(m_page, SIGNAL(urlChanged(QUrl)));
+
+ QCOMPARE(urlSpy.size(), 1);
+
+ QUrl dataUrl2("data:text/html,<html><head><title>title</title></head><body><h1>Test</body></html>");
+ m_view->setUrl(dataUrl2);
+
+ ::waitForSignal(m_page, SIGNAL(urlChanged(QUrl)));
+
+ QCOMPARE(urlSpy.size(), 2);
+}
+
+class FakeReply : public QNetworkReply {
+ Q_OBJECT
+
+public:
+ static const QUrl urlFor404ErrorWithoutContents;
+
+ FakeReply(const QNetworkRequest& request, QObject* parent = 0)
+ : QNetworkReply(parent)
+ {
+ setOperation(QNetworkAccessManager::GetOperation);
+ setRequest(request);
+ setUrl(request.url());
+ if (request.url() == QUrl("qrc:/test1.html")) {
+ setHeader(QNetworkRequest::LocationHeader, QString("qrc:/test2.html"));
+ setAttribute(QNetworkRequest::RedirectionTargetAttribute, QUrl("qrc:/test2.html"));
+ QTimer::singleShot(0, this, SLOT(continueRedirect()));
+ }
+#ifndef QT_NO_OPENSSL
+ else if (request.url() == QUrl("qrc:/fake-ssl-error.html")) {
+ setError(QNetworkReply::SslHandshakeFailedError, tr("Fake error!"));
+ QTimer::singleShot(0, this, SLOT(continueError()));
+ }
+#endif
+ else if (request.url().host() == QLatin1String("abcdef.abcdef")) {
+ setError(QNetworkReply::HostNotFoundError, tr("Invalid URL"));
+ QTimer::singleShot(0, this, SLOT(continueError()));
+ } else if (request.url() == FakeReply::urlFor404ErrorWithoutContents) {
+ setError(QNetworkReply::ContentNotFoundError, "Not found");
+ setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 404);
+ QTimer::singleShot(0, this, SLOT(continueError()));
+ }
+
+ open(QIODevice::ReadOnly);
+ }
+ ~FakeReply()
+ {
+ close();
+ }
+ virtual void abort() {}
+ virtual void close() {}
+
+protected:
+ qint64 readData(char*, qint64)
+ {
+ return 0;
+ }
+
+private Q_SLOTS:
+ void continueRedirect()
+ {
+ emit metaDataChanged();
+ emit finished();
+ }
+
+ void continueError()
+ {
+ emit error(this->error());
+ emit finished();
+ }
+};
+
+const QUrl FakeReply::urlFor404ErrorWithoutContents = QUrl("http://this.will/return-http-404-error-without-contents.html");
+
+class FakeNetworkManager : public QNetworkAccessManager {
+ Q_OBJECT
+
+public:
+ FakeNetworkManager(QObject* parent) : QNetworkAccessManager(parent) { }
+
+protected:
+ virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest& request, QIODevice* outgoingData)
+ {
+ QString url = request.url().toString();
+ if (op == QNetworkAccessManager::GetOperation) {
+#ifndef QT_NO_OPENSSL
+ if (url == "qrc:/fake-ssl-error.html") {
+ FakeReply* reply = new FakeReply(request, this);
+ QList<QSslError> errors;
+ emit sslErrors(reply, errors << QSslError(QSslError::UnspecifiedError));
+ return reply;
+ }
+#endif
+ if (url == "qrc:/test1.html" || url == "http://abcdef.abcdef/" || request.url() == FakeReply::urlFor404ErrorWithoutContents)
+ return new FakeReply(request, this);
+ }
+
+ return QNetworkAccessManager::createRequest(op, request, outgoingData);
+ }
+};
+
+void tst_QWebEnginePage::requestedUrlAfterSetAndLoadFailures()
+{
+ QWebEnginePage page;
+ page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+
+ const QUrl first("http://abcdef.abcdef/");
+ page.setUrl(first);
+ ::waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(page.url(), first);
+ QCOMPARE(page.requestedUrl(), first);
+ QVERIFY(!spy.at(0).first().toBool());
+
+ const QUrl second("http://abcdef.abcdef/another_page.html");
+ QVERIFY(first != second);
+
+ page.load(second);
+ ::waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QCOMPARE(spy.count(), 2);
+ QCOMPARE(page.url(), first);
+ QCOMPARE(page.requestedUrl(), second);
+ QVERIFY(!spy.at(1).first().toBool());
+}
+
+void tst_QWebEnginePage::javaScriptWindowObjectCleared_data()
+{
+ QTest::addColumn<QString>("html");
+ QTest::addColumn<int>("signalCount");
+ QTest::newRow("with <script>") << "<html><body><script>i=0</script><p>hello world</p></body></html>" << 1;
+ // NOTE: Empty scripts no longer cause this signal to be emitted.
+ QTest::newRow("with empty <script>") << "<html><body><script></script><p>hello world</p></body></html>" << 0;
+ QTest::newRow("without <script>") << "<html><body><p>hello world</p></body></html>" << 0;
+}
+
+void tst_QWebEnginePage::javaScriptWindowObjectCleared()
+{
+#if !defined(QWEBENGINEPAGE_JAVASCRIPTWINDOWOBJECTCLEARED)
+ QSKIP("QWEBENGINEPAGE_JAVASCRIPTWINDOWOBJECTCLEARED");
+#else
+ QWebEnginePage page;
+ QSignalSpy spy(&page, SIGNAL(javaScriptWindowObjectCleared()));
+ QFETCH(QString, html);
+ page.setHtml(html);
+
+ QFETCH(int, signalCount);
+ QCOMPARE(spy.count(), signalCount);
+#endif
+}
+
+void tst_QWebEnginePage::javaScriptWindowObjectClearedOnEvaluate()
+{
+#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
+ QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
+#else
+ QWebEnginePage page;
+ QSignalSpy spy(&page, SIGNAL(javaScriptWindowObjectCleared()));
+ page.setHtml("<html></html>");
+ QCOMPARE(spy.count(), 0);
+ page.evaluateJavaScript("var a = 'a';");
+ QCOMPARE(spy.count(), 1);
+ // no new clear for a new script:
+ page.evaluateJavaScript("var a = 1;");
+ QCOMPARE(spy.count(), 1);
+#endif
+}
+
+void tst_QWebEnginePage::asyncAndDelete()
+{
+ QWebEnginePage *page = new QWebEnginePage;
+ CallbackSpy<QString> plainTextSpy;
+ CallbackSpy<QString> htmlSpy;
+ page->toPlainText(plainTextSpy.ref());
+ page->toHtml(htmlSpy.ref());
+
+ delete page;
+ // Pending callbacks should be called with an empty value in the page's destructor.
+ QCOMPARE(plainTextSpy.waitForResult(), QString());
+ QVERIFY(plainTextSpy.wasCalled());
+ QCOMPARE(htmlSpy.waitForResult(), QString());
+ QVERIFY(htmlSpy.wasCalled());
+}
+
+void tst_QWebEnginePage::earlyToHtml()
+{
+ QString html("<html><head></head><body></body></html>");
+ QCOMPARE(toHtmlSync(m_view->page()), html);
+}
+
+void tst_QWebEnginePage::setHtml()
+{
+ QString html("<html><head></head><body><p>hello world</p></body></html>");
+ QSignalSpy spy(m_view->page(), SIGNAL(loadFinished(bool)));
+ m_view->page()->setHtml(html);
+ QVERIFY(spy.wait());
+ QCOMPARE(toHtmlSync(m_view->page()), html);
+}
+
+void tst_QWebEnginePage::setHtmlWithImageResource()
+{
+ // By default, only security origins of local files can load local resources.
+ // So we should specify baseUrl to be a local file in order to get a proper origin and load the local image.
+
+ QLatin1String html("<html><body><p>hello world</p><img src='qrc:/resources/image.png'/></body></html>");
+ QWebEnginePage page;
+
+ page.setHtml(html, QUrl(QLatin1String("file:///path/to/file")));
+ waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
+
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 128);
+
+ // Now we test the opposite: without a baseUrl as a local file, we cannot request local resources.
+
+ page.setHtml(html);
+ waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
+ QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118659", Continue);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 0);
+ QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118659", Continue);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 0);
+}
+
+void tst_QWebEnginePage::setHtmlWithStylesheetResource()
+{
+#if !defined(QWEBENGINEELEMENT)
+ QSKIP("QWEBENGINEELEMENT");
+#else
+ // By default, only security origins of local files can load local resources.
+ // So we should specify baseUrl to be a local file in order to be able to download the local stylesheet.
+
+ const char* htmlData =
+ "<html>"
+ "<head>"
+ "<link rel='stylesheet' href='qrc:/style.css' type='text/css' />"
+ "</head>"
+ "<body>"
+ "<p id='idP'>some text</p>"
+ "</body>"
+ "</html>";
+ QLatin1String html(htmlData);
+ QWebEnginePage page;
+ QWebEngineElement webElement;
+
+ page.setHtml(html, QUrl(QLatin1String("qrc:///file")));
+ waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
+ webElement = page.documentElement().findFirst("p");
+ QCOMPARE(webElement.styleProperty("color", QWebEngineElement::CascadedStyle), QLatin1String("red"));
+
+ // Now we test the opposite: without a baseUrl as a local file, we cannot request local resources.
+
+ page.setHtml(html, QUrl(QLatin1String("http://www.example.com/")));
+ waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
+ webElement = page.documentElement().findFirst("p");
+ QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118659", Continue);
+ QCOMPARE(webElement.styleProperty("color", QWebEngineElement::CascadedStyle), QString());
+#endif
+}
+
+void tst_QWebEnginePage::setHtmlWithBaseURL()
+{
+ // This tests if baseUrl is indeed affecting the relative paths from resources.
+ // As we are using a local file as baseUrl, its security origin should be able to load local resources.
+
+ if (!QDir(TESTS_SOURCE_DIR).exists())
+ W_QSKIP(QString("This test requires access to resources found in '%1'").arg(TESTS_SOURCE_DIR).toLatin1().constData(), SkipAll);
+
+ QDir::setCurrent(TESTS_SOURCE_DIR);
+
+ QString html("<html><body><p>hello world</p><img src='resources/image2.png'/></body></html>");
+
+ QWebEnginePage page;
+
+ // in few seconds, the image should be completey loaded
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+
+ page.setHtml(html, QUrl::fromLocalFile(TESTS_SOURCE_DIR));
+ waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
+ QCOMPARE(spy.count(), 1);
+
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 128);
+
+ // no history item has to be added.
+ QCOMPARE(m_view->page()->history()->count(), 0);
+}
+
+class MyPage : public QWebEnginePage
+{
+public:
+ MyPage() : QWebEnginePage(), alerts(0) {}
+ int alerts;
+
+protected:
+ virtual void javaScriptAlert(const QUrl &securityOrigin, const QString &msg)
+ {
+ alerts++;
+ QCOMPARE(securityOrigin, QUrl(QStringLiteral("http://test.origin.com/")));
+ QCOMPARE(msg, QString("foo"));
+ }
+};
+
+void tst_QWebEnginePage::setHtmlWithJSAlert()
+{
+ QString html("<html><head></head><body><script>alert('foo');</script><p>hello world</p></body></html>");
+ MyPage page;
+ page.setHtml(html, QUrl(QStringLiteral("http://test.origin.com/path#fragment")));
+ waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QCOMPARE(page.alerts, 1);
+ QCOMPARE(toHtmlSync(&page), html);
+}
+
+void tst_QWebEnginePage::metaData()
+{
+#if !defined(QWEBENGINEPAGE_METADATA)
+ QSKIP("QWEBENGINEPAGE_METADATA");
+#else
+ m_view->setHtml("<html>"
+ " <head>"
+ " <meta name=\"description\" content=\"Test description\">"
+ " <meta name=\"keywords\" content=\"HTML, JavaScript, Css\">"
+ " </head>"
+ "</html>");
+
+ QMultiMap<QString, QString> metaData = m_view->page()->metaData();
+
+ QCOMPARE(metaData.count(), 2);
+
+ QCOMPARE(metaData.value("description"), QString("Test description"));
+ QCOMPARE(metaData.value("keywords"), QString("HTML, JavaScript, Css"));
+ QCOMPARE(metaData.value("nonexistent"), QString());
+
+ m_view->setHtml("<html>"
+ " <head>"
+ " <meta name=\"samekey\" content=\"FirstValue\">"
+ " <meta name=\"samekey\" content=\"SecondValue\">"
+ " </head>"
+ "</html>");
+
+ metaData = m_view->page()->metaData();
+
+ QCOMPARE(metaData.count(), 2);
+
+ QStringList values = metaData.values("samekey");
+ QCOMPARE(values.count(), 2);
+
+ QVERIFY(values.contains("FirstValue"));
+ QVERIFY(values.contains("SecondValue"));
+
+ QCOMPARE(metaData.value("nonexistent"), QString());
+#endif
+}
+
+#if !defined(QT_NO_COMBOBOX)
+void tst_QWebEnginePage::popupFocus()
+{
+#if !defined(QWEBENGINEELEMENT)
+ QSKIP("QWEBENGINEELEMENT");
+#else
+ QWebEngineView view;
+ view.setHtml("<html>"
+ " <body>"
+ " <select name=\"select\">"
+ " <option>1</option>"
+ " <option>2</option>"
+ " </select>"
+ " <input type=\"text\"> </input>"
+ " <textarea name=\"text_area\" rows=\"3\" cols=\"40\">"
+ "This test checks whether showing and hiding a popup"
+ "takes the focus away from the webpage."
+ " </textarea>"
+ " </body>"
+ "</html>");
+ view.resize(400, 100);
+ // Call setFocus before show to work around http://bugreports.qt.nokia.com/browse/QTBUG-14762
+ view.setFocus();
+ view.show();
+ QTest::qWaitForWindowExposed(&view);
+ view.activateWindow();
+ QTRY_VERIFY(view.hasFocus());
+
+ // open the popup by clicking. check if focus is on the popup
+ const QWebEngineElement webCombo = view.page()->documentElement().findFirst(QLatin1String("select[name=select]"));
+ QTest::mouseClick(&view, Qt::LeftButton, 0, webCombo.geometry().center());
+
+ QComboBox* combo = view.findChild<QComboBox*>();
+ QVERIFY(combo != 0);
+ QTRY_VERIFY(!view.hasFocus() && combo->view()->hasFocus()); // Focus should be on the popup
+
+ // hide the popup and check if focus is on the page
+ combo->hidePopup();
+ QTRY_VERIFY(view.hasFocus()); // Focus should be back on the WebView
+#endif
+}
+#endif
+
+void tst_QWebEnginePage::inputFieldFocus()
+{
+#if !defined(QWEBENGINEELEMENT)
+ QSKIP("QWEBENGINEELEMENT");
+#else
+ QWebEngineView view;
+ view.setHtml("<html><body><input type=\"text\"></input></body></html>");
+ view.resize(400, 100);
+ view.show();
+ QTest::qWaitForWindowExposed(&view);
+ view.activateWindow();
+ view.setFocus();
+ QTRY_VERIFY(view.hasFocus());
+
+ // double the flashing time, should at least blink once already
+ int delay = qApp->cursorFlashTime() * 2;
+
+ // focus the lineedit and check if it blinks
+ bool autoSipEnabled = qApp->autoSipEnabled();
+ qApp->setAutoSipEnabled(false);
+ const QWebEngineElement inputElement = view.page()->documentElement().findFirst(QLatin1String("input[type=text]"));
+ QTest::mouseClick(&view, Qt::LeftButton, 0, inputElement.geometry().center());
+ m_inputFieldsTestView = &view;
+ view.installEventFilter( this );
+ QTest::qWait(delay);
+ QVERIFY2(m_inputFieldTestPaintCount >= 3,
+ "The input field should have a blinking caret");
+ qApp->setAutoSipEnabled(autoSipEnabled);
+#endif
+}
+
+void tst_QWebEnginePage::hitTestContent()
+{
+#if !defined(QWEBENGINEELEMENT)
+ QSKIP("QWEBENGINEELEMENT");
+#else
+ QString html("<html><body><p>A paragraph</p><br/><br/><br/><a href=\"about:blank\" target=\"_foo\" id=\"link\">link text</a></body></html>");
+
+ QWebEnginePage page;
+ page.setHtml(html);
+ page.setViewportSize(QSize(200, 0)); //no height so link is not visible
+ const QWebEngineElement linkElement = page.documentElement().findFirst(QLatin1String("a#link"));
+ QWebEngineHitTestResult result = page.hitTestContent(linkElement.geometry().center());
+ QCOMPARE(result.linkText(), QString("link text"));
+ QWebEngineElement link = result.linkElement();
+ QCOMPARE(link.attribute("target"), QString("_foo"));
+#endif
+}
+
+void tst_QWebEnginePage::baseUrl_data()
+{
+ QTest::addColumn<QString>("html");
+ QTest::addColumn<QUrl>("loadUrl");
+ QTest::addColumn<QUrl>("url");
+ QTest::addColumn<QUrl>("baseUrl");
+
+ QTest::newRow("null") << QString() << QUrl()
+ << QUrl("about:blank") << QUrl("about:blank");
+
+ QTest::newRow("foo") << QString() << QUrl("http://foobar.baz/")
+ << QUrl("http://foobar.baz/") << QUrl("http://foobar.baz/");
+
+ QString html = "<html>"
+ "<head>"
+ "<base href=\"http://foobaz.bar/\" />"
+ "</head>"
+ "</html>";
+ QTest::newRow("customBaseUrl") << html << QUrl("http://foobar.baz/")
+ << QUrl("http://foobar.baz/") << QUrl("http://foobaz.bar/");
+}
+
+void tst_QWebEnginePage::baseUrl()
+{
+ QFETCH(QString, html);
+ QFETCH(QUrl, loadUrl);
+ QFETCH(QUrl, url);
+ QFETCH(QUrl, baseUrl);
+
+ QSignalSpy loadSpy(m_page, SIGNAL(loadFinished(bool)));
+ m_page->setHtml(html, loadUrl);
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(m_page->url(), url);
+ QEXPECT_FAIL("null", "Slight change: We now translate QUrl() to about:blank for the virtual url, but not for the baseUrl", Continue);
+ QCOMPARE(baseUrlSync(m_page), baseUrl);
+}
+
+class DummyPaintEngine: public QPaintEngine {
+public:
+
+ DummyPaintEngine()
+ : QPaintEngine(QPaintEngine::AllFeatures)
+ , renderHints(0)
+ {
+ }
+
+ bool begin(QPaintDevice*)
+ {
+ setActive(true);
+ return true;
+ }
+
+ bool end()
+ {
+ setActive(false);
+ return false;
+ }
+
+ void updateState(const QPaintEngineState& state)
+ {
+ renderHints = state.renderHints();
+ }
+
+ void drawPath(const QPainterPath&) { }
+ void drawPixmap(const QRectF&, const QPixmap&, const QRectF&) { }
+
+ QPaintEngine::Type type() const
+ {
+ return static_cast<QPaintEngine::Type>(QPaintEngine::User + 2);
+ }
+
+ QPainter::RenderHints renderHints;
+};
+
+class DummyPaintDevice: public QPaintDevice {
+public:
+ DummyPaintDevice()
+ : QPaintDevice()
+ , m_engine(new DummyPaintEngine)
+ {
+ }
+
+ ~DummyPaintDevice()
+ {
+ delete m_engine;
+ }
+
+ QPaintEngine* paintEngine() const
+ {
+ return m_engine;
+ }
+
+ QPainter::RenderHints renderHints() const
+ {
+ return m_engine->renderHints;
+ }
+
+protected:
+ int metric(PaintDeviceMetric metric) const;
+
+private:
+ DummyPaintEngine* m_engine;
+ friend class DummyPaintEngine;
+};
+
+
+int DummyPaintDevice::metric(PaintDeviceMetric metric) const
+{
+ switch (metric) {
+ case PdmWidth:
+ return 400;
+ break;
+
+ case PdmHeight:
+ return 200;
+ break;
+
+ case PdmNumColors:
+ return INT_MAX;
+ break;
+
+ case PdmDepth:
+ return 32;
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+void tst_QWebEnginePage::renderHints()
+{
+#if !defined(QWEBENGINEPAGE_RENDER)
+ QSKIP("QWEBENGINEPAGE_RENDER");
+#else
+ QString html("<html><body><p>Hello, world!</p></body></html>");
+
+ QWebEnginePage page;
+ page.setHtml(html);
+ page.setViewportSize(page.contentsSize());
+
+ // We will call frame->render and trap the paint engine state changes
+ // to ensure that GraphicsContext does not clobber the render hints.
+ DummyPaintDevice buffer;
+ QPainter painter(&buffer);
+
+ painter.setRenderHint(QPainter::TextAntialiasing, false);
+ page.render(&painter);
+ QVERIFY(!(buffer.renderHints() & QPainter::TextAntialiasing));
+ QVERIFY(!(buffer.renderHints() & QPainter::SmoothPixmapTransform));
+ QVERIFY(!(buffer.renderHints() & QPainter::HighQualityAntialiasing));
+
+ painter.setRenderHint(QPainter::TextAntialiasing, true);
+ page.render(&painter);
+ QVERIFY(buffer.renderHints() & QPainter::TextAntialiasing);
+ QVERIFY(!(buffer.renderHints() & QPainter::SmoothPixmapTransform));
+ QVERIFY(!(buffer.renderHints() & QPainter::HighQualityAntialiasing));
+
+ painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
+ page.render(&painter);
+ QVERIFY(buffer.renderHints() & QPainter::TextAntialiasing);
+ QVERIFY(buffer.renderHints() & QPainter::SmoothPixmapTransform);
+ QVERIFY(!(buffer.renderHints() & QPainter::HighQualityAntialiasing));
+
+ painter.setRenderHint(QPainter::HighQualityAntialiasing, true);
+ page.render(&painter);
+ QVERIFY(buffer.renderHints() & QPainter::TextAntialiasing);
+ QVERIFY(buffer.renderHints() & QPainter::SmoothPixmapTransform);
+ QVERIFY(buffer.renderHints() & QPainter::HighQualityAntialiasing);
+#endif
+}
+
+void tst_QWebEnginePage::scrollPosition()
+{
+#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
+ QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
+#else
+ // enlarged image in a small viewport, to provoke the scrollbars to appear
+ QString html("<html><body><img src='qrc:/image.png' height=500 width=500/></body></html>");
+
+ QWebEnginePage page;
+ page.setViewportSize(QSize(200, 200));
+
+ page.setHtml(html);
+ page.setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
+ page.setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
+
+ // try to set the scroll offset programmatically
+ page.setScrollPosition(QPoint(23, 29));
+ QCOMPARE(page.scrollPosition().x(), 23);
+ QCOMPARE(page.scrollPosition().y(), 29);
+
+ int x = page.evaluateJavaScript("window.scrollX").toInt();
+ int y = page.evaluateJavaScript("window.scrollY").toInt();
+ QCOMPARE(x, 23);
+ QCOMPARE(y, 29);
+#endif
+}
+
+void tst_QWebEnginePage::scrollToAnchor()
+{
+#if !defined(QWEBENGINEELEMENT)
+ QSKIP("QWEBENGINEELEMENT");
+#else
+ QWebEnginePage page;
+ page.setViewportSize(QSize(480, 800));
+
+ QString html("<html><body><p style=\"margin-bottom: 1500px;\">Hello.</p>"
+ "<p><a id=\"foo\">This</a> is an anchor</p>"
+ "<p style=\"margin-bottom: 1500px;\"><a id=\"bar\">This</a> is another anchor</p>"
+ "</body></html>");
+ page.setHtml(html);
+ page.setScrollPosition(QPoint(0, 0));
+ QCOMPARE(page.scrollPosition().x(), 0);
+ QCOMPARE(page.scrollPosition().y(), 0);
+
+ QWebEngineElement fooAnchor = page.findFirstElement("a[id=foo]");
+
+ page.scrollToAnchor("foo");
+ QCOMPARE(page.scrollPosition().y(), fooAnchor.geometry().top());
+
+ page.scrollToAnchor("bar");
+ page.scrollToAnchor("foo");
+ QCOMPARE(page.scrollPosition().y(), fooAnchor.geometry().top());
+
+ page.scrollToAnchor("top");
+ QCOMPARE(page.scrollPosition().y(), 0);
+
+ page.scrollToAnchor("bar");
+ page.scrollToAnchor("notexist");
+ QVERIFY(page.scrollPosition().y() != 0);
+#endif
+}
+
+
+void tst_QWebEnginePage::scrollbarsOff()
+{
+#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
+ QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
+#else
+ QWebEngineView view;
+ QWebEngineFrame* mainFrame = view.page();
+
+ mainFrame->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
+ mainFrame->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
+
+ QString html("<script>" \
+ " function checkScrollbar() {" \
+ " if (innerWidth === document.documentElement.offsetWidth)" \
+ " document.getElementById('span1').innerText = 'SUCCESS';" \
+ " else" \
+ " document.getElementById('span1').innerText = 'FAIL';" \
+ " }" \
+ "</script>" \
+ "<body>" \
+ " <div style='margin-top:1000px ; margin-left:1000px'>" \
+ " <a id='offscreen' href='a'>End</a>" \
+ " </div>" \
+ "<span id='span1'></span>" \
+ "</body>");
+
+
+ QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
+ view.setHtml(html);
+ ::waitForSignal(&view, SIGNAL(loadFinished(bool)), 200);
+ QCOMPARE(loadSpy.count(), 1);
+
+ mainFrame->evaluateJavaScript("checkScrollbar();");
+ QCOMPARE(mainFrame->documentElement().findAll("span").at(0).toPlainText(), QString("SUCCESS"));
+#endif
+}
+
+void tst_QWebEnginePage::horizontalScrollAfterBack()
+{
+#if !defined(QWEBENGINESETTINGS)
+ QSKIP("QWEBENGINESETTINGS");
+#else
+ QWebEngineView view;
+ QSignalSpy loadSpy(view.page(), SIGNAL(loadFinished(bool)));
+
+ view.page()->settings()->setMaximumPagesInCache(2);
+ view.page()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAsNeeded);
+ view.page()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAsNeeded);
+
+ view.load(QUrl("qrc:/resources/testiframe2.html"));
+ view.resize(200, 200);
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_VERIFY((view.page()->scrollBarGeometry(Qt::Horizontal)).height());
+
+ view.load(QUrl("qrc:/resources/testiframe.html"));
+ QTRY_COMPARE(loadSpy.count(), 2);
+
+ view.page()->triggerAction(QWebEnginePage::Back);
+ QTRY_COMPARE(loadSpy.count(), 3);
+ QTRY_VERIFY((view.page()->scrollBarGeometry(Qt::Horizontal)).height());
+#endif
+}
+
+void tst_QWebEnginePage::evaluateWillCauseRepaint()
+{
+#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
+ QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
+#else
+ QWebEngineView view;
+ QString html("<html><body>top<div id=\"junk\" style=\"display: block;\">"
+ "junk</div>bottom</body></html>");
+ view.setHtml(html);
+ view.show();
+
+ QTest::qWaitForWindowExposed(&view);
+ view.page()->evaluateJavaScript(
+ "document.getElementById('junk').style.display = 'none';");
+
+ ::waitForSignal(view.page(), SIGNAL(repaintRequested(QRect)));
+#endif
+}
+
+void tst_QWebEnginePage::setContent_data()
+{
+ QTest::addColumn<QString>("mimeType");
+ QTest::addColumn<QByteArray>("testContents");
+ QTest::addColumn<QString>("expected");
+
+ QString str = QString::fromUtf8("ὕαλον ϕαγεῖν δύναμαι· τοῦτο οὔ με βλάπτει");
+ QTest::newRow("UTF-8 plain text") << "text/plain; charset=utf-8" << str.toUtf8() << str;
+
+ QTextCodec *utf16 = QTextCodec::codecForName("UTF-16");
+ if (utf16)
+ QTest::newRow("UTF-16 plain text") << "text/plain; charset=utf-16" << utf16->fromUnicode(str) << str;
+
+ str = QString::fromUtf8("Une chaîne de caractères à sa façon.");
+ QTest::newRow("latin-1 plain text") << "text/plain; charset=iso-8859-1" << str.toLatin1() << str;
+
+
+}
+
+void tst_QWebEnginePage::setContent()
+{
+ QFETCH(QString, mimeType);
+ QFETCH(QByteArray, testContents);
+ QFETCH(QString, expected);
+ QSignalSpy loadSpy(m_page, SIGNAL(loadFinished(bool)));
+ m_view->setContent(testContents, mimeType);
+ QVERIFY(loadSpy.wait());
+ QCOMPARE(toPlainTextSync(m_view->page()), expected);
+}
+
+class CacheNetworkAccessManager : public QNetworkAccessManager {
+public:
+ CacheNetworkAccessManager(QObject* parent = 0)
+ : QNetworkAccessManager(parent)
+ , m_lastCacheLoad(QNetworkRequest::PreferNetwork)
+ {
+ }
+
+ virtual QNetworkReply* createRequest(Operation, const QNetworkRequest& request, QIODevice*)
+ {
+ QVariant cacheLoad = request.attribute(QNetworkRequest::CacheLoadControlAttribute);
+ if (cacheLoad.isValid())
+ m_lastCacheLoad = static_cast<QNetworkRequest::CacheLoadControl>(cacheLoad.toUInt());
+ else
+ m_lastCacheLoad = QNetworkRequest::PreferNetwork; // default value
+ return new FakeReply(request, this);
+ }
+
+ QNetworkRequest::CacheLoadControl lastCacheLoad() const
+ {
+ return m_lastCacheLoad;
+ }
+
+private:
+ QNetworkRequest::CacheLoadControl m_lastCacheLoad;
+};
+
+void tst_QWebEnginePage::setCacheLoadControlAttribute()
+{
+#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
+ QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
+#else
+ QWebEnginePage page;
+ CacheNetworkAccessManager* manager = new CacheNetworkAccessManager(&page);
+ page.setNetworkAccessManager(manager);
+
+ QNetworkRequest request(QUrl("http://abcdef.abcdef/"));
+
+ request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache);
+ page.load(request);
+ QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::AlwaysCache);
+
+ request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
+ page.load(request);
+ QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::PreferCache);
+
+ request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
+ page.load(request);
+ QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::AlwaysNetwork);
+
+ request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork);
+ page.load(request);
+ QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::PreferNetwork);
+#endif
+}
+
+void tst_QWebEnginePage::setUrlWithPendingLoads()
+{
+ QWebEnginePage page;
+ page.setHtml("<img src='dummy:'/>");
+ page.setUrl(QUrl("about:blank"));
+}
+
+void tst_QWebEnginePage::setUrlToEmpty()
+{
+ QSKIP("FIXME: [0908/090526:FATAL:navigation_controller_impl.cc(927)] Check failed: active_entry->site_instance() == rfh->GetSiteInstance().");
+
+ int expectedLoadFinishedCount = 0;
+ const QUrl aboutBlank("about:blank");
+ const QUrl url("qrc:/resources/test2.html");
+
+ QWebEnginePage page;
+ QCOMPARE(page.url(), QUrl());
+ QCOMPARE(page.requestedUrl(), QUrl());
+ QCOMPARE(baseUrlSync(&page), QUrl());
+
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+
+ // Set existing url
+ page.setUrl(url);
+ expectedLoadFinishedCount++;
+ ::waitForSignal(&page, SIGNAL(loadFinished(bool)));
+
+ QCOMPARE(spy.count(), expectedLoadFinishedCount);
+ QCOMPARE(page.url(), url);
+ QCOMPARE(page.requestedUrl(), url);
+ QCOMPARE(baseUrlSync(&page), url);
+
+ // Set empty url
+ page.setUrl(QUrl());
+ expectedLoadFinishedCount++;
+
+ QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QCOMPARE(page.url(), aboutBlank);
+ QCOMPARE(page.requestedUrl(), QUrl());
+ QCOMPARE(baseUrlSync(&page), aboutBlank);
+
+ // Set existing url
+ page.setUrl(url);
+ expectedLoadFinishedCount++;
+
+ QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QCOMPARE(page.url(), url);
+ QCOMPARE(page.requestedUrl(), url);
+ QCOMPARE(baseUrlSync(&page), url);
+
+ // Load empty url
+ page.load(QUrl());
+ expectedLoadFinishedCount++;
+
+ QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QCOMPARE(page.url(), aboutBlank);
+ QCOMPARE(page.requestedUrl(), QUrl());
+ QCOMPARE(baseUrlSync(&page), aboutBlank);
+}
+
+void tst_QWebEnginePage::setUrlToInvalid()
+{
+ QEXPECT_FAIL("", "Unsupported: QtWebEngine doesn't adjust invalid URLs.", Abort);
+ QVERIFY(false);
+
+ QWebEnginePage page;
+
+ const QUrl invalidUrl("http:/example.com");
+ QVERIFY(!invalidUrl.isEmpty());
+ QVERIFY(invalidUrl != QUrl());
+
+ // QWebEnginePage will do its best to accept the URL, possible converting it to a valid equivalent URL.
+ const QUrl validUrl("http://example.com/");
+ page.setUrl(invalidUrl);
+ QCOMPARE(page.url(), validUrl);
+ QCOMPARE(page.requestedUrl(), validUrl);
+ QCOMPARE(baseUrlSync(&page), validUrl);
+
+ // QUrls equivalent to QUrl() will be treated as such.
+ const QUrl aboutBlank("about:blank");
+ const QUrl anotherInvalidUrl("1http://bugs.webkit.org");
+ QVERIFY(!anotherInvalidUrl.isEmpty()); // and they are not necessarily empty.
+ QVERIFY(!anotherInvalidUrl.isValid());
+ QCOMPARE(anotherInvalidUrl.toEncoded(), QUrl().toEncoded());
+
+ page.setUrl(anotherInvalidUrl);
+ QCOMPARE(page.url(), aboutBlank);
+ QCOMPARE(page.requestedUrl().toEncoded(), anotherInvalidUrl.toEncoded());
+ QCOMPARE(baseUrlSync(&page), aboutBlank);
+}
+
+static QStringList collectHistoryUrls(QWebEngineHistory *history)
+{
+ QStringList urls;
+ foreach (const QWebEngineHistoryItem &i, history->items())
+ urls << i.url().toString();
+ return urls;
+}
+
+void tst_QWebEnginePage::setUrlHistory()
+{
+ QSKIP("FIXME: [0908/090526:FATAL:navigation_controller_impl.cc(927)] Check failed: active_entry->site_instance() == rfh->GetSiteInstance().");
+
+ const QUrl aboutBlank("about:blank");
+ QUrl url;
+ int expectedLoadFinishedCount = 0;
+ QSignalSpy spy(m_page, SIGNAL(loadFinished(bool)));
+
+ QCOMPARE(m_page->history()->count(), 0);
+
+ m_page->setUrl(QUrl());
+ expectedLoadFinishedCount++;
+ QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QCOMPARE(m_page->url(), aboutBlank);
+ QCOMPARE(m_page->requestedUrl(), QUrl());
+ // Chromium stores navigation entry for every successful loads. The load of the empty page is committed and stored as about:blank.
+ QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString());
+
+ url = QUrl("http://non.existent/");
+ m_page->setUrl(url);
+ expectedLoadFinishedCount++;
+ QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ // When error page is disabled in case of LoadFail the entry of the unavailable page is not stored.
+ // We expect the url of the previously loaded page here.
+ QCOMPARE(m_page->url(), aboutBlank);
+ QCOMPARE(m_page->requestedUrl(), QUrl());
+ // Since the entry of the unavailable page is not stored it will not available in the history.
+ QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString());
+
+ url = QUrl("qrc:/resources/test1.html");
+ m_page->setUrl(url);
+ expectedLoadFinishedCount++;
+ QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QCOMPARE(m_page->url(), url);
+ QCOMPARE(m_page->requestedUrl(), url);
+ QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString() << QStringLiteral("qrc:/resources/test1.html"));
+
+ m_page->setUrl(QUrl());
+ expectedLoadFinishedCount++;
+ QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QCOMPARE(m_page->url(), aboutBlank);
+ QCOMPARE(m_page->requestedUrl(), QUrl());
+ // Chromium stores navigation entry for every successful loads. The load of the empty page is committed and stored as about:blank.
+ QCOMPARE(collectHistoryUrls(m_page->history()), QStringList()
+ << aboutBlank.toString()
+ << QStringLiteral("qrc:/resources/test1.html")
+ << aboutBlank.toString());
+
+ url = QUrl("qrc:/resources/test1.html");
+ m_page->setUrl(url);
+ expectedLoadFinishedCount++;
+ QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QCOMPARE(m_page->url(), url);
+ QCOMPARE(m_page->requestedUrl(), url);
+ // The history count DOES change since the about:blank is in the list.
+ QCOMPARE(collectHistoryUrls(m_page->history()), QStringList()
+ << aboutBlank.toString()
+ << QStringLiteral("qrc:/resources/test1.html")
+ << aboutBlank.toString()
+ << QStringLiteral("qrc:/resources/test1.html"));
+
+ url = QUrl("qrc:/resources/test2.html");
+ m_page->setUrl(url);
+ expectedLoadFinishedCount++;
+ QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QCOMPARE(m_page->url(), url);
+ QCOMPARE(m_page->requestedUrl(), url);
+ QCOMPARE(collectHistoryUrls(m_page->history()), QStringList()
+ << aboutBlank.toString()
+ << QStringLiteral("qrc:/resources/test1.html")
+ << aboutBlank.toString()
+ << QStringLiteral("qrc:/resources/test1.html")
+ << QStringLiteral("qrc:/resources/test2.html"));
+}
+
+void tst_QWebEnginePage::setUrlUsingStateObject()
+{
+ const QUrl aboutBlank("about:blank");
+ QUrl url;
+ QSignalSpy urlChangedSpy(m_page, SIGNAL(urlChanged(QUrl)));
+ int expectedUrlChangeCount = 0;
+
+ QCOMPARE(m_page->history()->count(), 0);
+
+ url = QUrl("qrc:/resources/test1.html");
+ m_page->setUrl(url);
+ waitForSignal(m_page, SIGNAL(loadFinished(bool)));
+ expectedUrlChangeCount++;
+ QCOMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
+ QCOMPARE(m_page->url(), url);
+ QCOMPARE(m_page->history()->count(), 1);
+
+ evaluateJavaScriptSync(m_page, "window.history.pushState(null, 'push', 'navigate/to/here')");
+ expectedUrlChangeCount++;
+ QCOMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
+ QCOMPARE(m_page->url(), QUrl("qrc:/resources/navigate/to/here"));
+ QCOMPARE(m_page->history()->count(), 2);
+ QVERIFY(m_page->history()->canGoBack());
+
+ evaluateJavaScriptSync(m_page, "window.history.replaceState(null, 'replace', 'another/location')");
+ expectedUrlChangeCount++;
+ QCOMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
+ QCOMPARE(m_page->url(), QUrl("qrc:/resources/navigate/to/another/location"));
+ QCOMPARE(m_page->history()->count(), 2);
+ QVERIFY(!m_page->history()->canGoForward());
+ QVERIFY(m_page->history()->canGoBack());
+
+ evaluateJavaScriptSync(m_page, "window.history.back()");
QTest::qWait(100);
+ expectedUrlChangeCount++;
+ QCOMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
+ QCOMPARE(m_page->url(), QUrl("qrc:/resources/test1.html"));
+ QVERIFY(m_page->history()->canGoForward());
+ QVERIFY(!m_page->history()->canGoBack());
+}
+
+static inline QUrl extractBaseUrl(const QUrl& url)
+{
+ return url.resolved(QUrl());
+}
+
+void tst_QWebEnginePage::setUrlThenLoads_data()
+{
+ QTest::addColumn<QUrl>("url");
+ QTest::addColumn<QUrl>("baseUrl");
+
+ QTest::newRow("resource file") << QUrl("qrc:/resources/test1.html") << extractBaseUrl(QUrl("qrc:/resources/test1.html"));
+ QTest::newRow("base specified in HTML") << QUrl("data:text/html,<head><base href=\"http://different.base/\"></head>") << QUrl("http://different.base/");
+}
+
+void tst_QWebEnginePage::setUrlThenLoads()
+{
+ QFETCH(QUrl, url);
+ QFETCH(QUrl, baseUrl);
+ QSignalSpy urlChangedSpy(m_page, SIGNAL(urlChanged(QUrl)));
+ QSignalSpy startedSpy(m_page, SIGNAL(loadStarted()));
+ QSignalSpy finishedSpy(m_page, SIGNAL(loadFinished(bool)));
+
+ m_page->setUrl(url);
+ QTRY_COMPARE(startedSpy.count(), 1);
+ QTRY_COMPARE(urlChangedSpy.count(), 1);
+ QTRY_COMPARE(finishedSpy.count(), 1);
+ QVERIFY(finishedSpy.at(0).first().toBool());
+ QCOMPARE(m_page->url(), url);
+ QCOMPARE(m_page->requestedUrl(), url);
+ QCOMPARE(baseUrlSync(m_page), baseUrl);
+
+ const QUrl urlToLoad1("qrc:/resources/test2.html");
+ const QUrl urlToLoad2("qrc:/resources/test1.html");
+
+ // Just after first load. URL didn't changed yet.
+ m_page->load(urlToLoad1);
+ QCOMPARE(m_page->url(), url);
+ QCOMPARE(m_page->requestedUrl(), urlToLoad1);
+ // baseUrlSync spins an event loop and this sometimes return the next result.
+ // QCOMPARE(baseUrlSync(m_page), baseUrl);
+ QTRY_COMPARE(startedSpy.count(), 2);
+
+ // After first URL changed.
+ QTRY_COMPARE(urlChangedSpy.count(), 2);
+ QTRY_COMPARE(finishedSpy.count(), 2);
+ QVERIFY(finishedSpy.at(1).first().toBool());
+ QCOMPARE(m_page->url(), urlToLoad1);
+ QCOMPARE(m_page->requestedUrl(), urlToLoad1);
+ QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad1));
+
+ // Just after second load. URL didn't changed yet.
+ m_page->load(urlToLoad2);
+ QCOMPARE(m_page->url(), urlToLoad1);
+ QCOMPARE(m_page->requestedUrl(), urlToLoad2);
+ QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad1));
+ QTRY_COMPARE(startedSpy.count(), 3);
+
+ // After second URL changed.
+ QTRY_COMPARE(urlChangedSpy.count(), 3);
+ QTRY_COMPARE(finishedSpy.count(), 3);
+ QVERIFY(finishedSpy.at(2).first().toBool());
+ QCOMPARE(m_page->url(), urlToLoad2);
+ QCOMPARE(m_page->requestedUrl(), urlToLoad2);
+ QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad2));
+}
+
+void tst_QWebEnginePage::loadFinishedAfterNotFoundError()
+{
+ QWebEnginePage page;
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+
+ page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+ page.setUrl(QUrl("http://non.existent/url"));
+ QTRY_COMPARE(spy.count(), 1);
+
+ page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true);
+ page.setUrl(QUrl("http://another.non.existent/url"));
+ QTRY_COMPARE(spy.count(), 2);
+}
+
+class URLSetter : public QObject {
+ Q_OBJECT
+
+public:
+ enum Signal {
+ LoadStarted,
+ LoadFinished,
+ ProvisionalLoad
+ };
+
+ enum Type {
+ UseLoad,
+ UseSetUrl
+ };
+
+ URLSetter(QWebEnginePage*, Signal, Type, const QUrl&);
+
+public Q_SLOTS:
+ void execute();
+
+Q_SIGNALS:
+ void finished();
+
+private:
+ QWebEnginePage* m_page;
+ QUrl m_url;
+ Type m_type;
+};
+
+Q_DECLARE_METATYPE(URLSetter::Signal)
+Q_DECLARE_METATYPE(URLSetter::Type)
+
+URLSetter::URLSetter(QWebEnginePage* page, Signal signal, URLSetter::Type type, const QUrl& url)
+ : m_page(page), m_url(url), m_type(type)
+{
+ if (signal == LoadStarted)
+ connect(m_page, SIGNAL(loadStarted()), SLOT(execute()));
+ else if (signal == LoadFinished)
+ connect(m_page, SIGNAL(loadFinished(bool)), SLOT(execute()));
+ else
+ connect(m_page, SIGNAL(provisionalLoad()), SLOT(execute()));
+}
+
+void URLSetter::execute()
+{
+ // We track only the first emission.
+ m_page->disconnect(this);
+ if (m_type == URLSetter::UseLoad)
+ m_page->load(m_url);
+ else
+ m_page->setUrl(m_url);
+ connect(m_page, SIGNAL(loadFinished(bool)), SIGNAL(finished()));
+}
+
+void tst_QWebEnginePage::loadInSignalHandlers_data()
+{
+ QSKIP("FIXME: This crashes in content::WebContentsImpl::NavigateToEntry because of reentrancy. Should we require QueuedConnections or do it ourselves to support this?");
+
+ QTest::addColumn<URLSetter::Type>("type");
+ QTest::addColumn<URLSetter::Signal>("signal");
+ QTest::addColumn<QUrl>("url");
+
+ const QUrl validUrl("qrc:/resources/test2.html");
+ const QUrl invalidUrl("qrc:/invalid");
+
+ QTest::newRow("call load() in loadStarted() after valid url") << URLSetter::UseLoad << URLSetter::LoadStarted << validUrl;
+ QTest::newRow("call load() in loadStarted() after invalid url") << URLSetter::UseLoad << URLSetter::LoadStarted << invalidUrl;
+ QTest::newRow("call load() in loadFinished() after valid url") << URLSetter::UseLoad << URLSetter::LoadFinished << validUrl;
+ QTest::newRow("call load() in loadFinished() after invalid url") << URLSetter::UseLoad << URLSetter::LoadFinished << invalidUrl;
+ QTest::newRow("call load() in provisionalLoad() after valid url") << URLSetter::UseLoad << URLSetter::ProvisionalLoad << validUrl;
+ QTest::newRow("call load() in provisionalLoad() after invalid url") << URLSetter::UseLoad << URLSetter::ProvisionalLoad << invalidUrl;
+
+ QTest::newRow("call setUrl() in loadStarted() after valid url") << URLSetter::UseSetUrl << URLSetter::LoadStarted << validUrl;
+ QTest::newRow("call setUrl() in loadStarted() after invalid url") << URLSetter::UseSetUrl << URLSetter::LoadStarted << invalidUrl;
+ QTest::newRow("call setUrl() in loadFinished() after valid url") << URLSetter::UseSetUrl << URLSetter::LoadFinished << validUrl;
+ QTest::newRow("call setUrl() in loadFinished() after invalid url") << URLSetter::UseSetUrl << URLSetter::LoadFinished << invalidUrl;
+ QTest::newRow("call setUrl() in provisionalLoad() after valid url") << URLSetter::UseSetUrl << URLSetter::ProvisionalLoad << validUrl;
+ QTest::newRow("call setUrl() in provisionalLoad() after invalid url") << URLSetter::UseSetUrl << URLSetter::ProvisionalLoad << invalidUrl;
+}
+
+void tst_QWebEnginePage::loadInSignalHandlers()
+{
+ QFETCH(URLSetter::Type, type);
+ QFETCH(URLSetter::Signal, signal);
+ QFETCH(QUrl, url);
+
+ const QUrl urlForSetter("qrc:/resources/test1.html");
+ URLSetter setter(m_page, signal, type, urlForSetter);
+
+ m_page->load(url);
+ waitForSignal(&setter, SIGNAL(finished()), 200);
+ QCOMPARE(m_page->url(), urlForSetter);
}
QTEST_MAIN(tst_QWebEnginePage)
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
index 994d71b43..c7bffd5bb 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
@@ -1,5 +1,6 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
+ <file>resources/content.html</file>
<file>resources/index.html</file>
<file>resources/frame_a.html</file>
<file>resources/frame_c.html</file>
@@ -7,8 +8,14 @@
<file>resources/iframe2.html</file>
<file>resources/iframe3.html</file>
<file>resources/framedindex.html</file>
- <file>resources/content.html</file>
+ <file>resources/fullscreen.html</file>
<file>resources/script.html</file>
<file>resources/user.css</file>
+ <file>resources/image.png</file>
+ <file>resources/style.css</file>
+ <file>resources/test1.html</file>
+ <file>resources/test2.html</file>
+ <file>resources/testiframe.html</file>
+ <file>resources/testiframe2.html</file>
</qresource>
</RCC>
diff --git a/tests/auto/widgets/qwebenginescript/qwebenginescript.pro b/tests/auto/widgets/qwebenginescript/qwebenginescript.pro
index ff6c49628..e99c7f493 100644
--- a/tests/auto/widgets/qwebenginescript/qwebenginescript.pro
+++ b/tests/auto/widgets/qwebenginescript/qwebenginescript.pro
@@ -1,2 +1 @@
include(../tests.pri)
-exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
diff --git a/tests/auto/widgets/qwebengineview/qwebengineview.pro b/tests/auto/widgets/qwebengineview/qwebengineview.pro
index ff6c49628..e99c7f493 100644
--- a/tests/auto/widgets/qwebengineview/qwebengineview.pro
+++ b/tests/auto/widgets/qwebengineview/qwebengineview.pro
@@ -1,2 +1 @@
include(../tests.pri)
-exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 83f65f9d0..1ebb22cc9 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -25,6 +25,7 @@
#include <qpainter.h>
#include <qwebengineview.h>
#include <qwebenginepage.h>
+#include <qwebenginesettings.h>
#include <qnetworkrequest.h>
#include <qdiriterator.h>
@@ -148,9 +149,7 @@ void tst_QWebEngineView::reusePage()
QWebEngineView* view1 = new QWebEngineView;
QPointer<QWebEnginePage> page = new QWebEnginePage;
view1->setPage(page.data());
-#if defined(QWEBENGINESETTINGS)
page.data()->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
-#endif
page->setHtml(html, QUrl::fromLocalFile(TESTS_SOURCE_DIR));
if (html.contains("</embed>")) {
// some reasonable time for the PluginStream to feed test.swf to flash and start painting
diff --git a/tests/auto/widgets/tests.pri b/tests/auto/widgets/tests.pri
index 8d86ac93e..afdf46f42 100644
--- a/tests/auto/widgets/tests.pri
+++ b/tests/auto/widgets/tests.pri
@@ -11,6 +11,8 @@ TARGET = tst_$$TARGET
SOURCES += $${TARGET}.cpp
INCLUDEPATH += $$PWD
+exists($$_PRO_FILE_PWD_/$${TARGET}.qrc): RESOURCES += $${TARGET}.qrc
+
QT += testlib network webenginewidgets widgets
macx: CONFIG -= app_bundle
diff --git a/tests/auto/widgets/util.h b/tests/auto/widgets/util.h
index 83067fe8d..2b485fc0f 100644
--- a/tests/auto/widgets/util.h
+++ b/tests/auto/widgets/util.h
@@ -166,6 +166,9 @@ static inline QUrl baseUrlSync(QWebEnginePage *page)
#define W_QSKIP(a, b) QSKIP(a)
#define W_QTEST_MAIN(TestObject, params) \
+QT_BEGIN_NAMESPACE \
+QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \
+QT_END_NAMESPACE \
int main(int argc, char *argv[]) \
{ \
QVector<const char *> w_argv(argc); \
@@ -178,6 +181,8 @@ int main(int argc, char *argv[]) \
QApplication app(w_argc, const_cast<char **>(w_argv.data())); \
app.setAttribute(Qt::AA_Use96Dpi, true); \
QTEST_DISABLE_KEYPAD_NAVIGATION \
+ QTEST_ADD_GPU_BLACKLIST_SUPPORT \
TestObject tc; \
+ QTEST_SET_MAIN_SOURCE_PATH \
return QTest::qExec(&tc, argc, argv); \
}
diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro
index 2c8296cb8..aaafcb6e5 100644
--- a/tests/auto/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets.pro
@@ -4,7 +4,6 @@ CONFIG += ordered
SUBDIRS += \
qwebengineaccessibility \
- qwebengineframe \
qwebenginepage \
qwebenginehistory \
qwebenginehistoryinterface \
diff --git a/tests/quicktestbrowser/ApplicationRoot.qml b/tests/quicktestbrowser/ApplicationRoot.qml
index 71737694d..5641b89a3 100644
--- a/tests/quicktestbrowser/ApplicationRoot.qml
+++ b/tests/quicktestbrowser/ApplicationRoot.qml
@@ -44,6 +44,8 @@ import QtWebEngine 1.1
QtObject {
id: root
+ property bool thirdPartyCookiesEnabled: true
+
property QtObject testProfile: WebEngineProfile {
storageName: "Test"
}
diff --git a/tests/quicktestbrowser/BrowserWindow.qml b/tests/quicktestbrowser/BrowserWindow.qml
index f93a6ccd1..3fcca4aab 100644
--- a/tests/quicktestbrowser/BrowserWindow.qml
+++ b/tests/quicktestbrowser/BrowserWindow.qml
@@ -39,7 +39,7 @@
****************************************************************************/
import QtQuick 2.1
-import QtWebEngine 1.1
+import QtWebEngine 1.2
import QtWebEngine.experimental 1.0
import QtQuick.Controls 1.0
@@ -61,8 +61,10 @@ ApplicationWindow {
// This is for the case where the system forces us to leave fullscreen.
if (currentWebView && !isFullScreen) {
currentWebView.state = ""
- if (currentWebView.isFullScreen)
+ if (currentWebView.isFullScreen) {
currentWebView.fullScreenCancelled()
+ fullScreenNotification.hide()
+ }
}
}
@@ -76,6 +78,8 @@ ApplicationWindow {
property alias autoLoadImages: loadImages.checked;
property alias javaScriptEnabled: javaScriptEnabled.checked;
property alias errorPageEnabled: errorPageEnabled.checked;
+ property alias pluginsEnabled: pluginsEnabled.checked;
+ property alias thirdPartyCookiesEnabled: thirdPartyCookiesEnabled.checked;
}
// Make sure the Qt.WindowFullscreenButtonHint is set on OS X.
@@ -245,6 +249,19 @@ ApplicationWindow {
checked: true
}
MenuItem {
+ id: pluginsEnabled
+ text: "Plugins On"
+ checkable: true
+ checked: true
+ }
+ MenuItem {
+ id: thirdPartyCookiesEnabled
+ text: "Third party cookies enabled"
+ checkable: true
+ checked: true
+ onToggled: applicationRoot.thirdPartyCookiesEnabled = checked
+ }
+ MenuItem {
id: offTheRecordEnabled
text: "Off The Record"
checkable: true
@@ -347,6 +364,7 @@ ApplicationWindow {
settings.autoLoadImages: appSettings.autoLoadImages
settings.javascriptEnabled: appSettings.javaScriptEnabled
settings.errorPageEnabled: appSettings.errorPageEnabled
+ settings.pluginsEnabled: appSettings.pluginsEnabled
onCertificateError: {
if (!acceptedCertificates.shouldAutoAccept(error)){
@@ -381,9 +399,11 @@ ApplicationWindow {
webEngineView.state = "FullScreen"
browserWindow.previousVisibility = browserWindow.visibility
browserWindow.showFullScreen()
+ fullScreenNotification.show()
} else {
webEngineView.state = ""
browserWindow.visibility = browserWindow.previousVisibility
+ fullScreenNotification.hide()
}
request.accept()
}
@@ -486,6 +506,10 @@ ApplicationWindow {
}
}
+ FullScreenNotification {
+ id: fullScreenNotification
+ }
+
DownloadView {
id: downloadView
visible: false
diff --git a/tests/quicktestbrowser/FullScreenNotification.qml b/tests/quicktestbrowser/FullScreenNotification.qml
new file mode 100644
index 000000000..80a63d479
--- /dev/null
+++ b/tests/quicktestbrowser/FullScreenNotification.qml
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+
+Rectangle {
+ id: fullScreenNotification
+ width: 500
+ height: 40
+ color: "white"
+ radius: 7
+
+ visible: false
+ opacity: 0
+
+ function show() {
+ visible = true
+ opacity = 1
+ reset.start()
+ }
+
+ function hide() {
+ reset.stop()
+ opacity = 0
+ }
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: 750
+ onStopped: {
+ if (opacity == 0)
+ visible = false
+ }
+ }
+ }
+
+ Timer {
+ id: reset
+ interval: 5000
+ onTriggered: hide()
+ }
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: 125
+
+ Text {
+ id: message
+ width: parent.width
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ wrapMode: Text.WordWrap
+ elide: Text.ElideNone
+ clip: true
+
+ text: qsTr("You are now in fullscreen mode. Press ESC to quit!")
+ }
+}
diff --git a/tests/quicktestbrowser/main.cpp b/tests/quicktestbrowser/main.cpp
index 7171baf77..167f67dc3 100644
--- a/tests/quicktestbrowser/main.cpp
+++ b/tests/quicktestbrowser/main.cpp
@@ -50,7 +50,9 @@ typedef QGuiApplication Application;
#endif
#include <QtQml/QQmlApplicationEngine>
#include <QtQml/QQmlContext>
+#include <QtQml/QQmlComponent>
#include <QtWebEngine/qtwebengineglobal.h>
+#include <QtWebEngineCore/qwebenginecookiestoreclient.h>
static QUrl startupUrl()
{
@@ -80,7 +82,30 @@ int main(int argc, char **argv)
Utils utils;
appEngine.rootContext()->setContextProperty("utils", &utils);
appEngine.load(QUrl("qrc:/ApplicationRoot.qml"));
- QMetaObject::invokeMethod(appEngine.rootObjects().first(), "load", Q_ARG(QVariant, startupUrl()));
+ QObject *rootObject = appEngine.rootObjects().first();
+
+ QQmlComponent component(&appEngine);
+ component.setData(QByteArrayLiteral("import QtQuick 2.0\n"
+ "import QtWebEngine 1.1\n"
+ "WebEngineProfile {\n"
+ "storageName: \"Test\"\n"
+ "}")
+ , QUrl());
+ QObject *profile = component.create();
+ const QMetaObject *rootMeta = rootObject->metaObject();
+ QWebEngineCookieStoreClient *client = 0;
+ QMetaObject::invokeMethod(profile, "cookieStoreClient", Q_RETURN_ARG(QWebEngineCookieStoreClient*, client));
+ int index = rootMeta->indexOfProperty("thirdPartyCookiesEnabled");
+ Q_ASSERT(index != -1);
+ QMetaProperty thirdPartyCookiesProperty = rootMeta->property(index);
+ client->setCookieFilter([rootObject,&thirdPartyCookiesProperty](const QWebEngineCookieStoreClient::FilterRequest&){ return thirdPartyCookiesProperty.read(rootObject).toBool(); });
+
+ index = rootMeta->indexOfProperty("testProfile");
+ Q_ASSERT(index != -1);
+ QMetaProperty profileProperty = rootMeta->property(index);
+ profileProperty.write(rootObject, qVariantFromValue(profile));
+
+ QMetaObject::invokeMethod(rootObject, "load", Q_ARG(QVariant, startupUrl()));
return app.exec();
}
diff --git a/tests/quicktestbrowser/quicktestbrowser.pro b/tests/quicktestbrowser/quicktestbrowser.pro
index 7d6dfa6df..996e82a63 100644
--- a/tests/quicktestbrowser/quicktestbrowser.pro
+++ b/tests/quicktestbrowser/quicktestbrowser.pro
@@ -14,7 +14,8 @@ OTHER_FILES += ApplicationRoot.qml \
ButtonWithMenu.qml \
ContextMenuExtras.qml \
DownloadView.qml \
- FeaturePermissionBar.qml
+ FeaturePermissionBar.qml \
+ FullScreenNotification.qml
RESOURCES += resources.qrc
diff --git a/tests/quicktestbrowser/resources.qrc b/tests/quicktestbrowser/resources.qrc
index 80f1d1543..2dcda4d0d 100644
--- a/tests/quicktestbrowser/resources.qrc
+++ b/tests/quicktestbrowser/resources.qrc
@@ -5,6 +5,7 @@
<file>BrowserWindow.qml</file>
<file>ContextMenuExtras.qml</file>
<file>FeaturePermissionBar.qml</file>
+ <file>FullScreenNotification.qml</file>
<file>ButtonWithMenu.qml</file>
<file>DownloadView.qml</file>
<file>ZoomController.qml</file>
diff --git a/tools/buildscripts/gyp_qtwebengine b/tools/buildscripts/gyp_qtwebengine
index 6db73519a..ce2a43328 100755
--- a/tools/buildscripts/gyp_qtwebengine
+++ b/tools/buildscripts/gyp_qtwebengine
@@ -92,6 +92,11 @@ if __name__ == '__main__':
if 'qt_cross_compile=1' in sys.argv:
os.environ['GYP_CROSSCOMPILE'] = '1'
+ sysroot = 'sysroot='
+ for opt in sys.argv:
+ if opt.startswith(sysroot):
+ os.environ['PKG_CONFIG_SYSROOT_DIR'] = opt[len(sysroot):]
+
gyp_helper.apply_chromium_gyp_env()
# This could give false positives since it doesn't actually do real option
@@ -140,12 +145,9 @@ if __name__ == '__main__':
args.extend(['-D', 'qtwebengine_root=' + purifyGypVarPath(qtwebengine_root)])
args.extend(['-D', 'chromium_src_dir=' + purifyGypVarPath(chrome_src)])
- # linux_use_bundled_gold currently relies on a hardcoded relative path from chromium/src/out/(Release|Debug)
- # Disable it along with the -Wl,--threads flag just in case gold isn't installed on the system.
- args.extend(['-D', 'linux_use_bundled_gold=0'])
- args.extend(['-D', 'linux_use_bundled_binutils=0'])
- args.extend(['-D', 'linux_use_gold_flags=0'])
args.extend(['-D', 'clang_use_chrome_plugins=0'])
+ # We do not want to ship more external binary blobs, so let v8 embed its startup data.
+ args.extend(['-D', 'v8_use_external_startup_data=0'])
# Trigger Qt-specific build conditions.
args.extend(['-D', 'use_qt=1'])
# Tweak the output location and format (hardcode ninja for now if not set)
diff --git a/tools/qmake/config.tests/khr/khr.cpp b/tools/qmake/config.tests/khr/khr.cpp
index 6182df286..01c0c26ca 100644
--- a/tools/qmake/config.tests/khr/khr.cpp
+++ b/tools/qmake/config.tests/khr/khr.cpp
@@ -38,7 +38,5 @@
int main(int, char **)
{
- const khronos_boolean_enum_t kfalse = KHRONOS_FALSE;
- const khronos_boolean_enum_t ktrue = KHRONOS_TRUE;
- return kfalse == ktrue;
+ return 0;
}
diff --git a/tools/qmake/config.tests/khr/khr.pro b/tools/qmake/config.tests/khr/khr.pro
index 6abd2367a..b8e935f5a 100644
--- a/tools/qmake/config.tests/khr/khr.pro
+++ b/tools/qmake/config.tests/khr/khr.pro
@@ -1,2 +1,6 @@
+!isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL
+!isEmpty(QMAKE_INCDIR_OPENGL): INCLUDEPATH += $$QMAKE_INCDIR_OPENGL
+
CONFIG-=qt
+
linux:SOURCES += khr.cpp
diff --git a/tools/qmake/config.tests/snappy/snappy.cpp b/tools/qmake/config.tests/snappy/snappy.cpp
new file mode 100644
index 000000000..7948303fc
--- /dev/null
+++ b/tools/qmake/config.tests/snappy/snappy.cpp
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <snappy.h>
+
+int main(int, char **)
+{
+ snappy::Source* src = 0;
+ snappy::Sink* sink = 0;
+ return 0;
+}
diff --git a/tools/qmake/config.tests/snappy/snappy.pro b/tools/qmake/config.tests/snappy/snappy.pro
new file mode 100644
index 000000000..890174a13
--- /dev/null
+++ b/tools/qmake/config.tests/snappy/snappy.pro
@@ -0,0 +1,3 @@
+linux:SOURCES += snappy.cpp
+LIBS += -lsnappy
+CONFIG -= qt
diff --git a/tools/qmake/config.tests/srtp/srtp.cpp b/tools/qmake/config.tests/srtp/srtp.cpp
new file mode 100644
index 000000000..12400f126
--- /dev/null
+++ b/tools/qmake/config.tests/srtp/srtp.cpp
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <srtp/srtp.h>
+
+int main(int, char **)
+{
+ err_status_t status = srtp_init();
+ return status == err_status_ok;
+}
diff --git a/tools/qmake/config.tests/srtp/srtp.pro b/tools/qmake/config.tests/srtp/srtp.pro
new file mode 100644
index 000000000..2151d64aa
--- /dev/null
+++ b/tools/qmake/config.tests/srtp/srtp.pro
@@ -0,0 +1,3 @@
+linux:SOURCES += srtp.cpp
+LIBS += -lsrtp
+CONFIG -= qt
diff --git a/tools/qmake/mkspecs/features/configure.prf b/tools/qmake/mkspecs/features/configure.prf
index 7b111b78f..f117e214d 100644
--- a/tools/qmake/mkspecs/features/configure.prf
+++ b/tools/qmake/mkspecs/features/configure.prf
@@ -19,14 +19,92 @@ defineTest(runConfigure) {
test ~= s/\\.pro$//
qtCompileTest($$test)
}
- # libcap-dev package doesn't ship .pc files on Ubuntu.
- linux:!config_libcap:skipBuild("libcap development package appears to be missing")
- linux:!config_khr:skipBuild("khronos development headers appear to be missing (mesa/libegl1-mesa-dev)")
- contains(QT_CONFIG, xcb) {
- for(package, $$list("libdrm xcomposite xi xrandr")) {
+
+ linux {
+ # libcap-dev package doesn't ship .pc files on Ubuntu.
+ !config_libcap:skipBuild("libcap development package appears to be missing")
+ !config_khr:skipBuild("khronos development headers appear to be missing (mesa/libegl1-mesa-dev)")
+
+ REQUIRED_PACKAGES = dbus-1 fontconfig
+ contains(QT_CONFIG, xcb): REQUIRED_PACKAGES += libdrm xcomposite xcursor xi xrandr xscrnsaver xtst
+ contains(QT_CONFIG, pulseaudio): REQUIRED_PACKAGES += libpulse
+ contains(QT_CONFIG, system-png): REQUIRED_PACKAGES += libpng
+ contains(QT_CONFIG, system-harfbuzz): REQUIRED_PACKAGES += harfbuzz
+ !cross_compile: REQUIRED_PACKAGES += libpci
+
+ for(package, $$list($$REQUIRED_PACKAGES)) {
!packagesExist($$package):skipBuild("Unmet dependency: $$package")
}
+ packagesExist(minizip, zlib): WEBENGINE_CONFIG += use_system_minizip
+ else: log("System zlib or minizip not found. Using Chromium's copies.$${EOL}")
+ packagesExist(libwebp,libwebpdemux): WEBENGINE_CONFIG += use_system_libwebp
+ else: log("System libwebp or libwebpdemux not found. Using Chromium's copies.$${EOL}")
+ packagesExist(libxml-2.0,libxslt): WEBENGINE_CONFIG += use_system_libxslt
+ else: log("System libxml2 or libxslt not found. Using Chromium's copies.$${EOL}")
+ for(package, $$list("libevent flac jsoncpp opus speex")) {
+ packagesExist($$package): WEBENGINE_CONFIG += use_system_$$package
+ else: log("System $$package not found. Using Chromium's copy.$${EOL}")
+ }
+ packagesExist("\'vpx >= 1.4\'"): WEBENGINE_CONFIG += use_system_vpx
+ else: log("System vpx >= 1.4 not found. Using Chromium's copy.$${EOL}")
+ config_srtp: WEBENGINE_CONFIG += use_system_libsrtp
+ else: log("System libsrtp not found. Using Chromium's copy.$${EOL}")
+ config_snappy: WEBENGINE_CONFIG += use_system_snappy
+ else: log("System snappy not found. Using Chromium's copy.$${EOL}")
+
+ # Optional dependencies
+ packagesExist(nss): WEBENGINE_CONFIG += use_nss
+ else: log("System NSS not found, BoringSSL will be used.$${EOL}")
+ }
+
+ isEmpty(skipBuildReason): {
+ cache(CONFIG, add, $$list(webengine_successfully_configured))
+ !isEmpty(WEBENGINE_CONFIG) {
+ cache(WEBENGINE_CONFIG, add, $$list($$WEBENGINE_CONFIG))
+ export(WEBENGINE_CONFIG)
+ }
+ }
+}
+
+# This is called from default_post, at which point we've also parsed
+# command line options
+defineTest(finalizeConfigure) {
+ linux {
+ use?(nss) {
+ log("SSL............................... Using system NSS$${EOL}")
+ } else {
+ log("SSL............................... Using bundled BoringSSL$${EOL}")
+ }
+ use?(system_icu) {
+ packagesExist("icu-uc icu-i18n") {
+ log("ICU............................... Using system version$${EOL}")
+ } else {
+ log("ICU............................... System ICU not found$${EOL}")
+ skipBuild("Unmet dependencies: icu-uc, icu-i18n")
+ }
+ } else {
+ log("ICU............................... Using internal copy (Default, force system ICU with WEBENGINE_CONFIG += use_system_icu)$${EOL}")
+ }
+ use?(system_ffmpeg) {
+ packagesExist("libavcodec libavformat libavutil") {
+ packagesExist("libwebp, libwebpdemux, opus, \'vpx >= 1.4\'"){
+ log("FFMPEG............................ Using system version$${EOL}")
+ } else {
+ log("FFMPEG............................ Conflicting FFMPEG dependencies$${EOL}")
+ skipBuild("Unmet dependencies: opus, vpx, libwebp, libwebpdemux")
+ }
+ } else {
+ log("FFMPEG............................ System FFMPEG not found$${EOL}")
+ skipBuild("Unmet dependencies: libavcodec, libavformat, libavutil")
+ }
+ } else {
+ log("FFMPEG............................ Using internal copy (Default, force system FFMPEG with WEBENGINE_CONFIG += use_system_ffmpeg)$${EOL}")
+ }
+ }
+ use?(proprietary_codecs) {
+ log("Proprietary codecs (H264, MP3).... Enabled$${EOL}")
+ } else {
+ log("Proprietary codecs (H264, MP3).... Not enabled (Default, enable with WEBENGINE_CONFIG += use_proprietary_codecs)$${EOL}")
}
- isEmpty(skipBuildReason):cache(CONFIG, add, $$list(webengine_successfully_configured))
}
diff --git a/tools/qmake/mkspecs/features/default_post.prf b/tools/qmake/mkspecs/features/default_post.prf
index d09ba05fd..64e8cb1fe 100644
--- a/tools/qmake/mkspecs/features/default_post.prf
+++ b/tools/qmake/mkspecs/features/default_post.prf
@@ -1,4 +1,7 @@
load(default_post)
+load(functions)
+
+root_project_file:isPlatformSupported(): finalizeConfigure()
!isEmpty(skipBuildReason) {
SUBDIRS =
diff --git a/tools/qmake/mkspecs/features/default_pre.prf b/tools/qmake/mkspecs/features/default_pre.prf
index 2e556c2a6..6506e67ad 100644
--- a/tools/qmake/mkspecs/features/default_pre.prf
+++ b/tools/qmake/mkspecs/features/default_pre.prf
@@ -16,7 +16,9 @@ load(default_pre)
load(functions)
# Check platform support and run config tests early enough to bail
-equals(_PRO_FILE_, "$$QTWEBENGINE_ROOT/qtwebengine.pro"): isPlatformSupported() {
+equals(_PRO_FILE_, "$$QTWEBENGINE_ROOT/qtwebengine.pro"): CONFIG += root_project_file
+
+root_project_file:isPlatformSupported() {
load(configure)
runConfigure()
}
diff --git a/tools/qmake/mkspecs/features/functions.prf b/tools/qmake/mkspecs/features/functions.prf
index 64064bddb..d5265ab00 100644
--- a/tools/qmake/mkspecs/features/functions.prf
+++ b/tools/qmake/mkspecs/features/functions.prf
@@ -1,5 +1,9 @@
defineTest(isPlatformSupported) {
- !win32-msvc2013: !contains(QT_CONFIG, c++11) {
+ !linux-g++*:!linux-clang:!win32-msvc2013*:!win32-msvc2015*:!macx-clang*:!boot2qt {
+ skipBuild("Qt WebEngine can currently only be built for Linux (GCC/clang), Windows (MSVC 2013 or 2015), OS X (10.9/XCode 5.1+) or Qt for Device Creation.")
+ return(false)
+ }
+ !contains(QT_CONFIG, c++11) {
skipBuild("C++11 support is required in order to build chromium.")
return(false)
}
@@ -7,18 +11,22 @@ defineTest(isPlatformSupported) {
skipBuild("Static builds of QtWebEngine aren't supported.")
return(false)
}
- osx:lessThan(QMAKE_XCODE_VERSION, 5.1) {
- skipBuild("Using xcode version $$QMAKE_XCODE_VERSION, but at least version 5.1 is required to build Qt WebEngine.")
- return(false)
+ osx {
+ lessThan(QMAKE_XCODE_VERSION, 5.1) {
+ skipBuild("Using xcode version $$QMAKE_XCODE_VERSION, but at least version 5.1 is required to build Qt WebEngine.")
+ return(false)
+ }
+ # We require OS X 10.9 (darwin version 13.0.0) or newer
+ darwin_major_version = $$section(QMAKE_HOST.version, ., 0, 0)
+ lessThan(darwin_major_version, 13) {
+ skipBuild("OS X version 10.9 or newer is required to build Qt WebEngine.")
+ return(false)
+ }
}
linux-g++*:!isGCCVersionSupported(): return(false)
!isPythonVersionSupported(): return(false)
- linux-g++*|win32-msvc2013|macx-clang*: return(true)
- boot2qt: return(true)
-
- skipBuild("Qt WebEngine can currently only be built for Linux (GCC), Windows (MSVC 2013), OS X (XCode 5.1+) or Qt for Device Creation.")
- return(false)
+ return(true)
}
defineTest(isPythonVersionSupported) {
@@ -149,6 +157,11 @@ defineReplace(which) {
return($$out)
}
+defineTest(use?) {
+ contains(WEBENGINE_CONFIG, use_$$lower($$1)): return(true)
+ return(false)
+}
+
defineReplace(findOrBuildNinja) {
# If NINJA_PATH env var is set, prefer that.
# Fallback to locating our own bootstrapped ninja.
diff --git a/tools/scripts/take_snapshot.py b/tools/scripts/take_snapshot.py
index bd2ec4e56..5f911f36f 100755
--- a/tools/scripts/take_snapshot.py
+++ b/tools/scripts/take_snapshot.py
@@ -78,7 +78,7 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/android_tools')
or '/tests/' in file_path
or ('/test/' in file_path and
- not '/webrtc/test/testsupport/' in file_path and
+ not '/webrtc/' in file_path and
not file_path.startswith('net/test/') and
not file_path.endswith('mock_chrome_application_mac.h') and
not file_path.endswith('perftimer.h') and
@@ -100,9 +100,9 @@ def isInChromiumBlacklist(file_path):
not 'repack_locales' in file_path and
not 'third_party/chromevox' in file_path and
not 'media/desktop_media_list.h' in file_path and
- not 'media/desktop_streams_registry.cc' in file_path and
- not 'media/desktop_streams_registry.h' in file_path and
- not 'common/localized_error' in file_path and
+ not 'media/desktop_streams_registry.' in file_path and
+ not 'common/chrome_switches.' in file_path and
+ not 'common/localized_error.' in file_path and
not file_path.endswith('cf_resources.rc') and
not file_path.endswith('version.py') and
not file_path.endswith('.grd') and
@@ -113,16 +113,25 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('chromeos')
or file_path.startswith('cloud_print')
or (file_path.startswith('components') and
+ not file_path.startswith('components/device_event_log') and
+ not file_path.startswith('components/devtools_') and
+ not file_path.startswith('components/error_page') and
+ not file_path.startswith('components/mime_util') and
+ not file_path.startswith('components/printing') and
+ not file_path.startswith('components/resources') and
+ not file_path.startswith('components/scheduler') and
+ not file_path.startswith('components/strings') and
not file_path.startswith('components/tracing') and
not file_path.startswith('components/visitedlink') and
- not file_path.startswith('components/error_page') and
+ not file_path.startswith('components/web_cache') and
+ not file_path.startswith('components/webcrypto') and
not file_path.endswith('.grdp') and
not 'components_strings' in file_path)
or file_path.startswith('content/public/android/java')
- or file_path.startswith('content/shell')
+ or (file_path.startswith('content/shell') and
+ not file_path.startswith('content/shell/common'))
or file_path.startswith('courgette')
or (file_path.startswith('extensions') and
- # Included by generated sources of ui/accessibility/ax_enums.idl
not 'browser/extension_function_registry.h' in file_path and
not 'browser/extension_function_histogram_value.h' in file_path)
or file_path.startswith('google_update')
@@ -136,19 +145,14 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('sync')
or file_path.startswith('testing/android')
or file_path.startswith('testing/buildbot')
- or file_path.startswith('third_party/accessibility-developer-tools')
- or file_path.startswith('third_party/GTM')
or file_path.startswith('third_party/WebKit/LayoutTests')
or file_path.startswith('third_party/WebKit/ManualTests')
or file_path.startswith('third_party/WebKit/PerformanceTests')
- or file_path.startswith('third_party/active_doc')
- or file_path.startswith('third_party/android_crazy_linker')
- or file_path.startswith('third_party/android_platform')
- or file_path.startswith('third_party/android_testrunner')
- or file_path.startswith('third_party/aosp')
- or file_path.startswith('third_party/apache-mime4j')
+ or file_path.startswith('third_party/accessibility-audit')
+ or file_path.startswith('third_party/android_')
or file_path.startswith('third_party/apache-win32')
or file_path.startswith('third_party/apple_sample_code')
+ or file_path.startswith('third_party/ashmem')
or file_path.startswith('third_party/binutils')
or file_path.startswith('third_party/bison')
or (file_path.startswith('third_party/cacheinvalidation') and
@@ -157,26 +161,20 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/cld_2')
or file_path.startswith('third_party/codesighs')
or file_path.startswith('third_party/colorama')
- or file_path.startswith('third_party/cros_dbus_cplusplus')
or file_path.startswith('third_party/cros_system_api')
or file_path.startswith('third_party/cygwin')
or file_path.startswith('third_party/cython')
+ or file_path.startswith('third_party/deqp')
or file_path.startswith('third_party/elfutils')
- or file_path.startswith('third_party/eyesfree')
- or file_path.startswith('third_party/findbugs')
or file_path.startswith('third_party/google_input_tools')
or file_path.startswith('third_party/gperf')
or file_path.startswith('third_party/gnu_binutils')
or file_path.startswith('third_party/gtk+')
or file_path.startswith('third_party/google_appengine_cloudstorage')
or file_path.startswith('third_party/google_toolbox_for_mac')
- or file_path.startswith('third_party/guava/src')
- or file_path.startswith('third_party/httpcomponents-client')
- or file_path.startswith('third_party/httpcomponents-core')
- or file_path.startswith('third_party/hunspell')
or file_path.startswith('third_party/hunspell_dictionaries')
+ or file_path.startswith('third_party/hunspell')
or file_path.startswith('third_party/instrumented_libraries')
- or file_path.startswith('third_party/jarjar')
or file_path.startswith('third_party/jsr-305/src')
or file_path.startswith('third_party/junit')
or file_path.startswith('third_party/libphonenumber')
@@ -188,21 +186,20 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/markdown')
or file_path.startswith('third_party/mingw-w64')
or file_path.startswith('third_party/nacl_sdk_binaries')
- or file_path.startswith('third_party/polymer')
+ or (file_path.startswith('third_party/polymer') and
+ not file_path.startswith('third_party/polymer/v1_0/components-chromium/'))
or file_path.startswith('third_party/pdfsqueeze')
or file_path.startswith('third_party/pefile')
or file_path.startswith('third_party/perl')
or file_path.startswith('third_party/pdfium')
or file_path.startswith('third_party/psyco_win32')
- or file_path.startswith('third_party/python_26')
or file_path.startswith('third_party/scons-2.0.1')
- or file_path.startswith('third_party/syzygy')
- or file_path.startswith('third_party/swig')
- or file_path.startswith('third_party/webgl')
or file_path.startswith('third_party/trace-viewer')
- or file_path.startswith('third_party/xulrunner-sdk')
+ or file_path.startswith('third_party/undoview')
+ or file_path.startswith('third_party/webgl')
or (file_path.startswith('tools') and
not file_path.startswith('tools/clang') and
+ not file_path.startswith('tools/compile_test') and
not file_path.startswith('tools/generate_library_loader') and
not file_path.startswith('tools/generate_shim_headers') and
not file_path.startswith('tools/generate_stubs') and
@@ -214,9 +211,12 @@ def isInChromiumBlacklist(file_path):
not file_path.startswith('tools/protoc_wrapper'))
or file_path.startswith('ui/android/java')
or file_path.startswith('ui/app_list')
+ or file_path.startswith('ui/base/ime/chromeos')
or file_path.startswith('ui/chromeos')
or file_path.startswith('ui/display/chromeos')
+ or file_path.startswith('ui/events/ozone/chromeos')
or file_path.startswith('ui/file_manager')
+ or file_path.startswith('ui/gfx/chromeos')
):
return True
@@ -306,7 +306,10 @@ def exportChromium():
commandNotFound = subprocess.call(['which', 'dos2unix'])
if not commandNotFound:
- dos2unixVersion = StrictVersion(subprocess.Popen(['dos2unix', '-V', '| true'], stdout=subprocess.PIPE).communicate()[0].splitlines()[0].split()[1])
+ dos2unixVersion , err = subprocess.Popen(['dos2unix', '-V', '| true'], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+ if not dos2unixVersion:
+ raise Exception("You need dos2unix version 6.0.6 minimum.")
+ dos2unixVersion = StrictVersion(dos2unixVersion.splitlines()[0].split()[1])
if commandNotFound or dos2unixVersion < StrictVersion('6.0.6'):
raise Exception("You need dos2unix version 6.0.6 minimum.")
diff --git a/tools/scripts/version_resolver.py b/tools/scripts/version_resolver.py
index 419fb72d1..baa4a468a 100644
--- a/tools/scripts/version_resolver.py
+++ b/tools/scripts/version_resolver.py
@@ -51,8 +51,8 @@ import json
import urllib2
import git_submodule as GitSubmodule
-chromium_version = '40.0.2214.115'
-chromium_branch = '2214'
+chromium_version = '45.0.2454.101'
+chromium_branch = '2454'
ninja_version = 'v1.5.3'
json_url = 'http://omahaproxy.appspot.com/all.json'
@@ -64,6 +64,7 @@ upstream_src_dir = os.path.abspath(snapshot_src_dir + '_upstream')
submodule_blacklist = [
'third_party/WebKit/LayoutTests/w3c/csswg-test'
, 'third_party/WebKit/LayoutTests/w3c/web-platform-tests'
+ , 'third_party/jsoncpp/source'
, 'chrome/tools/test/reference_build/chrome_mac'
, 'chrome/tools/test/reference_build/chrome_linux'
, 'chrome/tools/test/reference_build/chrome_win'
@@ -91,7 +92,7 @@ def readReleaseChannels():
return channels
def readSubmodules():
- git_deps = subprocess.check_output(['git', 'show', chromium_version +':.DEPS.git'])
+ git_deps = subprocess.check_output(['git', 'show', chromium_version +':DEPS'])
parser = GitSubmodule.DEPSParser()
git_submodules = parser.parse(git_deps)