summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--.qmake.conf2
-rw-r--r--dist/changes-5.6.074
-rw-r--r--examples/examples.pro5
-rw-r--r--examples/webengine/quicknanobrowser/ApplicationRoot.qml2
-rw-r--r--examples/webengine/quicknanobrowser/BrowserDialog.qml2
-rw-r--r--examples/webengine/quicknanobrowser/BrowserWindow.qml130
-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.qdoc108
-rw-r--r--examples/webengine/quicknanobrowser/main.cpp55
-rw-r--r--examples/webengine/quicknanobrowser/quicknanobrowser.pro3
-rw-r--r--examples/webengine/quicknanobrowser/resources.qrc1
-rw-r--r--examples/webengine/quicknanobrowser/utils.h64
-rw-r--r--examples/webenginewidgets/browser/autosaver.cpp93
-rw-r--r--examples/webenginewidgets/browser/autosaver.h75
-rw-r--r--examples/webenginewidgets/browser/browser.icnsbin50218 -> 0 bytes
-rw-r--r--examples/webenginewidgets/browser/browser.icobin15374 -> 0 bytes
-rw-r--r--examples/webenginewidgets/browser/browser.rc1
-rw-r--r--examples/webenginewidgets/browser/browserapplication.h127
-rw-r--r--examples/webenginewidgets/browser/chasewidget.h85
-rw-r--r--examples/webenginewidgets/browser/data/browser.svg411
-rw-r--r--examples/webenginewidgets/browser/doc/images/browser-demo.pngbin156342 -> 0 bytes
-rw-r--r--examples/webenginewidgets/browser/edittableview.cpp77
-rw-r--r--examples/webenginewidgets/browser/edittableview.h60
-rw-r--r--examples/webenginewidgets/browser/edittreeview.cpp76
-rw-r--r--examples/webenginewidgets/browser/networkaccessmanager.cpp160
-rw-r--r--examples/webenginewidgets/browser/networkaccessmanager.h75
-rw-r--r--examples/webenginewidgets/browser/searchlineedit.h102
-rw-r--r--examples/webenginewidgets/browser/settings.h73
-rw-r--r--examples/webenginewidgets/browser/squeezelabel.cpp60
-rw-r--r--examples/webenginewidgets/browser/toolbarsearch.h83
-rw-r--r--examples/webenginewidgets/browser/urllineedit.h114
-rw-r--r--examples/webenginewidgets/contentmanipulation/contentmanipulation.pro (renamed from examples/webenginewidgets/fancybrowser/fancybrowser.pro)4
-rw-r--r--examples/webenginewidgets/contentmanipulation/doc/images/contentmanipulation-example.png (renamed from examples/webenginewidgets/fancybrowser/doc/images/fancybrowser-example.png)bin98031 -> 98031 bytes
-rw-r--r--examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc (renamed from examples/webenginewidgets/fancybrowser/doc/src/fancybrowser.qdoc)28
-rw-r--r--examples/webenginewidgets/contentmanipulation/jquery.min.js (renamed from examples/webenginewidgets/fancybrowser/jquery.min.js)0
-rw-r--r--examples/webenginewidgets/contentmanipulation/jquery.qrc (renamed from examples/webenginewidgets/fancybrowser/jquery.qrc)0
-rw-r--r--examples/webenginewidgets/contentmanipulation/main.cpp (renamed from examples/webenginewidgets/fancybrowser/main.cpp)0
-rw-r--r--examples/webenginewidgets/contentmanipulation/mainwindow.cpp (renamed from examples/webenginewidgets/fancybrowser/mainwindow.cpp)0
-rw-r--r--examples/webenginewidgets/contentmanipulation/mainwindow.h (renamed from examples/webenginewidgets/fancybrowser/mainwindow.h)0
-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.cpp92
-rw-r--r--examples/webenginewidgets/demobrowser/autosaver.h74
-rw-r--r--examples/webenginewidgets/demobrowser/bookmarks.cpp (renamed from examples/webenginewidgets/browser/bookmarks.cpp)55
-rw-r--r--examples/webenginewidgets/demobrowser/bookmarks.h (renamed from examples/webenginewidgets/browser/bookmarks.h)55
-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)165
-rw-r--r--examples/webenginewidgets/demobrowser/browserapplication.h141
-rw-r--r--examples/webenginewidgets/demobrowser/browsermainwindow.cpp (renamed from examples/webenginewidgets/browser/browsermainwindow.cpp)55
-rw-r--r--examples/webenginewidgets/demobrowser/browsermainwindow.h (renamed from examples/webenginewidgets/browser/browsermainwindow.h)55
-rw-r--r--examples/webenginewidgets/demobrowser/chasewidget.cpp (renamed from examples/webenginewidgets/browser/chasewidget.cpp)55
-rw-r--r--examples/webenginewidgets/demobrowser/chasewidget.h84
-rw-r--r--examples/webenginewidgets/demobrowser/cookiejar.cpp (renamed from examples/webenginewidgets/browser/cookiejar.cpp)55
-rw-r--r--examples/webenginewidgets/demobrowser/cookiejar.h (renamed from examples/webenginewidgets/browser/cookiejar.h)55
-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.svg24
-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.icnsbin0 -> 31513 bytes
-rw-r--r--examples/webenginewidgets/demobrowser/demobrowser.icobin0 -> 82726 bytes
-rw-r--r--examples/webenginewidgets/demobrowser/demobrowser.pro (renamed from examples/webenginewidgets/browser/browser.pro)20
-rw-r--r--examples/webenginewidgets/demobrowser/demobrowser.rc1
-rw-r--r--examples/webenginewidgets/demobrowser/doc/images/browser-demo.pngbin0 -> 199354 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)11
-rw-r--r--examples/webenginewidgets/demobrowser/downloadmanager.cpp (renamed from examples/webenginewidgets/browser/downloadmanager.cpp)56
-rw-r--r--examples/webenginewidgets/demobrowser/downloadmanager.h (renamed from examples/webenginewidgets/browser/downloadmanager.h)57
-rw-r--r--examples/webenginewidgets/demobrowser/downloads.ui (renamed from examples/webenginewidgets/browser/downloads.ui)0
-rw-r--r--examples/webenginewidgets/demobrowser/edittableview.cpp76
-rw-r--r--examples/webenginewidgets/demobrowser/edittableview.h59
-rw-r--r--examples/webenginewidgets/demobrowser/edittreeview.cpp75
-rw-r--r--examples/webenginewidgets/demobrowser/edittreeview.h59
-rw-r--r--examples/webenginewidgets/demobrowser/featurepermissionbar.cpp (renamed from examples/webenginewidgets/browser/featurepermissionbar.cpp)55
-rw-r--r--examples/webenginewidgets/demobrowser/featurepermissionbar.h73
-rw-r--r--examples/webenginewidgets/demobrowser/fullscreennotification.cpp111
-rw-r--r--examples/webenginewidgets/demobrowser/fullscreennotification.h76
-rw-r--r--examples/webenginewidgets/demobrowser/history.cpp (renamed from examples/webenginewidgets/browser/history.cpp)55
-rw-r--r--examples/webenginewidgets/demobrowser/history.h (renamed from examples/webenginewidgets/browser/history.h)55
-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.cpp54
-rw-r--r--examples/webenginewidgets/demobrowser/modelmenu.cpp (renamed from examples/webenginewidgets/browser/modelmenu.cpp)55
-rw-r--r--examples/webenginewidgets/demobrowser/modelmenu.h (renamed from examples/webenginewidgets/browser/modelmenu.h)55
-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)59
-rw-r--r--examples/webenginewidgets/demobrowser/searchlineedit.h101
-rw-r--r--examples/webenginewidgets/demobrowser/settings.cpp (renamed from examples/webenginewidgets/browser/settings.cpp)88
-rw-r--r--examples/webenginewidgets/demobrowser/settings.h75
-rw-r--r--examples/webenginewidgets/demobrowser/settings.ui (renamed from examples/webenginewidgets/browser/settings.ui)27
-rw-r--r--examples/webenginewidgets/demobrowser/squeezelabel.cpp59
-rw-r--r--examples/webenginewidgets/demobrowser/squeezelabel.h58
-rw-r--r--examples/webenginewidgets/demobrowser/tabwidget.cpp (renamed from examples/webenginewidgets/browser/tabwidget.cpp)220
-rw-r--r--examples/webenginewidgets/demobrowser/tabwidget.h (renamed from examples/webenginewidgets/browser/tabwidget.h)72
-rw-r--r--examples/webenginewidgets/demobrowser/toolbarsearch.cpp (renamed from examples/webenginewidgets/browser/toolbarsearch.cpp)55
-rw-r--r--examples/webenginewidgets/demobrowser/toolbarsearch.h82
-rw-r--r--examples/webenginewidgets/demobrowser/urllineedit.cpp (renamed from examples/webenginewidgets/browser/urllineedit.cpp)67
-rw-r--r--examples/webenginewidgets/demobrowser/urllineedit.h113
-rw-r--r--examples/webenginewidgets/demobrowser/webview.cpp (renamed from examples/webenginewidgets/browser/webview.cpp)129
-rw-r--r--examples/webenginewidgets/demobrowser/webview.h (renamed from examples/webenginewidgets/browser/webview.h)60
-rw-r--r--examples/webenginewidgets/demobrowser/xbel.cpp (renamed from examples/webenginewidgets/browser/xbel.cpp)55
-rw-r--r--examples/webenginewidgets/demobrowser/xbel.h (renamed from examples/webenginewidgets/browser/xbel.h)55
-rw-r--r--examples/webenginewidgets/markdowneditor/3RDPARTY.md23
-rw-r--r--examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.pngbin0 -> 41883 bytes
-rw-r--r--examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc164
-rw-r--r--examples/webenginewidgets/markdowneditor/document.cpp48
-rw-r--r--examples/webenginewidgets/markdowneditor/document.h62
-rw-r--r--examples/webenginewidgets/markdowneditor/main.cpp54
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.cpp170
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.h77
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.ui115
-rw-r--r--examples/webenginewidgets/markdowneditor/markdowneditor.pro28
-rw-r--r--examples/webenginewidgets/markdowneditor/previewpage.cpp53
-rw-r--r--examples/webenginewidgets/markdowneditor/previewpage.h55
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/default.md12
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/index.html32
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/markdown.css260
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc9
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/marked.min.js6
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/qwebchannel.js419
m---------src/3rdparty0
-rw-r--r--src/core/api/core_api.pro58
-rw-r--r--src/core/api/qtwebenginecoreglobal.cpp94
-rw-r--r--src/core/api/qtwebenginecoreglobal.h54
-rw-r--r--src/core/api/qtwebenginecoreglobal_p.h (renamed from src/core/qtwebenginecoreglobal.h)31
-rw-r--r--src/core/api/qwebenginecallback.h99
-rw-r--r--src/core/api/qwebenginecallback_p.h249
-rw-r--r--src/core/api/qwebenginecookiestore.cpp307
-rw-r--r--src/core/api/qwebenginecookiestore.h84
-rw-r--r--src/core/api/qwebenginecookiestore_p.h (renamed from src/webengine/api/qquickwebengineprofile_p_p.h)72
-rw-r--r--src/core/api/qwebengineurlrequestinfo.cpp282
-rw-r--r--src/core/api/qwebengineurlrequestinfo.h109
-rw-r--r--src/core/api/qwebengineurlrequestinfo_p.h (renamed from src/webenginewidgets/api/qwebengineurlschemehandler_p_p.h)47
-rw-r--r--src/core/api/qwebengineurlrequestinterceptor.h65
-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.cpp (renamed from src/webenginewidgets/api/qwebengineurlschemehandler_p.h)78
-rw-r--r--src/core/api/qwebengineurlschemehandler.h (renamed from src/core/custom_url_scheme_handler.h)42
-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.cpp85
-rw-r--r--src/core/browser_context_adapter.h34
-rw-r--r--src/core/browser_context_adapter_client.h1
-rw-r--r--src/core/browser_context_qt.cpp21
-rw-r--r--src/core/browser_context_qt.h9
-rw-r--r--src/core/chrome_qt.gyp12
-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.h13
-rw-r--r--src/core/common/user_script_data.h6
-rw-r--r--src/core/config/desktop_linux.pri23
-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.pri43
-rw-r--r--src/core/content_browser_client_qt.cpp65
-rw-r--r--src/core/content_browser_client_qt.h27
-rw-r--r--src/core/content_client_qt.cpp111
-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.cpp180
-rw-r--r--src/core/cookie_monster_delegate_qt.h88
-rw-r--r--src/core/core.pro19
-rw-r--r--src/core/core_common.pri4
-rw-r--r--src/core/core_gyp_generator.pro37
-rw-r--r--src/core/core_headers.pro5
-rw-r--r--src/core/core_module.pro79
-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.cpp77
-rw-r--r--src/core/delegated_frame_node.h6
-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.qdoc50
-rw-r--r--src/core/download_manager_delegate_qt.cpp28
-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.pro93
-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.cpp52
-rw-r--r--src/core/media_capture_devices_dispatcher.cpp11
-rw-r--r--src/core/network_delegate_qt.cpp155
-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.cpp209
-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.gypi8
-rw-r--r--src/core/qtwebengine_extras.gypi2
-rw-r--r--src/core/render_view_observer_host_qt.cpp (renamed from src/core/qt_render_view_observer_host.cpp)28
-rw-r--r--src/core/render_view_observer_host_qt.h (renamed from src/core/qt_render_view_observer_host.h)10
-rw-r--r--src/core/render_widget_host_view_qt.cpp81
-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.cpp21
-rw-r--r--src/core/renderer/content_renderer_client_qt.h7
-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/render_frame_observer_qt.cpp65
-rw-r--r--src/core/renderer/render_frame_observer_qt.h66
-rw-r--r--src/core/renderer/render_view_observer_qt.cpp (renamed from src/core/renderer/qt_render_view_observer.cpp)40
-rw-r--r--src/core/renderer/render_view_observer_qt.h (renamed from src/core/renderer/qt_render_view_observer.h)21
-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/devtools_discovery_page.html106
-rw-r--r--src/core/resources/resources.gyp10
-rw-r--r--src/core/stream_video_node.cpp39
-rw-r--r--src/core/stream_video_node.h19
-rw-r--r--src/core/type_conversion.h37
-rw-r--r--src/core/url_request_context_getter_qt.cpp141
-rw-r--r--src/core/url_request_context_getter_qt.h15
-rw-r--r--src/core/url_request_custom_job.cpp36
-rw-r--r--src/core/url_request_custom_job.h9
-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.cpp157
-rw-r--r--src/core/web_contents_adapter.h21
-rw-r--r--src/core/web_contents_adapter_client.h79
-rw-r--r--src/core/web_contents_adapter_p.h4
-rw-r--r--src/core/web_contents_delegate_qt.cpp99
-rw-r--r--src/core/web_contents_delegate_qt.h28
-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.cpp60
-rw-r--r--src/core/web_engine_context.h5
-rw-r--r--src/core/web_engine_library_info.cpp66
-rw-r--r--src/core/web_engine_settings.cpp118
-rw-r--r--src/core/web_engine_settings.h6
-rw-r--r--src/core/yuv_video_node.cpp179
-rw-r--r--src/core/yuv_video_node.h38
-rw-r--r--src/process/process.pro27
-rw-r--r--src/webengine/api/qquickwebenginecertificateerror.cpp22
-rw-r--r--src/webengine/api/qquickwebenginecertificateerror_p.h2
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem.cpp18
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem_p.h5
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem_p_p.h3
-rw-r--r--src/webengine/api/qquickwebenginehistory.cpp112
-rw-r--r--src/webengine/api/qquickwebengineloadrequest.cpp2
-rw-r--r--src/webengine/api/qquickwebenginenewviewrequest.cpp9
-rw-r--r--src/webengine/api/qquickwebenginenewviewrequest_p.h2
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp310
-rw-r--r--src/webengine/api/qquickwebengineprofile.h159
-rw-r--r--src/webengine/api/qquickwebengineprofile_p.h99
-rw-r--r--src/webengine/api/qquickwebenginescript.cpp1
-rw-r--r--src/webengine/api/qquickwebenginescript_p.h4
-rw-r--r--src/webengine/api/qquickwebenginesettings.cpp55
-rw-r--r--src/webengine/api/qquickwebenginesettings_p.h10
-rw-r--r--src/webengine/api/qquickwebenginesingleton.cpp38
-rw-r--r--src/webengine/api/qquickwebenginetestsupport_p.h4
-rw-r--r--src/webengine/api/qquickwebengineview.cpp493
-rw-r--r--src/webengine/api/qquickwebengineview_p.h96
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h20
-rw-r--r--src/webengine/api/qtwebengineglobal.cpp62
-rw-r--r--src/webengine/doc/images/qtwebengine-architecture.pngbin0 -> 11325 bytes
-rw-r--r--src/webengine/doc/qtwebengine.qdocconf48
-rw-r--r--src/webengine/doc/src/external-resources.qdoc63
-rw-r--r--src/webengine/doc/src/qtwebengine-debugging.qdoc74
-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.qdoc67
-rw-r--r--src/webengine/doc/src/qtwebengine-modules.qdoc48
-rw-r--r--src/webengine/doc/src/qtwebengine-overview.qdoc211
-rw-r--r--src/webengine/doc/src/qtwebengine-platform-notes.qdoc119
-rw-r--r--src/webengine/doc/src/qtwebengine-qmlmodule.qdoc45
-rw-r--r--src/webengine/doc/src/webengineview.qdoc (renamed from src/webengine/doc/src/qquickwebengineview_lgpl.qdoc)423
-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.cpp28
-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.cpp34
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.h3
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.h1
-rw-r--r--src/webengine/ui/AuthenticationDialog.qml122
-rw-r--r--src/webengine/ui/ui.pro2
-rw-r--r--src/webengine/ui_delegates_manager.cpp135
-rw-r--r--src/webengine/ui_delegates_manager.h38
-rw-r--r--src/webengine/webengine.pro8
-rw-r--r--src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp8
-rw-r--r--src/webenginewidgets/api/qwebenginecertificateerror.h6
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem.cpp12
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem.h7
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem_p.h1
-rw-r--r--src/webenginewidgets/api/qwebenginefullscreenrequest.cpp69
-rw-r--r--src/webenginewidgets/api/qwebenginefullscreenrequest.h67
-rw-r--r--src/webenginewidgets/api/qwebenginehistory.cpp10
-rw-r--r--src/webenginewidgets/api/qwebenginehistory.h4
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp588
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h75
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h68
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp210
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.h27
-rw-r--r--src/webenginewidgets/api/qwebengineprofile_p.h7
-rw-r--r--src/webenginewidgets/api/qwebenginescript.cpp94
-rw-r--r--src/webenginewidgets/api/qwebenginescript.h9
-rw-r--r--src/webenginewidgets/api/qwebenginescriptcollection.cpp64
-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.cpp27
-rw-r--r--src/webenginewidgets/api/qwebengineview.h5
-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.qdoc61
-rw-r--r--src/webenginewidgets/doc/src/qwebenginehistory_lgpl.qdoc46
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc226
-rw-r--r--src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc4
-rw-r--r--src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc121
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp25
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h3
-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.pro5
-rw-r--r--tests/auto/core/qwebenginecookiestore/qwebenginecookiestore.pro1
-rw-r--r--tests/auto/core/qwebenginecookiestore/resources/content.html5
-rw-r--r--tests/auto/core/qwebenginecookiestore/resources/index.html38
-rw-r--r--tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp202
-rw-r--r--tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.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.cpp274
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc7
-rw-r--r--tests/auto/core/tests.pri15
-rw-r--r--tests/auto/quick/inspectorserver/tst_inspectorserver.cpp2
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp217
-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.js (renamed from examples/webenginewidgets/browser/main.cpp)26
-rw-r--r--tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml (renamed from examples/webenginewidgets/browser/featurepermissionbar.h)66
-rw-r--r--tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_download.qml12
-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.qml4
-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.qml (renamed from examples/webenginewidgets/browser/edittreeview.h)34
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/qmldir1
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml (renamed from examples/webenginewidgets/browser/squeezelabel.h)26
-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.cpp123
-rw-r--r--tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp17
-rw-r--r--tests/auto/quick/quick.pro3
-rw-r--r--tests/auto/widgets/positionplugin/plugin.cpp112
-rw-r--r--tests/auto/widgets/positionplugin/plugin.json9
-rw-r--r--tests/auto/widgets/positionplugin/positionplugin.pro12
-rw-r--r--tests/auto/widgets/qwebengineaccessibility/BLACKLIST6
-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/BLACKLIST5
-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.cpp1803
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc9
-rw-r--r--tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp98
-rw-r--r--tests/auto/widgets/qwebenginescript/qwebenginescript.pro1
-rw-r--r--tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp29
-rw-r--r--tests/auto/widgets/qwebenginesettings/qwebenginesettings.pro2
-rw-r--r--tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp63
-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.pri6
-rw-r--r--tests/auto/widgets/util.h5
-rw-r--r--tests/auto/widgets/widgets.pro9
-rw-r--r--tests/quicktestbrowser/ApplicationRoot.qml2
-rw-r--r--tests/quicktestbrowser/BrowserWindow.qml20
-rw-r--r--tests/quicktestbrowser/FullScreenNotification.qml99
-rw-r--r--tests/quicktestbrowser/main.cpp15
-rw-r--r--tests/quicktestbrowser/quicktestbrowser.pro3
-rw-r--r--tests/quicktestbrowser/resources.qrc1
-rwxr-xr-xtools/buildscripts/gyp_qtwebengine20
-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.prf91
-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.py9
453 files changed, 18546 insertions, 7461 deletions
diff --git a/.gitignore b/.gitignore
index d3e523f3a..ab40b145a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,14 +5,16 @@ 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
examples/webengine/quicknanobrowser/quicknanobrowser.app
examples/webenginewidgets/browser/browser
examples/webenginewidgets/browser/browser.app
-examples/webenginewidgets/fancybrowser/fancybrowser
-examples/webenginewidgets/fancybrowser/fancybrowser.app
+examples/webenginewidgets/contentmanipulation/contentmanipulation
+examples/webenginewidgets/contentmanipulation/contentmanipulation.app
tests/quicktestbrowser/quicktestbrowser
tests/**/tst_*
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/dist/changes-5.6.0 b/dist/changes-5.6.0
new file mode 100644
index 000000000..f6495942a
--- /dev/null
+++ b/dist/changes-5.6.0
@@ -0,0 +1,74 @@
+Qt 5.6 introduces many new features and improvements as well as bugfixes
+over the 5.5.x series. For more details, refer to the online documentation
+included in this distribution. The documentation is also available online:
+
+ http://doc.qt.io/qt-5/index.html
+
+The Qt version 5.6 series is binary compatible with the 5.5.x series.
+Applications compiled for 5.5 will continue to run with 5.6.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+ https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* General *
+****************************************************************************
+
+ - Chromium Snapshot:
+ * The Chromium version has been updated to 45.0.2554.101.
+ * In addition security fixes from Chromium 46, 47 and 48 have been merged.
+
+ - General:
+ * The WebEngineCore module now contains shared C++ API.
+ * Will now follow Qt Network application proxy settings.
+
+ - Platforms:
+ * Linux builds can now link against system libraries instead of Chromium's
+ bundled versions.
+ * Support for the Aarch64 architecture.
+
+ - Web Features:
+ * PPAPI plugins are now supported, including the Flash plugin.
+
+****************************************************************************
+* Qt WebEngineCore *
+****************************************************************************
+
+ - QWebEngineCookieStore:
+ * A new API for monitoring and controlling cookies.
+
+ - QWebEngineUrlRequestInterceptor:
+ * A new API for blocking, modifying or redirecting URL requests.
+
+ - QWebEngineUrlSchemeHandler:
+ * A new API for implementing custom URL schemes.
+
+****************************************************************************
+* Qt WebEngineQML *
+****************************************************************************
+
+ - QQuickWebEngineProfile:
+ * Now a public C++ API for use with the new core APIs.
+
+ - QQuickWebEngineView:
+ * WebAction API added.
+
+
+****************************************************************************
+* Qt WebEngineWidgets *
+****************************************************************************
+
+ - QWebEnginePage:
+ * More WebActions added from the old QWebPage API.
+
+****************************************************************************
+* Examples *
+****************************************************************************
+
+ - General:
+ * Examples have been renamed to make their purpose more clear.
diff --git a/examples/examples.pro b/examples/examples.pro
index 3d6872d55..fdd25664f 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -6,6 +6,7 @@ qtHaveModule(webengine) {
qtHaveModule(webenginewidgets) {
SUBDIRS += \
- webenginewidgets/browser \
- webenginewidgets/fancybrowser
+ webenginewidgets/contentmanipulation \
+ webenginewidgets/demobrowser \
+ webenginewidgets/markdowneditor
}
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..ed49040ca 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
@@ -54,16 +54,6 @@ ApplicationWindow {
property Item currentWebView: tabs.currentIndex < tabs.count ? tabs.getTab(tabs.currentIndex).item : null
property int previousVisibility: Window.Windowed
- property bool isFullScreen: visibility == Window.FullScreen
- onIsFullScreenChanged: {
- // This is for the case where the system forces us to leave fullscreen.
- if (currentWebView && !isFullScreen) {
- currentWebView.state = ""
- if (currentWebView.isFullScreen)
- currentWebView.fullScreenCancelled()
- }
- }
-
width: 1300
height: 900
visible: true
@@ -82,6 +72,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 +91,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,19 +107,19 @@ 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 {
shortcut: "Escape"
onTriggered: {
- if (browserWindow.isFullScreen)
+ if (currentWebView.state == "FullScreen") {
browserWindow.visibility = browserWindow.previousVisibility
+ fullScreenNotification.hide()
+ currentWebView.triggerWebAction(WebEngineView.ExitFullScreen);
+ }
}
}
Action {
@@ -135,14 +127,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 +259,18 @@ ApplicationWindow {
checked: WebEngine.settings.errorPageEnabled
}
MenuItem {
+ id: pluginsEnabled
+ text: "Plugins On"
+ checkable: true
+ checked: true
+ }
+ MenuItem {
+ id: fullScreenSupportEnabled
+ text: "FullScreen On"
+ checkable: true
+ checked: WebEngine.settings.fullScreenSupportEnabled
+ }
+ MenuItem {
id: offTheRecordEnabled
text: "Off The Record"
checkable: true
@@ -312,6 +353,8 @@ ApplicationWindow {
settings.autoLoadImages: appSettings.autoLoadImages
settings.javascriptEnabled: appSettings.javaScriptEnabled
settings.errorPageEnabled: appSettings.errorPageEnabled
+ settings.pluginsEnabled: appSettings.pluginsEnabled
+ settings.fullScreenSupportEnabled: appSettings.fullScreenSupportEnabled
onCertificateError: {
error.defer()
@@ -342,12 +385,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 +463,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..3643cfce7 100644
--- a/examples/webengine/quicknanobrowser/doc/src/quicknanobrowser.qdoc
+++ b/examples/webengine/quicknanobrowser/doc/src/quicknanobrowser.qdoc
@@ -26,16 +26,114 @@
****************************************************************************/
/*!
- \example quicknanobrowser
+ \example webengine/quicknanobrowser
\title WebEngine Quick Nano Browser
\ingroup webengine-examples
\brief A web browser implemented using the WebEngineView QML type.
- The Quick Nano Browser demo shows the \l{Qt WebEngine} module in action,
- providing a little QML web browser with support for tabs and keyboard
- shortcuts.
-
\image quicknanobrowser-demo.jpg
+ \e {Quick Nano Browser} demonstrates how to use the \l{Qt WebEngine QML Types}
+ {Qt WebEngine QML types} to develop a small web browser application that consists of a browser
+ window with a title bar, toolbar, tab view, and status bar. The web content is loaded in a web
+ engine view within the tab view. If certificate errors occur, users are prompted for action in a
+ message dialog. The status bar pops up to display the URL of a hovered link.
+
+ A web page can issue a request for being displayed in fullscreen mode. Users can allow full
+ screen mode by using a toolbar button. They can leave fullscreen mode by using a keyboard
+ shortcut. Additional toolbar buttons enable moving backwards and forwards in the browser
+ history, reloading tab content, and opening a settings menu for enabling the following features:
+ JavaScript, plugins, fullscreen mode, off the record, HTTP disc cache, autoloading images, and
+ ignoring certificate errors.
+
\include examples-run.qdocinc
+
+ \section1 Creating the Main Browser Window
+
+ When the browser main window is loaded, it creates an empty tab using the default profile. Each
+ tab is a web engine view that fills the main window.
+
+ We create the main window in the \e BrowserWindow.qml file using the ApplicationWindow type:
+
+ \quotefromfile webengine/quicknanobrowser/BrowserWindow.qml
+ \skipto ApplicationWindow
+ \printuntil currentWebView
+ \dots
+ \skipto width
+ \printuntil title
+
+ We use the TabView Qt Quick control to create an empty tab view that fills the main window. We
+ set the tab active first, to make sure that the tab item is immediately instantiated:
+
+ \skipto TabView
+ \printuntil Component.onCompleted
+
+ The tab contains a web engine view that loads web content:
+
+ \printuntil focus
+
+ We use the \l Action type to create new tabs:
+
+ \quotefromfile webengine/quicknanobrowser/BrowserWindow.qml
+ \skipto reload
+ \skipto Action
+ \printuntil }
+
+ We use the \l TextField Qt Quick Control within a \l ToolBar to create an address bar that
+ shows the current URL and where users can enter another URL:
+
+ \skipto toolBar
+ \printuntil anchors.fill
+ \dots
+ \skipto TextField
+ \printuntil addressBar
+ \dots
+ \skipto focus
+ \printuntil /^\ {16}\}/
+
+ \section1 Handling Certificate Errors
+
+ If the certificate of the site being loaded triggers a certificate error, we call the
+ \l{WebEngineCertificateError::}{defer()} QML method to pause the URL request and wait for user
+ input:
+
+ \quotefromfile webengine/quicknanobrowser/BrowserWindow.qml
+ \skipto onCertificateError
+ \printuntil }
+
+ We use the MessageDialog type to prompt users to continue or cancel the loading of the web page.
+ If users select \uicontrol Yes, we call the
+ \l{WebEngineCertificateError::}{ignoreCertificateError()} method to ignore the error and
+ continue loading content from the URL. If users select \uicontrol No, we call the
+ \l{WebEngineCertificateError::}{rejectCertificate()} method to reject the request and stop
+ loading content from the URL:
+
+ \skipto MessageDialog
+ \printuntil /^\ {4}\}/
+
+ \section1 Entering and Leaving Fullscreen Mode
+
+ We create a menu item for allowing fullscreen mode in a settings menu that we place on the tool
+ bar. Also, we create an action for leaving fullscreen mode by using a keyboard shortcut.
+ We call the \l{WebEngineFullScreenRequest::}{accept()} method to accept the fullscreen request.
+ The methdod sets the \l{WebEngineView::}{isFullScreen} property to be equal to the
+ \l{WebEngineFullScreenRequest::}{toggleOn} property.
+
+ \quotefromfile webengine/quicknanobrowser/BrowserWindow.qml
+ \skipto onFullScreenRequested
+ \printuntil /^\ {16}\}/
+
+ When entering fullscreen mode, we display a notification using the FullScreenNotification custom
+ type that we create in \e FullScreenNotification.qml.
+
+ We use the \l Action type in the settings menu to create a shortcut for leaving fullscreen mode
+ by pressing the escape key:
+
+ \quotefromfile webengine/quicknanobrowser/BrowserWindow.qml
+ \skipto Settings
+ \printuntil appSettings
+ \skipto fullScreenSupportEnabled
+ \printuntil Action
+ \skipto Escape
+ \printuntil /^\ {4}\}/
*/
diff --git a/examples/webengine/quicknanobrowser/main.cpp b/examples/webengine/quicknanobrowser/main.cpp
index 455c409a1..b7ab03699 100644
--- a/examples/webengine/quicknanobrowser/main.cpp
+++ b/examples/webengine/quicknanobrowser/main.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
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/webengine/quicknanobrowser/utils.h b/examples/webengine/quicknanobrowser/utils.h
index 0f4460dfe..84cac6363 100644
--- a/examples/webengine/quicknanobrowser/utils.h
+++ b/examples/webengine/quicknanobrowser/utils.h
@@ -1,43 +1,43 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 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.
-**
+** This file is part of the examples 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$
**
****************************************************************************/
+
#ifndef UTILS_H
#define UTILS_H
diff --git a/examples/webenginewidgets/browser/autosaver.cpp b/examples/webenginewidgets/browser/autosaver.cpp
deleted file mode 100644
index dc72090dd..000000000
--- a/examples/webenginewidgets/browser/autosaver.cpp
+++ /dev/null
@@ -1,93 +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 "autosaver.h"
-
-#include <QtCore/QDir>
-#include <QtCore/QCoreApplication>
-#include <QtCore/QMetaObject>
-#include <QtDebug>
-
-#define AUTOSAVE_IN 1000 * 3 // seconds
-#define MAXWAIT 1000 * 15 // seconds
-
-AutoSaver::AutoSaver(QObject *parent) : QObject(parent)
-{
- Q_ASSERT(parent);
-}
-
-AutoSaver::~AutoSaver()
-{
- if (m_timer.isActive())
- qWarning() << "AutoSaver: still active when destroyed, changes not saved.";
-}
-
-void AutoSaver::changeOccurred()
-{
- if (m_firstChange.isNull())
- m_firstChange.start();
-
- if (m_firstChange.elapsed() > MAXWAIT) {
- saveIfNeccessary();
- } else {
- m_timer.start(AUTOSAVE_IN, this);
- }
-}
-
-void AutoSaver::timerEvent(QTimerEvent *event)
-{
- if (event->timerId() == m_timer.timerId()) {
- saveIfNeccessary();
- } else {
- QObject::timerEvent(event);
- }
-}
-
-void AutoSaver::saveIfNeccessary()
-{
- if (!m_timer.isActive())
- return;
- m_timer.stop();
- m_firstChange = QTime();
- if (!QMetaObject::invokeMethod(parent(), "save", Qt::DirectConnection)) {
- qWarning() << "AutoSaver: error invoking slot save() on parent";
- }
-}
diff --git a/examples/webenginewidgets/browser/autosaver.h b/examples/webenginewidgets/browser/autosaver.h
deleted file mode 100644
index b0c73846f..000000000
--- a/examples/webenginewidgets/browser/autosaver.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 AUTOSAVER_H
-#define AUTOSAVER_H
-
-#include <QtCore/QObject>
-#include <QtCore/QBasicTimer>
-#include <QtCore/QTime>
-
-/*
- This class will call the save() slot on the parent object when the parent changes.
- It will wait several seconds after changed() to combining multiple changes and
- prevent continuous writing to disk.
- */
-class AutoSaver : public QObject {
-
-Q_OBJECT
-
-public:
- AutoSaver(QObject *parent);
- ~AutoSaver();
- void saveIfNeccessary();
-
-public slots:
- void changeOccurred();
-
-protected:
- void timerEvent(QTimerEvent *event);
-
-private:
- QBasicTimer m_timer;
- QTime m_firstChange;
-
-};
-
-#endif // AUTOSAVER_H
diff --git a/examples/webenginewidgets/browser/browser.icns b/examples/webenginewidgets/browser/browser.icns
deleted file mode 100644
index f591ae48a..000000000
--- a/examples/webenginewidgets/browser/browser.icns
+++ /dev/null
Binary files differ
diff --git a/examples/webenginewidgets/browser/browser.ico b/examples/webenginewidgets/browser/browser.ico
deleted file mode 100644
index 7f9be934d..000000000
--- a/examples/webenginewidgets/browser/browser.ico
+++ /dev/null
Binary files differ
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/browserapplication.h b/examples/webenginewidgets/browser/browserapplication.h
deleted file mode 100644
index 26557b8f9..000000000
--- a/examples/webenginewidgets/browser/browserapplication.h
+++ /dev/null
@@ -1,127 +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 BROWSERAPPLICATION_H
-#define BROWSERAPPLICATION_H
-
-#include <QtWidgets/QApplication>
-
-#include <QtCore/QUrl>
-#include <QtCore/QPointer>
-
-#include <QtGui/QIcon>
-
-QT_BEGIN_NAMESPACE
-class QLocalServer;
-class QNetworkAccessManager;
-class QWebEngineProfile;
-QT_END_NAMESPACE
-
-class BookmarksManager;
-class BrowserMainWindow;
-class CookieJar;
-class DownloadManager;
-class HistoryManager;
-class BrowserApplication : public QApplication
-{
- Q_OBJECT
-
-public:
- BrowserApplication(int &argc, char **argv);
- ~BrowserApplication();
- static BrowserApplication *instance();
- void loadSettings();
-
- bool isTheOnlyBrowser() const;
- BrowserMainWindow *mainWindow();
- QList<BrowserMainWindow*> mainWindows();
- QIcon icon(const QUrl &url) const;
- QIcon defaultIcon() const;
-
- void saveSession();
- bool canRestoreSession() const;
- bool privateBrowsing() const { return m_privateBrowsing; }
-
- static HistoryManager *historyManager();
- static CookieJar *cookieJar();
- static DownloadManager *downloadManager();
- static QNetworkAccessManager *networkAccessManager();
- static BookmarksManager *bookmarksManager();
-
-#if defined(Q_OS_OSX)
- bool event(QEvent *event);
-#endif
-
-public slots:
- BrowserMainWindow *newMainWindow();
- void restoreLastSession();
-#if defined(Q_OS_OSX)
- void lastWindowClosed();
- void quitBrowser();
-#endif
- void setPrivateBrowsing(bool);
-
-signals:
- void privateBrowsingChanged(bool);
-
-private slots:
- void postLaunch();
- void openUrl(const QUrl &url);
- void newLocalSocketConnection();
-
-private:
- void clean();
- void installTranslator(const QString &name);
-
- static HistoryManager *s_historyManager;
- static DownloadManager *s_downloadManager;
- static QNetworkAccessManager *s_networkAccessManager;
- static BookmarksManager *s_bookmarksManager;
-
- QList<QPointer<BrowserMainWindow> > m_mainWindows;
- QLocalServer *m_localServer;
- QByteArray m_lastSession;
- QWebEngineProfile *m_privateProfile;
- bool m_privateBrowsing;
- mutable QIcon m_defaultIcon;
-};
-
-#endif // BROWSERAPPLICATION_H
diff --git a/examples/webenginewidgets/browser/chasewidget.h b/examples/webenginewidgets/browser/chasewidget.h
deleted file mode 100644
index a90389034..000000000
--- a/examples/webenginewidgets/browser/chasewidget.h
+++ /dev/null
@@ -1,85 +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 CHASEWIDGET_H
-#define CHASEWIDGET_H
-
-#include <QtWidgets/QWidget>
-
-#include <QtCore/QSize>
-#include <QtGui/QColor>
-#include <QtGui/QPixmap>
-
-QT_BEGIN_NAMESPACE
-class QHideEvent;
-class QShowEvent;
-class QPaintEvent;
-class QTimerEvent;
-QT_END_NAMESPACE
-
-class ChaseWidget : public QWidget
-{
- Q_OBJECT
-public:
- ChaseWidget(QWidget *parent = 0, QPixmap pixmap = QPixmap(), bool pixmapEnabled = false);
-
- void setAnimated(bool value);
- void setPixmapEnabled(bool enable);
- QSize sizeHint() const;
-
-protected:
- void paintEvent(QPaintEvent *event);
- void timerEvent(QTimerEvent *event);
-
-private:
- int segmentCount() const;
- QColor colorForSegment(int segment) const;
-
- int m_segment;
- int m_delay;
- int m_step;
- int m_timerId;
- bool m_animated;
- QPixmap m_pixmap;
- bool m_pixmapEnabled;
-};
-
-#endif
diff --git a/examples/webenginewidgets/browser/data/browser.svg b/examples/webenginewidgets/browser/data/browser.svg
deleted file mode 100644
index 2127a0a6e..000000000
--- a/examples/webenginewidgets/browser/data/browser.svg
+++ /dev/null
@@ -1,411 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="48px"
- height="48px"
- 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"
- inkscape:output_extension="org.inkscape.output.svg.inkscape">
- <defs
- id="defs2162"><linearGradient
- id="linearGradient3808">
- <stop
- id="stop3810"
- offset="0"
- style="stop-color:#000000;stop-opacity:0.54263568;" />
- <stop
- id="stop3812"
- offset="1"
- style="stop-color:#000000;stop-opacity:0;" />
-</linearGradient>
-<inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="0 : 24 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="48 : 24 : 1"
- inkscape:persp3d-origin="24 : 16 : 1"
- id="perspective63" />
-<linearGradient
- id="linearGradient3326">
- <stop
- style="stop-color:#000000;stop-opacity:0.3137255;"
- offset="0"
- id="stop3328" />
- <stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="1"
- id="stop3330" />
-</linearGradient>
-<linearGradient
- id="linearGradient3318">
- <stop
- style="stop-color:#000000;stop-opacity:0.3137255;"
- offset="0"
- id="stop3320" />
- <stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="1"
- id="stop3322" />
-</linearGradient>
-<linearGradient
- id="linearGradient3302">
- <stop
- style="stop-color:#000000;stop-opacity:0.3137255;"
- offset="0"
- id="stop3304" />
- <stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="1"
- id="stop3306" />
-</linearGradient>
-<linearGradient
- id="linearGradient3267">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop3269" />
- <stop
- id="stop3275"
- offset="0.79661018"
- style="stop-color:#000000;stop-opacity:1;" />
- <stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="1"
- id="stop3271" />
-</linearGradient>
-<linearGradient
- id="linearGradient3745">
- <stop
- style="stop-color:#ffffff;stop-opacity:0.19587629;"
- offset="0"
- id="stop3747" />
- <stop
- style="stop-color:#7cb2ff;stop-opacity:0.07216495;"
- offset="1"
- id="stop3749" />
-</linearGradient>
-<linearGradient
- inkscape:collect="always"
- id="linearGradient3561">
- <stop
- style="stop-color:#b1d0ff;stop-opacity:1;"
- offset="0"
- id="stop3563" />
- <stop
- style="stop-color:#b1d0ff;stop-opacity:0;"
- offset="1"
- id="stop3565" />
-</linearGradient>
-<linearGradient
- id="linearGradient3181">
- <stop
- style="stop-color:#4f7a33;stop-opacity:1;"
- offset="0"
- id="stop3183" />
- <stop
- style="stop-color:#204712;stop-opacity:1;"
- offset="1"
- id="stop3185" />
-</linearGradient>
-<linearGradient
- id="linearGradient3143">
- <stop
- style="stop-color:#c1dbff;stop-opacity:1;"
- offset="0"
- id="stop3145" />
- <stop
- style="stop-color:#004e92;stop-opacity:1;"
- offset="1"
- id="stop3147" />
-</linearGradient>
-<radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3143"
- id="radialGradient3149"
- cx="9.1428566"
- cy="15.142858"
- fx="9.1428566"
- fy="15.142858"
- r="20.121096"
- gradientUnits="userSpaceOnUse" />
-<radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3181"
- id="radialGradient3187"
- cx="10.739879"
- cy="18.250999"
- fx="10.739879"
- fy="18.250999"
- r="7.4191086"
- gradientTransform="matrix(1.0504709,0,0,1.5077925,-0.3797113,-9.2677171)"
- gradientUnits="userSpaceOnUse" />
-<radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3181"
- id="radialGradient3195"
- cx="14.947268"
- cy="35.920116"
- fx="14.947268"
- fy="35.920116"
- r="6.0472684"
- gradientTransform="matrix(1,0,0,0.7248478,0,9.8834985)"
- gradientUnits="userSpaceOnUse" />
-<radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3181"
- id="radialGradient3203"
- cx="34.227203"
- cy="24.681196"
- fx="34.227203"
- fy="24.681196"
- r="6.7517419"
- gradientTransform="matrix(0.9941509,-0.1079997,0.2962199,2.7267411,-7.1108629,-38.921508)"
- gradientUnits="userSpaceOnUse" />
-<radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3561"
- id="radialGradient3567"
- cx="22.714285"
- cy="23.571428"
- fx="22.714285"
- fy="23.571428"
- r="19.828572"
- gradientUnits="userSpaceOnUse" />
-<linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3745"
- id="linearGradient3751"
- x1="0.84126461"
- y1="13.678415"
- x2="31.397495"
- y2="13.678415"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.8791332,0.7829527,-0.6285195,1.0951445,14.147627,-10.49311)" />
-<filter
- inkscape:collect="always"
- id="filter4176">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.27747502"
- id="feGaussianBlur4178" />
-</filter>
-<radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3267"
- id="radialGradient3273"
- cx="22.714285"
- cy="23.571428"
- fx="22.714285"
- fy="23.571428"
- r="19.428572"
- gradientUnits="userSpaceOnUse" />
-<inkscape:perspective
- id="perspective136"
- inkscape:persp3d-origin="138.6795 : 92.479329 : 1"
- inkscape:vp_z="277.35901 : 138.71899 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 138.71899 : 1"
- sodipodi:type="inkscape:persp3d" />
-
-
-
-
-
-
-
-
-
-
-<linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3808"
- id="linearGradient3806"
- x1="32.829472"
- y1="32.055603"
- x2="34.522324"
- y2="-1.0290829"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.8832227,0,0,1,-8.0103007,9.1923882)" />
-</defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="5.6568542"
- inkscape:cx="30.924085"
- inkscape:cy="24.59691"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:grid-bbox="true"
- inkscape:document-units="px"
- inkscape:window-width="1299"
- inkscape:window-height="883"
- inkscape:window-x="373"
- inkscape:window-y="89"
- showguides="false" />
- <metadata
- id="metadata2165">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title>Qt Browser</dc:title>
- <dc:creator>
- <cc:Agent>
- <dc:title>Jens Bache-Wiig</dc:title>
- </cc:Agent>
- </dc:creator>
- <dc:rights>
- <cc:Agent>
- <dc:title>Copyright (C) 2015 The Qt Company Ltd.</dc:title>
- </cc:Agent>
- </dc:rights>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- id="layer1"
- inkscape:label="Layer 1"
- inkscape:groupmode="layer">
- <path
- sodipodi:type="arc"
- style="opacity:0.78108437;fill:url(#radialGradient3273);fill-opacity:1;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="path3407"
- sodipodi:cx="22.714285"
- sodipodi:cy="23.571428"
- sodipodi:rx="19.428572"
- sodipodi:ry="19.428572"
- d="M 42.142857,23.571428 A 19.428572,19.428572 0 1 1 3.2857132,23.571428 A 19.428572,19.428572 0 1 1 42.142857,23.571428 z"
- transform="matrix(1.0818892,0,0,1.0409446,-2.4313375,0.4303723)" />
- <path
- sodipodi:type="arc"
- style="fill:url(#radialGradient3149);fill-opacity:1;stroke:none;stroke-width:0.80000000000000004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="path2170"
- sodipodi:cx="22.714285"
- sodipodi:cy="23.571428"
- sodipodi:rx="19.428572"
- sodipodi:ry="19.428572"
- d="M 42.142857 23.571428 A 19.428572 19.428572 0 1 1 3.2857132,23.571428 A 19.428572 19.428572 0 1 1 42.142857 23.571428 z" />
- <path
- d="M 26.602136,8.2160843 C 26.322653,8.1637524 26.048884,8.1512446 25.78375,8.1745351 L 25.783243,8.1743913 C 25.783243,8.1743913 23.973525,8.3138471 23.891496,8.3211793 C 22.239361,8.4705552 20.985434,10.008307 20.985434,12.131916 L 20.985434,37.174579 L 22.83515,39.126673 L 41.425135,33.998394 C 42.704203,33.746799 43.714709,33.629384 43.714709,31.78483 L 43.714709,11.392226 L 26.602136,8.2160843 z"
- id="path2998"
- style="fill:url(#linearGradient3806);fill-opacity:1"
- sodipodi:nodetypes="cccsccccccc" />
- <path
- style="fill:url(#radialGradient3203);fill-opacity:1;fill-rule:evenodd;stroke:#1d3215;stroke-width:0.51392877000000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 37.535517,11.721122 C 32.782916,8.7478602 30.602351,6.3542385 32.09957,13.4346 C 32.320572,14.27055 33.291276,13.739232 33.291276,14.862228 C 33.291276,16.155819 32.607502,17.380765 31.797574,18.146663 C 30.959323,18.939344 31.011357,20.258984 31.797574,21.002459 C 33.06234,22.198469 33.942515,22.715936 35.572536,22.715936 C 36.6448,22.715936 37.003629,23.274262 37.23352,24.143834 C 37.362263,24.630808 38.410486,25.085663 38.894503,25.428942 C 38.938905,25.460433 38.139512,26.551348 38.139512,27.999158 C 38.139512,29.113512 38.405167,29.358325 38.743505,29.998215 C 38.949111,30.387072 36.418877,30.283794 36.025532,30.283794 C 35.005751,30.283794 34.181701,30.712163 33.15656,30.712163 C 32.264543,30.712163 31.099578,30.3566 31.344578,31.283323 C 31.763542,32.868074 32.552566,33.932342 32.552566,35.709806 C 32.552566,36.862272 31.047367,37.598377 30.287588,38.137232 C 29.30273,38.835721 29.133207,39.307154 28.475606,40.136289 C 28.132145,40.569341 26.990548,41.409612 28.475606,40.707448 C 29.476144,40.234375 31.192063,39.423774 32.09957,38.565601 C 33.257846,37.470293 34.527421,37.269266 35.723534,36.138176 C 36.659137,35.253436 37.512933,34.691155 38.29051,33.710749 C 39.024031,32.785889 39.498498,31.90347 39.498498,30.712163 C 39.498498,29.682482 39.308098,28.750366 39.951493,28.141948 C 40.902684,24.235856 42.225874,19.789742 39.751646,16.005086 C 38.569376,15.014407 37.717516,13.109859 37.535517,11.721122 z "
- id="path3151"
- sodipodi:nodetypes="ccsssssssssssssssssssccc" />
- <path
- style="fill:url(#radialGradient3187);fill-opacity:1;fill-rule:evenodd;stroke:#063a0a;stroke-width:0.51231807;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 14.777083,7.8630009 C 14.047432,8.4403746 12.751987,10.898939 13.27641,12.146301 C 13.709874,13.177316 14.920827,13.613143 15.827553,13.859622 C 16.568703,14.061091 17.049015,14.457271 17.478293,15.001835 C 17.832696,15.451415 17.971105,16.346745 18.078563,16.857932 C 18.298637,17.904845 18.947911,17.058563 17.62836,18.000145 C 17.234352,18.281296 14.875696,18.000145 14.476948,18.000145 C 11.976825,18.384083 14.297504,19.464893 14.92715,20.712903 C 15.204987,21.770261 15.377352,22.405336 15.377352,23.711213 C 15.377352,24.875672 15.377352,24.78389 15.377352,25.99564 C 15.377352,27.194757 15.044241,27.28063 13.876679,27.28063 C 13.023055,27.28063 12.647321,26.423969 11.625669,26.423969 C 10.400599,26.423969 11.303539,27.667106 11.475602,27.994513 C 12.006402,29.004538 11.662121,29.599737 10.875334,28.851174 C 9.855722,27.881096 8.8280305,26.760556 8.0240557,25.99564 C 2.8789379,25.807372 4.5677903,23.466499 3.9722395,18.999582 C 5.041259,16.526382 4.7558935,17.248897 7.2737194,12.574632 C 10.149914,9.5491592 13.589212,5.9532919 14.777083,7.8630009 z"
- id="path3159"
- sodipodi:nodetypes="csssssccsssssscccc" />
- <path
- style="fill:url(#radialGradient3195);fill-opacity:1;fill-rule:evenodd;stroke:#163c0c;stroke-width:0.59999999999999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 10.265966,34.571429 C 9.245427,35.081699 8.6225774,36.042538 9.980252,36.857143 C 10.637564,37.25153 11.478587,37.606311 12.265966,38 C 13.258976,38.496505 14.481138,39.018522 15.408823,39.714286 C 16.227572,40.328348 15.587589,39.928184 16.123109,38.857143 C 16.827927,37.447507 18.14516,38.79674 18.837395,39.142857 C 20.044787,39.746554 20.46001,38.652394 20.694537,37.714286 C 20.459863,35.791335 18.579948,34.625723 17.123109,33.285715 C 16.704922,32.588736 15.507117,31.689713 14.837395,31.857143 C 13.49505,33.304042 12.350312,33.960279 10.265966,34.571429 z "
- id="path3161"
- sodipodi:nodetypes="cssssscccc" />
- <path
- sodipodi:type="arc"
- style="fill:none;fill-opacity:1;stroke:url(#radialGradient3567);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.6502732"
- id="path3557"
- sodipodi:cx="22.714285"
- sodipodi:cy="23.571428"
- sodipodi:rx="19.428572"
- sodipodi:ry="19.428572"
- d="M 42.142857 23.571428 A 19.428572 19.428572 0 1 1 3.2857132,23.571428 A 19.428572 19.428572 0 1 1 42.142857 23.571428 z"
- transform="matrix(0.95317,0,0,0.95317,0.9922816,1.1752786)" />
- <path
- style="fill:url(#linearGradient3751);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 39.916926,27.786316 C 44.588637,26.790847 38.225604,13.201712 32.946381,8.5000566 C 18.135275,-0.40265528 10.844456,5.6490056 3.6645529,16.333771 C 5.7478288,18.189127 14.704728,33.158645 39.916926,27.786316 z"
- id="path3578"
- sodipodi:nodetypes="cccs" />
- <path
- d="M 45.902562,20.610592 C 46.007701,20.610592 46.120332,20.603354 46.240455,20.590275 L 45.609873,20.590275 C 45.697743,20.603608 45.798946,20.610592 45.902562,20.610592 z"
- id="path3012"
- style="fill:#0a6333" />
- <path
- sodipodi:type="arc"
- style="fill:none;fill-opacity:1;stroke:#273e5e;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="path3818"
- sodipodi:cx="22.714285"
- sodipodi:cy="23.571428"
- sodipodi:rx="19.428572"
- sodipodi:ry="19.428572"
- d="M 42.142857,23.571428 A 19.428572,19.428572 0 1 1 3.2857132,23.571428 A 19.428572,19.428572 0 1 1 42.142857,23.571428 z"
- transform="matrix(0.9754581,0,0,0.9754581,0.3821951,0.7002631)" />
- <g
- transform="matrix(0.1269799,0,0,0.1269799,23.283534,9.5774104)"
- id="g236">
- <path
- style="fill:#024c1c"
- id="path238"
- d="M 44.233,0.368 C 42.032,0.004 39.876,-0.083 37.788,0.079 L 37.784,0.078 C 37.784,0.078 23.532,1.048 22.886,1.099 C 9.875,2.138 0,12.834 0,27.605 L 0,201.792 L 14.567,215.37 L 160.968,190.766 C 171.041,189.016 178.999,177.133 178.999,164.303 L 178.999,22.46 L 44.233,0.368 z" />
-
- <path
- style="fill:#66b036"
- id="path240"
- d="M 179,164.304 C 179,177.134 171.042,189.017 160.969,190.767 L 14.567,215.37 L 14.567,26.683 C 14.567,9.52 28.263,-2.264 44.231,0.368 L 179,22.462 L 179,164.304 z" />
-
- <g
- id="g242">
- <path
- style="fill:#ffffff"
- id="path244"
- d="M 133.897,47.137 L 145.72,48.411 L 145.72,69.158 L 159.025,70.099 L 159.025,83.113 L 145.72,82.502 L 145.72,130.066 C 145.72,134.207 146.176,136.869 147.093,138.064 C 147.919,139.158 149.195,139.697 150.907,139.697 C 151.069,139.697 151.24,139.695 151.414,139.683 C 154.031,139.533 156.878,138.728 159.98,137.314 L 159.98,149.275 C 154.707,151.591 149.532,152.966 144.452,153.398 C 143.716,153.457 143.005,153.486 142.317,153.486 C 137.716,153.486 134.199,152.152 131.797,149.451 C 128.998,146.318 127.598,141.285 127.598,134.387 L 127.598,81.661 L 121.209,81.368 L 121.209,67.424 L 129,67.985 L 133.897,47.137 z" />
-
- </g>
-
- <polygon
- style="fill:#0a6333"
- id="polygon246"
- points="159.027,83.112 145.722,82.501 145.722,82.785 152.854,83.112 159.027,83.112 " />
-
- <path
- style="fill:#024c1c"
- id="path248"
- d="M 148.488,139.21 C 149.168,139.548 149.96,139.696 150.908,139.696 C 151.07,139.696 151.241,139.694 151.415,139.682 C 154.032,139.532 156.879,138.727 159.981,137.313 L 153.806,137.313 C 151.938,138.169 150.178,138.808 148.488,139.21 z" />
-
- <path
- style="fill:#024c1c"
- id="path250"
- d="M 133.897,47.137 L 127.723,47.137 L 122.93,67.549 L 129,67.985 L 133.897,47.137 z M 131.799,149.45 C 129,146.317 127.6,141.284 127.6,134.386 L 127.6,81.661 L 121.211,81.368 L 121.211,67.424 L 115.03,67.424 L 115.03,70.539 C 115.926,73.897 116.63,77.539 117.149,81.465 L 121.426,81.661 L 121.426,134.386 C 121.426,141.284 122.827,146.318 125.625,149.45 C 128.029,152.151 131.541,153.485 136.141,153.485 L 142.318,153.485 C 137.718,153.485 134.2,152.151 131.799,149.45 z" />
-
- <path
- style="fill:#0a6333"
- id="path252"
- d="M 102.954,170.419 C 103.782,170.419 104.669,170.362 105.615,170.259 L 100.649,170.259 C 101.341,170.364 102.138,170.419 102.954,170.419 z" />
-
- <path
- style="fill:#ffffff"
- id="path254"
- d="M 112.036,139.78 C 107.81,149.749 101.365,156.27 92.542,159.288 C 93.43,163.856 94.778,166.929 96.567,168.55 C 97.955,169.796 100.094,170.419 102.958,170.419 C 103.782,170.419 104.671,170.362 105.615,170.259 L 105.615,183.736 L 99.497,184.539 C 97.692,184.771 95.98,184.889 94.361,184.889 C 89.001,184.889 84.665,183.59 81.402,180.961 C 77.085,177.496 73.899,170.805 71.857,160.908 C 62.48,158.91 55.166,152.945 50.103,142.937 C 44.965,132.769 42.349,117.895 42.349,98.441 C 42.349,77.466 45.927,61.985 52.971,52.169 C 58.912,43.885 67.202,39.812 77.634,39.812 C 79.306,39.812 81.033,39.916 82.809,40.124 C 95.081,41.539 103.977,47.329 109.77,57.362 C 115.453,67.177 118.243,81.244 118.243,99.721 C 118.242,116.643 116.186,129.954 112.036,139.78 z M 93.582,135.933 C 95.996,129.724 97.189,117.54 97.189,99.37 C 97.189,83.054 96.007,71.837 93.608,65.682 C 91.21,59.496 87.622,56.153 82.808,55.731 C 82.441,55.7 82.075,55.681 81.724,55.681 C 77.264,55.681 73.84,58.283 71.447,63.508 C 68.863,69.201 67.555,81.003 67.555,98.866 C 67.555,116.129 68.826,128.379 71.388,135.569 C 73.804,142.419 77.423,145.813 82.174,145.813 C 82.384,145.813 82.593,145.805 82.809,145.79 C 87.566,145.489 91.148,142.202 93.582,135.933" />
-
- <path
- style="fill:#024c1c"
- id="path256"
- d="M 84.708,183.003 C 84.59,182.95 84.477,182.896 84.361,182.839 C 84.349,182.835 84.336,182.829 84.323,182.821 C 84.218,182.77 84.115,182.716 84.011,182.663 C 83.991,182.653 83.971,182.642 83.948,182.63 C 83.854,182.579 83.761,182.528 83.667,182.476 C 83.636,182.46 83.609,182.443 83.579,182.427 C 83.494,182.38 83.412,182.331 83.328,182.284 C 83.286,182.263 83.25,182.239 83.209,182.214 C 83.137,182.171 83.062,182.128 82.994,182.083 C 82.943,182.054 82.897,182.024 82.848,181.993 C 82.785,181.954 82.726,181.915 82.663,181.876 C 82.606,181.837 82.552,181.798 82.492,181.759 C 82.442,181.726 82.392,181.693 82.342,181.659 C 82.272,181.612 82.206,181.563 82.141,181.518 C 82.101,181.489 82.061,181.463 82.021,181.432 C 81.943,181.377 81.866,181.319 81.79,181.26 C 81.764,181.239 81.735,181.221 81.708,181.199 C 81.607,181.121 81.505,181.039 81.402,180.959 C 77.085,177.494 73.899,170.803 71.857,160.906 C 62.48,158.908 55.166,152.943 50.103,142.935 C 44.965,132.767 42.349,117.893 42.349,98.439 C 42.349,77.464 45.927,61.983 52.971,52.167 C 58.912,43.883 67.202,39.81 77.634,39.81 C 77.67,39.81 71.114,39.806 71.114,39.806 L 71.114,39.81 C 60.694,39.818 52.411,43.89 46.476,52.167 C 39.434,61.984 35.855,77.465 35.855,98.439 C 35.855,117.892 38.469,132.767 43.609,142.935 C 48.671,152.943 55.983,158.908 65.361,160.906 C 67.403,170.802 70.588,177.494 74.904,180.959 C 78.168,183.588 82.507,184.887 87.867,184.887 C 87.967,184.887 88.07,184.887 88.17,184.885 L 93.861,184.885 C 90.361,184.828 87.306,184.203 84.716,183.006 C 84.712,183.007 84.708,183.007 84.708,183.003 z M 87.113,65.681 C 89.511,71.837 90.69,83.054 90.69,99.369 C 90.69,117.539 89.502,129.723 87.083,135.932 C 85.142,140.942 82.439,144.047 79.013,145.248 C 79.999,145.621 81.058,145.81 82.173,145.81 C 82.383,145.81 82.592,145.802 82.808,145.787 C 87.567,145.488 91.149,142.201 93.582,135.932 C 95.996,129.723 97.189,117.539 97.189,99.369 C 97.189,83.053 96.007,71.836 93.608,65.681 C 91.21,59.495 87.622,56.152 82.808,55.73 C 82.441,55.699 82.075,55.68 81.724,55.68 C 80.601,55.68 79.549,55.845 78.556,56.173 L 78.556,56.175 L 78.556,56.175 C 82.254,57.322 85.104,60.5 87.113,65.681 z" />
-
-</g>
- </g>
-</svg>
diff --git a/examples/webenginewidgets/browser/doc/images/browser-demo.png b/examples/webenginewidgets/browser/doc/images/browser-demo.png
deleted file mode 100644
index 09d065095..000000000
--- a/examples/webenginewidgets/browser/doc/images/browser-demo.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginewidgets/browser/edittableview.cpp b/examples/webenginewidgets/browser/edittableview.cpp
deleted file mode 100644
index 866ee6f1f..000000000
--- a/examples/webenginewidgets/browser/edittableview.cpp
+++ /dev/null
@@ -1,77 +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 "edittableview.h"
-#include <QtGui/QKeyEvent>
-
-EditTableView::EditTableView(QWidget *parent)
- : QTableView(parent)
-{
-}
-
-void EditTableView::keyPressEvent(QKeyEvent *event)
-{
- if ((event->key() == Qt::Key_Delete
- || event->key() == Qt::Key_Backspace)
- && model()) {
- removeOne();
- } else {
- QAbstractItemView::keyPressEvent(event);
- }
-}
-
-void EditTableView::removeOne()
-{
- if (!model() || !selectionModel())
- return;
- int row = currentIndex().row();
- model()->removeRow(row, rootIndex());
- QModelIndex idx = model()->index(row, 0, rootIndex());
- if (!idx.isValid())
- idx = model()->index(row - 1, 0, rootIndex());
- selectionModel()->select(idx, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
-}
-
-void EditTableView::removeAll()
-{
- if (model())
- model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex());
-}
diff --git a/examples/webenginewidgets/browser/edittableview.h b/examples/webenginewidgets/browser/edittableview.h
deleted file mode 100644
index 315427eac..000000000
--- a/examples/webenginewidgets/browser/edittableview.h
+++ /dev/null
@@ -1,60 +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 EDITTABLEVIEW_H
-#define EDITTABLEVIEW_H
-
-#include <QtWidgets/QTableView>
-
-class EditTableView : public QTableView
-{
- Q_OBJECT
-
-public:
- EditTableView(QWidget *parent = 0);
- void keyPressEvent(QKeyEvent *event);
-
-public slots:
- void removeOne();
- void removeAll();
-};
-
-#endif // EDITTABLEVIEW_H
diff --git a/examples/webenginewidgets/browser/edittreeview.cpp b/examples/webenginewidgets/browser/edittreeview.cpp
deleted file mode 100644
index d515ea058..000000000
--- a/examples/webenginewidgets/browser/edittreeview.cpp
+++ /dev/null
@@ -1,76 +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 "edittreeview.h"
-
-#include <QtGui/QKeyEvent>
-
-EditTreeView::EditTreeView(QWidget *parent)
- : QTreeView(parent)
-{
-}
-
-void EditTreeView::keyPressEvent(QKeyEvent *event)
-{
- if ((event->key() == Qt::Key_Delete
- || event->key() == Qt::Key_Backspace)
- && model()) {
- removeOne();
- } else {
- QAbstractItemView::keyPressEvent(event);
- }
-}
-
-void EditTreeView::removeOne()
-{
- if (!model())
- return;
- QModelIndex ci = currentIndex();
- int row = ci.row();
- model()->removeRow(row, ci.parent());
-}
-
-void EditTreeView::removeAll()
-{
- if (!model())
- return;
- model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex());
-}
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/searchlineedit.h b/examples/webenginewidgets/browser/searchlineedit.h
deleted file mode 100644
index b8b8337fd..000000000
--- a/examples/webenginewidgets/browser/searchlineedit.h
+++ /dev/null
@@ -1,102 +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 SEARCHLINEEDIT_H
-#define SEARCHLINEEDIT_H
-
-#include "urllineedit.h"
-
-#include <QtWidgets/QLineEdit>
-#include <QtWidgets/QAbstractButton>
-
-QT_BEGIN_NAMESPACE
-class QMenu;
-QT_END_NAMESPACE
-
-class SearchButton;
-
-/*
- Clear button on the right hand side of the search widget.
- Hidden by default
- "A circle with an X in it"
- */
-class ClearButton : public QAbstractButton
-{
- Q_OBJECT
-
-public:
- ClearButton(QWidget *parent = 0);
- void paintEvent(QPaintEvent *event);
-
-public slots:
- void textChanged(const QString &text);
-};
-
-
-class SearchLineEdit : public ExLineEdit
-{
- Q_OBJECT
- Q_PROPERTY(QString inactiveText READ inactiveText WRITE setInactiveText)
-
-signals:
- void textChanged(const QString &text);
-
-public:
- SearchLineEdit(QWidget *parent = 0);
-
- QString inactiveText() const;
- void setInactiveText(const QString &text);
-
- QMenu *menu() const;
- void setMenu(QMenu *menu);
-
-protected:
- void resizeEvent(QResizeEvent *event);
- void paintEvent(QPaintEvent *event);
-
-private:
- void updateGeometries();
-
- SearchButton *m_searchButton;
- QString m_inactiveText;
-};
-
-#endif // SEARCHLINEEDIT_H
diff --git a/examples/webenginewidgets/browser/settings.h b/examples/webenginewidgets/browser/settings.h
deleted file mode 100644
index 6def66928..000000000
--- a/examples/webenginewidgets/browser/settings.h
+++ /dev/null
@@ -1,73 +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 SETTINGS_H
-#define SETTINGS_H
-
-#include <QtWidgets/QDialog>
-#include "ui_settings.h"
-
-class SettingsDialog : public QDialog, public Ui_Settings
-{
- Q_OBJECT
-
-public:
- SettingsDialog(QWidget *parent = 0);
- void accept();
-
-private slots:
- void loadDefaults();
- void loadFromSettings();
- void saveToSettings();
-
- void setHomeToCurrentPage();
- void showCookies();
- void showExceptions();
-
- void chooseFont();
- void chooseFixedFont();
-
-private:
- QFont standardFont;
- QFont fixedFont;
-};
-
-#endif // SETTINGS_H
diff --git a/examples/webenginewidgets/browser/squeezelabel.cpp b/examples/webenginewidgets/browser/squeezelabel.cpp
deleted file mode 100644
index 78198c3f0..000000000
--- a/examples/webenginewidgets/browser/squeezelabel.cpp
+++ /dev/null
@@ -1,60 +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 "squeezelabel.h"
-
-SqueezeLabel::SqueezeLabel(QWidget *parent) : QLabel(parent)
-{
-}
-
-void SqueezeLabel::paintEvent(QPaintEvent *event)
-{
- QFontMetrics fm = fontMetrics();
- if (fm.width(text()) > contentsRect().width()) {
- QString elided = fm.elidedText(text(), Qt::ElideMiddle, width());
- QString oldText = text();
- setText(elided);
- QLabel::paintEvent(event);
- setText(oldText);
- } else {
- QLabel::paintEvent(event);
- }
-}
diff --git a/examples/webenginewidgets/browser/toolbarsearch.h b/examples/webenginewidgets/browser/toolbarsearch.h
deleted file mode 100644
index cbe00366c..000000000
--- a/examples/webenginewidgets/browser/toolbarsearch.h
+++ /dev/null
@@ -1,83 +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 TOOLBARSEARCH_H
-#define TOOLBARSEARCH_H
-
-#include "searchlineedit.h"
-
-QT_BEGIN_NAMESPACE
-class QUrl;
-class QAction;
-class QStringListModel;
-QT_END_NAMESPACE
-
-class AutoSaver;
-
-class ToolbarSearch : public SearchLineEdit
-{
- Q_OBJECT
-
-signals:
- void search(const QUrl &url);
-
-public:
- ToolbarSearch(QWidget *parent = 0);
- ~ToolbarSearch();
-
-public slots:
- void clear();
- void searchNow();
-
-private slots:
- void save();
- void aboutToShowMenu();
- void triggeredMenuAction(QAction *action);
-
-private:
- void load();
-
- AutoSaver *m_autosaver;
- int m_maxSavedSearches;
- QStringListModel *m_stringListModel;
-};
-
-#endif // TOOLBARSEARCH_H
diff --git a/examples/webenginewidgets/browser/urllineedit.h b/examples/webenginewidgets/browser/urllineedit.h
deleted file mode 100644
index 775aa7d18..000000000
--- a/examples/webenginewidgets/browser/urllineedit.h
+++ /dev/null
@@ -1,114 +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 URLLINEEDIT_H
-#define URLLINEEDIT_H
-
-#include <QtCore/QUrl>
-#include <QtWidgets/QWidget>
-#include <QtWidgets/QStyleOptionFrame>
-
-QT_BEGIN_NAMESPACE
-class QLineEdit;
-QT_END_NAMESPACE
-
-class ClearButton;
-class ExLineEdit : public QWidget
-{
- Q_OBJECT
-
-public:
- ExLineEdit(QWidget *parent = 0);
-
- inline QLineEdit *lineEdit() const { return m_lineEdit; }
-
- void setLeftWidget(QWidget *widget);
- QWidget *leftWidget() const;
-
- QSize sizeHint() const;
-
- QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
-protected:
- void focusInEvent(QFocusEvent *event);
- void focusOutEvent(QFocusEvent *event);
- void keyPressEvent(QKeyEvent *event);
- void paintEvent(QPaintEvent *event);
- void resizeEvent(QResizeEvent *event);
- void inputMethodEvent(QInputMethodEvent *e);
- bool event(QEvent *event);
-
-protected:
- void updateGeometries();
- void initStyleOption(QStyleOptionFrameV2 *option) const;
-
- QWidget *m_leftWidget;
- QLineEdit *m_lineEdit;
- ClearButton *m_clearButton;
-};
-
-class UrlIconLabel;
-class WebView;
-class UrlLineEdit : public ExLineEdit
-{
- Q_OBJECT
-
-public:
- UrlLineEdit(QWidget *parent = 0);
- void setWebView(WebView *webView);
-
-protected:
- void paintEvent(QPaintEvent *event);
- void focusOutEvent(QFocusEvent *event);
-
-private slots:
- void webViewUrlChanged(const QUrl &url);
- void webViewIconChanged();
-
-private:
- QLinearGradient generateGradient(const QColor &color) const;
- WebView *m_webView;
- UrlIconLabel *m_iconLabel;
- QColor m_defaultBaseColor;
-
-};
-
-
-#endif // URLLINEEDIT_H
diff --git a/examples/webenginewidgets/fancybrowser/fancybrowser.pro b/examples/webenginewidgets/contentmanipulation/contentmanipulation.pro
index e5dcd9678..2ac97d487 100644
--- a/examples/webenginewidgets/fancybrowser/fancybrowser.pro
+++ b/examples/webenginewidgets/contentmanipulation/contentmanipulation.pro
@@ -6,5 +6,5 @@ SOURCES = main.cpp \
RESOURCES = jquery.qrc
# install
-target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/fancybrowser
-INSTALLS += target \ No newline at end of file
+target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/contentmanipulation
+INSTALLS += target
diff --git a/examples/webenginewidgets/fancybrowser/doc/images/fancybrowser-example.png b/examples/webenginewidgets/contentmanipulation/doc/images/contentmanipulation-example.png
index 717ac9ddc..717ac9ddc 100644
--- a/examples/webenginewidgets/fancybrowser/doc/images/fancybrowser-example.png
+++ b/examples/webenginewidgets/contentmanipulation/doc/images/contentmanipulation-example.png
Binary files differ
diff --git a/examples/webenginewidgets/fancybrowser/doc/src/fancybrowser.qdoc b/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc
index e6c6ada34..676173755 100644
--- a/examples/webenginewidgets/fancybrowser/doc/src/fancybrowser.qdoc
+++ b/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc
@@ -26,16 +26,16 @@
****************************************************************************/
/*!
- \example fancybrowser
- \title WebEngine Fancy Browser Example
+ \example webenginewidgets/contentmanipulation
+ \title WebEngine Content Manipulation Example
\ingroup webengine-widgetexamples
\brief Demonstrates how to use browse web and manipulate content
- \brief The Fancy Browser example shows how to use JQuery with QtWebEngine to
+ \brief The Content Manipulation example shows how to use JQuery with QtWebEngine to
create a web browser with special effects and content
manipulation.
- \image fancybrowser-example.png
+ \image contentmanipulation-example.png
The application makes use of QWebEnginePage::evaluateJavaScript to
evaluate the jQuery JavaScript code. A QMainWindow with a QWebEngineView
@@ -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/contentmanipulation/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/contentmanipulation/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/contentmanipulation/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/contentmanipulation/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/contentmanipulation/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/contentmanipulation/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/contentmanipulation/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/contentmanipulation/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/contentmanipulation/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/contentmanipulation/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/examples/webenginewidgets/fancybrowser/jquery.min.js b/examples/webenginewidgets/contentmanipulation/jquery.min.js
index b1ae21d8b..b1ae21d8b 100644
--- a/examples/webenginewidgets/fancybrowser/jquery.min.js
+++ b/examples/webenginewidgets/contentmanipulation/jquery.min.js
diff --git a/examples/webenginewidgets/fancybrowser/jquery.qrc b/examples/webenginewidgets/contentmanipulation/jquery.qrc
index 1022d682f..1022d682f 100644
--- a/examples/webenginewidgets/fancybrowser/jquery.qrc
+++ b/examples/webenginewidgets/contentmanipulation/jquery.qrc
diff --git a/examples/webenginewidgets/fancybrowser/main.cpp b/examples/webenginewidgets/contentmanipulation/main.cpp
index a21d881f4..a21d881f4 100644
--- a/examples/webenginewidgets/fancybrowser/main.cpp
+++ b/examples/webenginewidgets/contentmanipulation/main.cpp
diff --git a/examples/webenginewidgets/fancybrowser/mainwindow.cpp b/examples/webenginewidgets/contentmanipulation/mainwindow.cpp
index 3dca497a3..3dca497a3 100644
--- a/examples/webenginewidgets/fancybrowser/mainwindow.cpp
+++ b/examples/webenginewidgets/contentmanipulation/mainwindow.cpp
diff --git a/examples/webenginewidgets/fancybrowser/mainwindow.h b/examples/webenginewidgets/contentmanipulation/mainwindow.h
index 8e9b12538..8e9b12538 100644
--- a/examples/webenginewidgets/fancybrowser/mainwindow.h
+++ b/examples/webenginewidgets/contentmanipulation/mainwindow.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/demobrowser/autosaver.cpp b/examples/webenginewidgets/demobrowser/autosaver.cpp
new file mode 100644
index 000000000..53e89b448
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/autosaver.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include "autosaver.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QMetaObject>
+#include <QtDebug>
+
+#define AUTOSAVE_IN 1000 * 3 // seconds
+#define MAXWAIT 1000 * 15 // seconds
+
+AutoSaver::AutoSaver(QObject *parent) : QObject(parent)
+{
+ Q_ASSERT(parent);
+}
+
+AutoSaver::~AutoSaver()
+{
+ if (m_timer.isActive())
+ qWarning() << "AutoSaver: still active when destroyed, changes not saved.";
+}
+
+void AutoSaver::changeOccurred()
+{
+ if (m_firstChange.isNull())
+ m_firstChange.start();
+
+ if (m_firstChange.elapsed() > MAXWAIT) {
+ saveIfNeccessary();
+ } else {
+ m_timer.start(AUTOSAVE_IN, this);
+ }
+}
+
+void AutoSaver::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == m_timer.timerId()) {
+ saveIfNeccessary();
+ } else {
+ QObject::timerEvent(event);
+ }
+}
+
+void AutoSaver::saveIfNeccessary()
+{
+ if (!m_timer.isActive())
+ return;
+ m_timer.stop();
+ m_firstChange = QTime();
+ if (!QMetaObject::invokeMethod(parent(), "save", Qt::DirectConnection)) {
+ qWarning() << "AutoSaver: error invoking slot save() on parent";
+ }
+}
diff --git a/examples/webenginewidgets/demobrowser/autosaver.h b/examples/webenginewidgets/demobrowser/autosaver.h
new file mode 100644
index 000000000..a166e0c5e
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/autosaver.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef AUTOSAVER_H
+#define AUTOSAVER_H
+
+#include <QtCore/QObject>
+#include <QtCore/QBasicTimer>
+#include <QtCore/QTime>
+
+/*
+ This class will call the save() slot on the parent object when the parent changes.
+ It will wait several seconds after changed() to combining multiple changes and
+ prevent continuous writing to disk.
+ */
+class AutoSaver : public QObject {
+
+Q_OBJECT
+
+public:
+ AutoSaver(QObject *parent);
+ ~AutoSaver();
+ void saveIfNeccessary();
+
+public slots:
+ void changeOccurred();
+
+protected:
+ void timerEvent(QTimerEvent *event);
+
+private:
+ QBasicTimer m_timer;
+ QTime m_firstChange;
+
+};
+
+#endif // AUTOSAVER_H
diff --git a/examples/webenginewidgets/browser/bookmarks.cpp b/examples/webenginewidgets/demobrowser/bookmarks.cpp
index 15078caa3..dab6bba51 100644
--- a/examples/webenginewidgets/browser/bookmarks.cpp
+++ b/examples/webenginewidgets/demobrowser/bookmarks.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
diff --git a/examples/webenginewidgets/browser/bookmarks.h b/examples/webenginewidgets/demobrowser/bookmarks.h
index 244f003c6..f9d2e7ec3 100644
--- a/examples/webenginewidgets/browser/bookmarks.h
+++ b/examples/webenginewidgets/demobrowser/bookmarks.h
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
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..339061961 100644
--- a/examples/webenginewidgets/browser/browserapplication.cpp
+++ b/examples/webenginewidgets/demobrowser/browserapplication.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
@@ -46,7 +45,6 @@
#include "cookiejar.h"
#include "downloadmanager.h"
#include "history.h"
-#include "networkaccessmanager.h"
#include "tabwidget.h"
#include "webview.h"
@@ -64,6 +62,7 @@
#include <QtNetwork/QLocalServer>
#include <QtNetwork/QLocalSocket>
#include <QtNetwork/QNetworkProxy>
+#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QSslSocket>
#include <QWebEngineProfile>
@@ -191,25 +190,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 +225,8 @@ void BrowserApplication::quitBrowser()
}
exit(0);
-}
#endif
+}
/*!
Any actions that can be delayed until the window is visible
@@ -243,7 +241,7 @@ void BrowserApplication::postLaunch()
QWebEngineSettings::setOfflineStoragePath(directory);
#endif
- setWindowIcon(QIcon(QLatin1String(":browser.svg")));
+ setWindowIcon(QIcon(QLatin1String(":demobrowser.svg")));
loadSettings();
@@ -283,14 +281,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 +299,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 +489,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 +553,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/demobrowser/browserapplication.h b/examples/webenginewidgets/demobrowser/browserapplication.h
new file mode 100644
index 000000000..d473d9bc9
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/browserapplication.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef BROWSERAPPLICATION_H
+#define BROWSERAPPLICATION_H
+
+#include <QtWidgets/QApplication>
+
+#include <QtCore/QUrl>
+#include <QtCore/QPointer>
+
+#include <QtGui/QIcon>
+
+#include <QtNetwork/QAuthenticator>
+
+QT_BEGIN_NAMESPACE
+class QLocalServer;
+class QNetworkAccessManager;
+class QNetworkProxy;
+class QNetworkReply;
+class QWebEngineProfile;
+QT_END_NAMESPACE
+
+class BookmarksManager;
+class BrowserMainWindow;
+class CookieJar;
+class DownloadManager;
+class HistoryManager;
+class BrowserApplication : public QApplication
+{
+ Q_OBJECT
+
+public:
+ BrowserApplication(int &argc, char **argv);
+ ~BrowserApplication();
+ static BrowserApplication *instance();
+ void loadSettings();
+
+ bool isTheOnlyBrowser() const;
+ BrowserMainWindow *mainWindow();
+ QList<BrowserMainWindow*> mainWindows();
+ QIcon icon(const QUrl &url) const;
+ QIcon defaultIcon() const;
+
+ void saveSession();
+ 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();
+ static QNetworkAccessManager *networkAccessManager();
+ static BookmarksManager *bookmarksManager();
+
+#if defined(Q_OS_OSX)
+ bool event(QEvent *event);
+#endif
+
+public slots:
+ BrowserMainWindow *newMainWindow();
+ void restoreLastSession();
+ void lastWindowClosed();
+ void quitBrowser();
+ void setPrivateBrowsing(bool);
+ void authenticationRequired(QNetworkReply *, QAuthenticator *);
+ void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *);
+
+signals:
+ void privateBrowsingChanged(bool);
+
+private slots:
+ void postLaunch();
+ void openUrl(const QUrl &url);
+ void newLocalSocketConnection();
+
+private:
+ void clean();
+ void installTranslator(const QString &name);
+
+ static HistoryManager *s_historyManager;
+ static DownloadManager *s_downloadManager;
+ static QNetworkAccessManager *s_networkAccessManager;
+ static BookmarksManager *s_bookmarksManager;
+
+ QList<QPointer<BrowserMainWindow> > m_mainWindows;
+ QLocalServer *m_localServer;
+ QByteArray m_lastSession;
+ 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..946810cef 100644
--- a/examples/webenginewidgets/browser/browsermainwindow.cpp
+++ b/examples/webenginewidgets/demobrowser/browsermainwindow.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
diff --git a/examples/webenginewidgets/browser/browsermainwindow.h b/examples/webenginewidgets/demobrowser/browsermainwindow.h
index a2bbc443f..5387b3d8c 100644
--- a/examples/webenginewidgets/browser/browsermainwindow.h
+++ b/examples/webenginewidgets/demobrowser/browsermainwindow.h
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
diff --git a/examples/webenginewidgets/browser/chasewidget.cpp b/examples/webenginewidgets/demobrowser/chasewidget.cpp
index fb0e9ce76..18f040824 100644
--- a/examples/webenginewidgets/browser/chasewidget.cpp
+++ b/examples/webenginewidgets/demobrowser/chasewidget.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
diff --git a/examples/webenginewidgets/demobrowser/chasewidget.h b/examples/webenginewidgets/demobrowser/chasewidget.h
new file mode 100644
index 000000000..325cd5e19
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/chasewidget.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef CHASEWIDGET_H
+#define CHASEWIDGET_H
+
+#include <QtWidgets/QWidget>
+
+#include <QtCore/QSize>
+#include <QtGui/QColor>
+#include <QtGui/QPixmap>
+
+QT_BEGIN_NAMESPACE
+class QHideEvent;
+class QShowEvent;
+class QPaintEvent;
+class QTimerEvent;
+QT_END_NAMESPACE
+
+class ChaseWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ ChaseWidget(QWidget *parent = 0, QPixmap pixmap = QPixmap(), bool pixmapEnabled = false);
+
+ void setAnimated(bool value);
+ void setPixmapEnabled(bool enable);
+ QSize sizeHint() const;
+
+protected:
+ void paintEvent(QPaintEvent *event);
+ void timerEvent(QTimerEvent *event);
+
+private:
+ int segmentCount() const;
+ QColor colorForSegment(int segment) const;
+
+ int m_segment;
+ int m_delay;
+ int m_step;
+ int m_timerId;
+ bool m_animated;
+ QPixmap m_pixmap;
+ bool m_pixmapEnabled;
+};
+
+#endif
diff --git a/examples/webenginewidgets/browser/cookiejar.cpp b/examples/webenginewidgets/demobrowser/cookiejar.cpp
index d9a7465ca..11a8562c3 100644
--- a/examples/webenginewidgets/browser/cookiejar.cpp
+++ b/examples/webenginewidgets/demobrowser/cookiejar.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
diff --git a/examples/webenginewidgets/browser/cookiejar.h b/examples/webenginewidgets/demobrowser/cookiejar.h
index 374156e89..00fb70009 100644
--- a/examples/webenginewidgets/browser/cookiejar.h
+++ b/examples/webenginewidgets/demobrowser/cookiejar.h
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
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/demobrowser/data/demobrowser.svg b/examples/webenginewidgets/demobrowser/data/demobrowser.svg
new file mode 100644
index 000000000..9f39deb66
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/data/demobrowser.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="94px" height="94px" viewBox="0 0 94 94" enable-background="new 0 0 94 94" xml:space="preserve">
+<g>
+ <circle fill="none" cx="47" cy="47" r="47"/>
+ <g>
+ <path fill="#46A2DA" d="M47,92.979c-11.779,0-23.559-4.484-32.526-13.451C-3.461,61.591-3.461,32.409,14.472,14.474
+ C32.41-3.463,61.592-3.461,79.526,14.473c17.935,17.936,17.935,47.119,0.002,65.054l-0.002,0.001
+ C70.559,88.495,58.779,92.979,47,92.979z"/>
+ </g>
+ <path fill="#80C342" d="M93,47C93,21.595,72.405,1,47,1C34.297,1,22.797,6.149,14.473,14.473l65.054,65.054
+ C87.851,71.203,93,59.703,93,47z"/>
+ <g>
+ <path fill="#46A2DA" d="M47,65c-4.808,0-9.328-1.873-12.728-5.272c-7.018-7.019-7.018-18.438,0-25.456
+ C37.672,30.873,42.192,29,47,29s9.328,1.873,12.728,5.272c7.018,7.019,7.018,18.438,0,25.456C56.328,63.127,51.808,65,47,65z"/>
+ <path fill="#FFFFFF" d="M62.248,59.919c6.671-7.858,6.312-19.644-1.105-27.061C57.237,28.953,52.118,27,47,27
+ c-5.118,0-10.237,1.953-14.142,5.858c-7.81,7.81-7.81,20.474,0,28.284C36.763,65.047,41.882,67,47,67
+ c4.379,0,8.752-1.441,12.372-4.3L77.88,81.209c0.989-0.895,1.935-1.837,2.843-2.814L62.248,59.919z M35.686,58.314
+ c-6.238-6.238-6.238-16.389,0-22.627C38.708,32.664,42.726,31,47,31c4.274,0,8.292,1.664,11.314,4.686
+ c6.238,6.238,6.238,16.389,0,22.627C55.292,61.336,51.274,63,47,63C42.726,63,38.708,61.336,35.686,58.314z"/>
+ </g>
+</g>
+</svg>
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/demobrowser/demobrowser.icns b/examples/webenginewidgets/demobrowser/demobrowser.icns
new file mode 100644
index 000000000..f24ac6ee7
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/demobrowser.icns
Binary files differ
diff --git a/examples/webenginewidgets/demobrowser/demobrowser.ico b/examples/webenginewidgets/demobrowser/demobrowser.ico
new file mode 100644
index 000000000..d197d0358
--- /dev/null
+++ 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..113eeb40e 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
@@ -27,6 +28,7 @@ HEADERS += \
edittableview.h \
edittreeview.h \
featurepermissionbar.h\
+ fullscreennotification.h \
history.h \
modelmenu.h \
searchlineedit.h \
@@ -48,6 +50,7 @@ SOURCES += \
edittableview.cpp \
edittreeview.cpp \
featurepermissionbar.cpp\
+ fullscreennotification.cpp \
history.cpp \
modelmenu.cpp \
searchlineedit.cpp \
@@ -62,28 +65,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/demobrowser/doc/images/browser-demo.png b/examples/webenginewidgets/demobrowser/doc/images/browser-demo.png
new file mode 100644
index 000000000..e8695dbca
--- /dev/null
+++ 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..e506f28b6 100644
--- a/examples/webenginewidgets/browser/downloaditem.ui
+++ b/examples/webenginewidgets/demobrowser/downloaditem.ui
@@ -13,7 +13,16 @@
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout" >
- <property name="margin" >
+ <property name="leftMargin">
+ <number>5</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>5</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
<item>
diff --git a/examples/webenginewidgets/browser/downloadmanager.cpp b/examples/webenginewidgets/demobrowser/downloadmanager.cpp
index aa83d7145..8cfa66e38 100644
--- a/examples/webenginewidgets/browser/downloadmanager.cpp
+++ b/examples/webenginewidgets/demobrowser/downloadmanager.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
@@ -43,7 +42,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..794f17aef 100644
--- a/examples/webenginewidgets/browser/downloadmanager.h
+++ b/examples/webenginewidgets/demobrowser/downloadmanager.h
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
@@ -98,7 +97,6 @@ class DownloadManager : public QDialog, public Ui_DownloadDialog
{
Q_OBJECT
Q_PROPERTY(RemovePolicy removePolicy READ removePolicy WRITE setRemovePolicy)
- Q_ENUMS(RemovePolicy)
public:
enum RemovePolicy {
@@ -106,6 +104,7 @@ public:
Exit,
SuccessFullDownload
};
+ Q_ENUM(RemovePolicy)
DownloadManager(QWidget *parent = 0);
~DownloadManager();
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/demobrowser/edittableview.cpp b/examples/webenginewidgets/demobrowser/edittableview.cpp
new file mode 100644
index 000000000..8ab5327da
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/edittableview.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include "edittableview.h"
+#include <QtGui/QKeyEvent>
+
+EditTableView::EditTableView(QWidget *parent)
+ : QTableView(parent)
+{
+}
+
+void EditTableView::keyPressEvent(QKeyEvent *event)
+{
+ if ((event->key() == Qt::Key_Delete
+ || event->key() == Qt::Key_Backspace)
+ && model()) {
+ removeOne();
+ } else {
+ QAbstractItemView::keyPressEvent(event);
+ }
+}
+
+void EditTableView::removeOne()
+{
+ if (!model() || !selectionModel())
+ return;
+ int row = currentIndex().row();
+ model()->removeRow(row, rootIndex());
+ QModelIndex idx = model()->index(row, 0, rootIndex());
+ if (!idx.isValid())
+ idx = model()->index(row - 1, 0, rootIndex());
+ selectionModel()->select(idx, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
+}
+
+void EditTableView::removeAll()
+{
+ if (model())
+ model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex());
+}
diff --git a/examples/webenginewidgets/demobrowser/edittableview.h b/examples/webenginewidgets/demobrowser/edittableview.h
new file mode 100644
index 000000000..4d23b607d
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/edittableview.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef EDITTABLEVIEW_H
+#define EDITTABLEVIEW_H
+
+#include <QtWidgets/QTableView>
+
+class EditTableView : public QTableView
+{
+ Q_OBJECT
+
+public:
+ EditTableView(QWidget *parent = 0);
+ void keyPressEvent(QKeyEvent *event);
+
+public slots:
+ void removeOne();
+ void removeAll();
+};
+
+#endif // EDITTABLEVIEW_H
diff --git a/examples/webenginewidgets/demobrowser/edittreeview.cpp b/examples/webenginewidgets/demobrowser/edittreeview.cpp
new file mode 100644
index 000000000..872191015
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/edittreeview.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include "edittreeview.h"
+
+#include <QtGui/QKeyEvent>
+
+EditTreeView::EditTreeView(QWidget *parent)
+ : QTreeView(parent)
+{
+}
+
+void EditTreeView::keyPressEvent(QKeyEvent *event)
+{
+ if ((event->key() == Qt::Key_Delete
+ || event->key() == Qt::Key_Backspace)
+ && model()) {
+ removeOne();
+ } else {
+ QAbstractItemView::keyPressEvent(event);
+ }
+}
+
+void EditTreeView::removeOne()
+{
+ if (!model())
+ return;
+ QModelIndex ci = currentIndex();
+ int row = ci.row();
+ model()->removeRow(row, ci.parent());
+}
+
+void EditTreeView::removeAll()
+{
+ if (!model())
+ return;
+ model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex());
+}
diff --git a/examples/webenginewidgets/demobrowser/edittreeview.h b/examples/webenginewidgets/demobrowser/edittreeview.h
new file mode 100644
index 000000000..5dbb8b5d1
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/edittreeview.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef EDITTREEVIEW_H
+#define EDITTREEVIEW_H
+
+#include <QtWidgets/QTreeView>
+
+class EditTreeView : public QTreeView
+{
+ Q_OBJECT
+
+public:
+ EditTreeView(QWidget *parent = 0);
+ void keyPressEvent(QKeyEvent *event);
+
+public slots:
+ void removeOne();
+ void removeAll();
+};
+
+#endif // EDITTREEVIEW_H
diff --git a/examples/webenginewidgets/browser/featurepermissionbar.cpp b/examples/webenginewidgets/demobrowser/featurepermissionbar.cpp
index b7275dfc2..743542904 100644
--- a/examples/webenginewidgets/browser/featurepermissionbar.cpp
+++ b/examples/webenginewidgets/demobrowser/featurepermissionbar.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
diff --git a/examples/webenginewidgets/demobrowser/featurepermissionbar.h b/examples/webenginewidgets/demobrowser/featurepermissionbar.h
new file mode 100644
index 000000000..eb5dbf876
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/featurepermissionbar.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef FEATUREPERMISSIONBAR_H
+#define FEATUREPERMISSIONBAR_H
+
+#include <QWidget>
+#include <QWebEnginePage>
+
+QT_BEGIN_NAMESPACE
+class QLabel;
+class QPushButton;
+QT_END_NAMESPACE
+
+class FeaturePermissionBar : public QWidget {
+Q_OBJECT
+
+public:
+ FeaturePermissionBar(QWidget*);
+ void requestPermission(const QUrl &, QWebEnginePage::Feature feature);
+
+signals:
+ void featurePermissionProvided(const QUrl &securityOrigin, QWebEnginePage::Feature, QWebEnginePage::PermissionPolicy);
+
+private slots:
+ void permissionDenied();
+ void permissionGranted();
+ void permissionUnknown();
+
+private:
+ QWebEnginePage::Feature m_feature;
+ QLabel *m_messageLabel;
+ QUrl m_securityOrigin;
+};
+
+#endif // FEATUREPERMISSIONBAR_H
diff --git a/examples/webenginewidgets/demobrowser/fullscreennotification.cpp b/examples/webenginewidgets/demobrowser/fullscreennotification.cpp
new file mode 100644
index 000000000..7b9dcd1db
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/fullscreennotification.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include "fullscreennotification.h"
+
+#include <QApplication>
+#include <QDesktopWidget>
+#include <QGridLayout>
+#include <QLabel>
+#include <QPropertyAnimation>
+#include <QTimer>
+
+FullScreenNotification::FullScreenNotification(QWidget *parent)
+ : QWidget(parent)
+ , width(400)
+ , height(80)
+ , x((parent->geometry().width() - width) / 2)
+ , y(80)
+{
+ setVisible(false);
+ setWindowFlags(Qt::ToolTip | Qt::WindowDoesNotAcceptFocus);
+
+ QGridLayout *layout = new QGridLayout(this);
+
+ m_label = new QLabel(tr("You are now in fullscreen mode. Press ESC to quit!"), this);
+ layout->addWidget(m_label, 0, 0, 0, 0, Qt::AlignHCenter | Qt::AlignVCenter);
+
+ setGeometry(x, y, width, height);
+
+ setStyleSheet("background-color: white;\
+ color: black;");
+
+ m_animation = new QPropertyAnimation(this, "windowOpacity");
+ connect(m_animation, SIGNAL(finished()), this, SLOT(fadeOutFinished()));
+}
+
+FullScreenNotification::~FullScreenNotification()
+{
+}
+
+void FullScreenNotification::show()
+{
+ setWindowOpacity(1.0);
+ QTimer::singleShot(300, [&] {
+ QWidget *parent = parentWidget();
+ x = (parent->geometry().width() - width) / 2;
+ QPoint topLeft = parent->mapToGlobal(QPoint(x, y));
+ QWidget::move(topLeft.x(), topLeft.y());
+ QWidget::show();
+ QWidget::raise();
+ });
+ QTimer::singleShot(5000, this, SLOT(fadeOut()));
+}
+
+void FullScreenNotification::hide()
+{
+ QWidget::hide();
+ m_animation->stop();
+}
+
+void FullScreenNotification::fadeOut()
+{
+ m_animation->setDuration(800);
+ m_animation->setStartValue(1.0);
+ m_animation->setEndValue(0.0);
+ m_animation->setEasingCurve(QEasingCurve::OutQuad);
+ m_animation->start();
+}
+
+void FullScreenNotification::fadeOutFinished()
+{
+ hide();
+ setWindowOpacity(1.0);
+}
diff --git a/examples/webenginewidgets/demobrowser/fullscreennotification.h b/examples/webenginewidgets/demobrowser/fullscreennotification.h
new file mode 100644
index 000000000..b0cba215b
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/fullscreennotification.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef FULLSCREENNOTIFICATION_H
+#define FULLSCREENNOTIFICATION_H
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QLabel;
+class QGridLayout;
+class QPropertyAnimation;
+QT_END_NAMESPACE
+
+class FullScreenNotification : public QWidget
+{
+ Q_OBJECT
+public:
+ FullScreenNotification(QWidget *parent = 0);
+ ~FullScreenNotification();
+
+ void show();
+ void hide();
+
+public slots:
+ void fadeOut();
+ void fadeOutFinished();
+
+private:
+ QLabel *m_label;
+ QGridLayout *m_layout;
+ QPropertyAnimation *m_animation;
+ int width;
+ int height;
+ int x;
+ int y;
+};
+
+#endif // FULLSCREENNOTIFICATION_H
diff --git a/examples/webenginewidgets/browser/history.cpp b/examples/webenginewidgets/demobrowser/history.cpp
index ce104e982..99f93c178 100644
--- a/examples/webenginewidgets/browser/history.cpp
+++ b/examples/webenginewidgets/demobrowser/history.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
diff --git a/examples/webenginewidgets/browser/history.h b/examples/webenginewidgets/demobrowser/history.h
index bcb9c9b28..d8d9e6abe 100644
--- a/examples/webenginewidgets/browser/history.h
+++ b/examples/webenginewidgets/demobrowser/history.h
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
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/demobrowser/main.cpp b/examples/webenginewidgets/demobrowser/main.cpp
new file mode 100644
index 000000000..125d92dc2
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include "browserapplication.h"
+
+#include <qtwebenginewidgetsglobal.h>
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(data);
+ BrowserApplication application(argc, argv);
+ if (!application.isTheOnlyBrowser())
+ return 0;
+
+ application.newMainWindow();
+ return application.exec();
+}
diff --git a/examples/webenginewidgets/browser/modelmenu.cpp b/examples/webenginewidgets/demobrowser/modelmenu.cpp
index ec0eaffab..d3ba1e129 100644
--- a/examples/webenginewidgets/browser/modelmenu.cpp
+++ b/examples/webenginewidgets/demobrowser/modelmenu.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
diff --git a/examples/webenginewidgets/browser/modelmenu.h b/examples/webenginewidgets/demobrowser/modelmenu.h
index c0a7d56b8..a4b9e0eac 100644
--- a/examples/webenginewidgets/browser/modelmenu.h
+++ b/examples/webenginewidgets/demobrowser/modelmenu.h
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
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..c322d2489 100644
--- a/examples/webenginewidgets/browser/searchlineedit.cpp
+++ b/examples/webenginewidgets/demobrowser/searchlineedit.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
@@ -45,7 +44,7 @@
#include <QtGui/QMouseEvent>
#include <QtWidgets/QMenu>
#include <QtWidgets/QStyle>
-#include <QtWidgets/QStyleOptionFrameV2>
+#include <QtWidgets/QStyleOptionFrame>
ClearButton::ClearButton(QWidget *parent)
: QAbstractButton(parent)
@@ -181,7 +180,7 @@ void SearchLineEdit::paintEvent(QPaintEvent *event)
{
if (lineEdit()->text().isEmpty() && !hasFocus() && !m_inactiveText.isEmpty()) {
ExLineEdit::paintEvent(event);
- QStyleOptionFrameV2 panel;
+ QStyleOptionFrame panel;
initStyleOption(&panel);
QRect r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
QFontMetrics fm = fontMetrics();
diff --git a/examples/webenginewidgets/demobrowser/searchlineedit.h b/examples/webenginewidgets/demobrowser/searchlineedit.h
new file mode 100644
index 000000000..68d75aa66
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/searchlineedit.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef SEARCHLINEEDIT_H
+#define SEARCHLINEEDIT_H
+
+#include "urllineedit.h"
+
+#include <QtWidgets/QLineEdit>
+#include <QtWidgets/QAbstractButton>
+
+QT_BEGIN_NAMESPACE
+class QMenu;
+QT_END_NAMESPACE
+
+class SearchButton;
+
+/*
+ Clear button on the right hand side of the search widget.
+ Hidden by default
+ "A circle with an X in it"
+ */
+class ClearButton : public QAbstractButton
+{
+ Q_OBJECT
+
+public:
+ ClearButton(QWidget *parent = 0);
+ void paintEvent(QPaintEvent *event);
+
+public slots:
+ void textChanged(const QString &text);
+};
+
+
+class SearchLineEdit : public ExLineEdit
+{
+ Q_OBJECT
+ Q_PROPERTY(QString inactiveText READ inactiveText WRITE setInactiveText)
+
+signals:
+ void textChanged(const QString &text);
+
+public:
+ SearchLineEdit(QWidget *parent = 0);
+
+ QString inactiveText() const;
+ void setInactiveText(const QString &text);
+
+ QMenu *menu() const;
+ void setMenu(QMenu *menu);
+
+protected:
+ void resizeEvent(QResizeEvent *event);
+ void paintEvent(QPaintEvent *event);
+
+private:
+ void updateGeometries();
+
+ SearchButton *m_searchButton;
+ QString m_inactiveText;
+};
+
+#endif // SEARCHLINEEDIT_H
diff --git a/examples/webenginewidgets/browser/settings.cpp b/examples/webenginewidgets/demobrowser/settings.cpp
index 7ed5f707b..9e9a7154c 100644
--- a/examples/webenginewidgets/browser/settings.cpp
+++ b/examples/webenginewidgets/demobrowser/settings.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
@@ -47,9 +46,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 +65,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 +96,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 +153,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 +212,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 +238,6 @@ void SettingsDialog::saveToSettings()
BrowserApplication::instance()->loadSettings();
#if defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- BrowserApplication::networkAccessManager()->loadSettings();
BrowserApplication::cookieJar()->loadSettings();
#endif
BrowserApplication::historyManager()->loadSettings();
@@ -271,6 +285,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/demobrowser/settings.h b/examples/webenginewidgets/demobrowser/settings.h
new file mode 100644
index 000000000..968f92cb9
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/settings.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include <QtWidgets/QDialog>
+#include "ui_settings.h"
+
+class SettingsDialog : public QDialog, public Ui_Settings
+{
+ Q_OBJECT
+
+public:
+ SettingsDialog(QWidget *parent = 0);
+ void accept();
+
+private slots:
+ void loadDefaults();
+ void loadFromSettings();
+ void saveToSettings();
+
+ void setHomeToCurrentPage();
+ void showCookies();
+ void showExceptions();
+
+ void chooseFont();
+ void chooseFixedFont();
+
+ void on_httpUserAgent_editingFinished();
+ void on_httpAcceptLanguage_editingFinished();
+
+private:
+ QFont standardFont;
+ QFont fixedFont;
+};
+
+#endif // SETTINGS_H
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/demobrowser/squeezelabel.cpp b/examples/webenginewidgets/demobrowser/squeezelabel.cpp
new file mode 100644
index 000000000..2d9061a80
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/squeezelabel.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include "squeezelabel.h"
+
+SqueezeLabel::SqueezeLabel(QWidget *parent) : QLabel(parent)
+{
+}
+
+void SqueezeLabel::paintEvent(QPaintEvent *event)
+{
+ QFontMetrics fm = fontMetrics();
+ if (fm.width(text()) > contentsRect().width()) {
+ QString elided = fm.elidedText(text(), Qt::ElideMiddle, width());
+ QString oldText = text();
+ setText(elided);
+ QLabel::paintEvent(event);
+ setText(oldText);
+ } else {
+ QLabel::paintEvent(event);
+ }
+}
diff --git a/examples/webenginewidgets/demobrowser/squeezelabel.h b/examples/webenginewidgets/demobrowser/squeezelabel.h
new file mode 100644
index 000000000..e29e9f958
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/squeezelabel.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef SQUEEZELABEL_H
+#define SQUEEZELABEL_H
+
+#include <QtWidgets/QLabel>
+
+class SqueezeLabel : public QLabel
+{
+ Q_OBJECT
+
+public:
+ SqueezeLabel(QWidget *parent = 0);
+
+protected:
+ void paintEvent(QPaintEvent *event);
+
+};
+
+#endif // SQUEEZELABEL_H
diff --git a/examples/webenginewidgets/browser/tabwidget.cpp b/examples/webenginewidgets/demobrowser/tabwidget.cpp
index c093b804a..73ca39bf9 100644
--- a/examples/webenginewidgets/browser/tabwidget.cpp
+++ b/examples/webenginewidgets/demobrowser/tabwidget.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
@@ -44,14 +43,16 @@
#include "browserapplication.h"
#include "browsermainwindow.h"
#include "downloadmanager.h"
+#include "fullscreennotification.h"
#include "history.h"
#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,12 @@ TabBar::TabBar(QWidget *parent)
setMovable(true);
}
+TabWidget::~TabWidget()
+{
+ delete m_fullScreenNotification;
+ delete m_fullScreenView;
+}
+
void TabBar::selectTabAction()
{
if (QShortcut *shortCut = qobject_cast<QShortcut*>(sender())) {
@@ -153,7 +160,17 @@ void TabBar::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
m_dragStartPos = event->pos();
+
QTabBar::mousePressEvent(event);
+
+ // Middle click on tab should close it.
+ if (event->button() == Qt::MiddleButton) {
+ const QPoint pos = event->pos();
+ int index = tabAt(pos);
+ if (index != -1) {
+ emit closeTab(index);
+ }
+ }
}
void TabBar::mouseMoveEvent(QMouseEvent *event)
@@ -213,16 +230,19 @@ TabWidget::TabWidget(QWidget *parent)
, m_lineEdits(0)
, m_tabBar(new TabBar(this))
, m_profile(QWebEngineProfile::defaultProfile())
+ , m_fullScreenView(0)
+ , m_fullScreenNotification(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)));
connect(m_tabBar, SIGNAL(reloadAllTabs()), this, SLOT(reloadAllTabs()));
connect(m_tabBar, SIGNAL(tabMoved(int,int)), this, SLOT(moveTab(int,int)));
+ connect(m_tabBar, SIGNAL(tabBarDoubleClicked(int)), this, SLOT(handleTabBarDoubleClicked(int)));
setTabBar(m_tabBar);
setDocumentMode(true);
@@ -235,7 +255,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 +335,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(QWebEngineFullScreenRequest)),
+ this, SLOT(fullScreenRequested(QWebEngineFullScreenRequest)));
}
#if defined(QWEBENGINEVIEW_STATUSBARMESSAGE)
@@ -327,6 +349,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(QWebEngineFullScreenRequest)),
+ this, SLOT(fullScreenRequested(QWebEngineFullScreenRequest)));
for (int i = 0; i < m_actions.count(); ++i) {
WebActionMapper *mapper = m_actions[i];
@@ -342,6 +366,44 @@ void TabWidget::currentChanged(int index)
webView->setFocus();
}
+void TabWidget::fullScreenRequested(QWebEngineFullScreenRequest request)
+{
+ WebPage *webPage = qobject_cast<WebPage*>(sender());
+ if (request.toggleOn()) {
+ if (!m_fullScreenView) {
+ m_fullScreenView = new QWebEngineView();
+ m_fullScreenNotification = new FullScreenNotification(m_fullScreenView);
+
+ QAction *exitFullScreenAction = new QAction(m_fullScreenView);
+ exitFullScreenAction->setShortcut(Qt::Key_Escape);
+ connect(exitFullScreenAction, &QAction::triggered, [webPage] {
+ webPage->triggerAction(QWebEnginePage::ExitFullScreen);
+ });
+ m_fullScreenView->addAction(exitFullScreenAction);
+ }
+ webPage->setView(m_fullScreenView);
+ request.accept();
+ m_fullScreenView->showFullScreen();
+ m_fullScreenView->raise();
+ m_fullScreenNotification->show();
+ } else {
+ if (!m_fullScreenView)
+ return;
+ WebView *oldWebView = this->webView(m_lineEdits->currentIndex());
+ webPage->setView(oldWebView);
+ request.accept();
+ raise();
+ m_fullScreenView->hide();
+ m_fullScreenNotification->hide();
+ }
+}
+
+void TabWidget::handleTabBarDoubleClicked(int index)
+{
+ if (index != -1) return;
+ newTab();
+}
+
QAction *TabWidget::newTabAction() const
{
return m_newTabAction;
@@ -415,6 +477,36 @@ int TabWidget::webViewIndex(WebView *webView) const
return index;
}
+void TabWidget::setupPage(QWebEnginePage* page)
+{
+ connect(page, SIGNAL(windowCloseRequested()),
+ this, SLOT(windowCloseRequested()));
+ connect(page, SIGNAL(geometryChangeRequested(QRect)),
+ this, SIGNAL(geometryChangeRequested(QRect)));
+#if defined(QWEBENGINEPAGE_PRINTREQUESTED)
+ connect(page, SIGNAL(printRequested(QWebEngineFrame*)),
+ this, SIGNAL(printRequested(QWebEngineFrame*)));
+#endif
+#if defined(QWEBENGINEPAGE_MENUBARVISIBILITYCHANGEREQUESTED)
+ connect(page, SIGNAL(menuBarVisibilityChangeRequested(bool)),
+ this, SIGNAL(menuBarVisibilityChangeRequested(bool)));
+#endif
+#if defined(QWEBENGINEPAGE_STATUSBARVISIBILITYCHANGEREQUESTED)
+ connect(page, SIGNAL(statusBarVisibilityChangeRequested(bool)),
+ this, SIGNAL(statusBarVisibilityChangeRequested(bool)));
+#endif
+#if defined(QWEBENGINEPAGE_TOOLBARVISIBILITYCHANGEREQUESTED)
+ connect(page, SIGNAL(toolBarVisibilityChangeRequested(bool)),
+ this, SIGNAL(toolBarVisibilityChangeRequested(bool)));
+#endif
+
+ // webview actions
+ for (int i = 0; i < m_actions.count(); ++i) {
+ WebActionMapper *mapper = m_actions[i];
+ mapper->addChild(page->action(mapper->webAction()));
+ }
+}
+
WebView *TabWidget::newTab(bool makeCurrent)
{
// line edit
@@ -462,35 +554,13 @@ WebView *TabWidget::newTab(bool makeCurrent)
this, SLOT(webViewTitleChanged(QString)));
connect(webView, SIGNAL(urlChanged(QUrl)),
this, SLOT(webViewUrlChanged(QUrl)));
- connect(webView->page(), SIGNAL(windowCloseRequested()),
- this, SLOT(windowCloseRequested()));
- connect(webView->page(), SIGNAL(geometryChangeRequested(QRect)),
- this, SIGNAL(geometryChangeRequested(QRect)));
-#if defined(QWEBENGINEPAGE_PRINTREQUESTED)
- connect(webView->page(), SIGNAL(printRequested(QWebEngineFrame*)),
- this, SIGNAL(printRequested(QWebEngineFrame*)));
-#endif
-#if defined(QWEBENGINEPAGE_MENUBARVISIBILITYCHANGEREQUESTED)
- connect(webView->page(), SIGNAL(menuBarVisibilityChangeRequested(bool)),
- this, SIGNAL(menuBarVisibilityChangeRequested(bool)));
-#endif
-#if defined(QWEBENGINEPAGE_STATUSBARVISIBILITYCHANGEREQUESTED)
- connect(webView->page(), SIGNAL(statusBarVisibilityChangeRequested(bool)),
- this, SIGNAL(statusBarVisibilityChangeRequested(bool)));
-#endif
-#if defined(QWEBENGINEPAGE_TOOLBARVISIBILITYCHANGEREQUESTED)
- connect(webView->page(), SIGNAL(toolBarVisibilityChangeRequested(bool)),
- this, SIGNAL(toolBarVisibilityChangeRequested(bool)));
-#endif
+
+
addTab(webView, tr("(Untitled)"));
if (makeCurrent)
setCurrentWidget(webView);
- // webview actions
- for (int i = 0; i < m_actions.count(); ++i) {
- WebActionMapper *mapper = m_actions[i];
- mapper->addChild(webView->page()->action(mapper->webAction()));
- }
+ setupPage(webView->page());
if (count() == 1)
currentChanged(currentIndex());
@@ -522,12 +592,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 +618,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()) {
@@ -605,6 +666,7 @@ void TabWidget::setProfile(QWebEngineProfile *profile)
QWidget *tabWidget = widget(i);
if (WebView *tab = qobject_cast<WebView*>(tabWidget)) {
WebPage* webPage = new WebPage(m_profile, tab);
+ setupPage(webPage);
webPage->load(tab->page()->url());
tab->setPage(webPage);
}
diff --git a/examples/webenginewidgets/browser/tabwidget.h b/examples/webenginewidgets/demobrowser/tabwidget.h
index 5d7f1e2c5..cfe1b0397 100644
--- a/examples/webenginewidgets/browser/tabwidget.h
+++ b/examples/webenginewidgets/demobrowser/tabwidget.h
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
@@ -42,13 +41,14 @@
#ifndef TABWIDGET_H
#define TABWIDGET_H
+#include <QtWebEngineWidgets/QWebEngineFullScreenRequest>
#include <QtWidgets/QTabBar>
-
#include <QtWidgets/QShortcut>
QT_BEGIN_NAMESPACE
class QWebEngineDownloadItem;
class QWebEngineProfile;
+class QWebEngineView;
QT_END_NAMESPACE
/*
@@ -127,12 +127,16 @@ private:
#include <QtCore/QUrl>
#include <QtWidgets/QTabWidget>
+
+class FullScreenNotification;
+
QT_BEGIN_NAMESPACE
class QCompleter;
class QLineEdit;
class QMenu;
class QStackedWidget;
QT_END_NAMESPACE
+
/*!
TabWidget that contains WebViews and a stack widget of associated line edits.
@@ -164,6 +168,7 @@ signals:
public:
TabWidget(QWidget *parent = 0);
+ ~TabWidget();
void clear();
void addWebAction(QAction *action, QWebEnginePage::WebAction webAction);
@@ -194,7 +199,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,8 +219,12 @@ private slots:
void lineEditReturnPressed();
void windowCloseRequested();
void moveTab(int fromIndex, int toIndex);
+ void fullScreenRequested(QWebEngineFullScreenRequest request);
+ void handleTabBarDoubleClicked(int index);
private:
+ void setupPage(QWebEnginePage* page);
+
QAction *m_recentlyClosedTabsAction;
QAction *m_newTabAction;
QAction *m_closeTabAction;
@@ -230,6 +240,8 @@ private:
QStackedWidget *m_lineEdits;
TabBar *m_tabBar;
QWebEngineProfile *m_profile;
+ QWebEngineView *m_fullScreenView;
+ FullScreenNotification *m_fullScreenNotification;
};
#endif // TABWIDGET_H
diff --git a/examples/webenginewidgets/browser/toolbarsearch.cpp b/examples/webenginewidgets/demobrowser/toolbarsearch.cpp
index 42cdaec18..37ba14ec0 100644
--- a/examples/webenginewidgets/browser/toolbarsearch.cpp
+++ b/examples/webenginewidgets/demobrowser/toolbarsearch.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
diff --git a/examples/webenginewidgets/demobrowser/toolbarsearch.h b/examples/webenginewidgets/demobrowser/toolbarsearch.h
new file mode 100644
index 000000000..078deac49
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/toolbarsearch.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef TOOLBARSEARCH_H
+#define TOOLBARSEARCH_H
+
+#include "searchlineedit.h"
+
+QT_BEGIN_NAMESPACE
+class QUrl;
+class QAction;
+class QStringListModel;
+QT_END_NAMESPACE
+
+class AutoSaver;
+
+class ToolbarSearch : public SearchLineEdit
+{
+ Q_OBJECT
+
+signals:
+ void search(const QUrl &url);
+
+public:
+ ToolbarSearch(QWidget *parent = 0);
+ ~ToolbarSearch();
+
+public slots:
+ void clear();
+ void searchNow();
+
+private slots:
+ void save();
+ void aboutToShowMenu();
+ void triggeredMenuAction(QAction *action);
+
+private:
+ void load();
+
+ AutoSaver *m_autosaver;
+ int m_maxSavedSearches;
+ QStringListModel *m_stringListModel;
+};
+
+#endif // TOOLBARSEARCH_H
diff --git a/examples/webenginewidgets/browser/urllineedit.cpp b/examples/webenginewidgets/demobrowser/urllineedit.cpp
index 685277d9c..ad5ec1263 100644
--- a/examples/webenginewidgets/browser/urllineedit.cpp
+++ b/examples/webenginewidgets/demobrowser/urllineedit.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
@@ -57,7 +56,7 @@
#include <QtGui/QDrag>
#include <QtGui/QPainter>
#include <QtWidgets/QStyle>
-#include <QtWidgets/QStyleOptionFrameV2>
+#include <QtWidgets/QStyleOptionFrame>
#include <QtCore/QDebug>
@@ -112,7 +111,7 @@ void ExLineEdit::resizeEvent(QResizeEvent *event)
void ExLineEdit::updateGeometries()
{
- QStyleOptionFrameV2 panel;
+ QStyleOptionFrame panel;
initStyleOption(&panel);
QRect rect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
@@ -131,7 +130,7 @@ void ExLineEdit::updateGeometries()
clearButtonWidth, this->height());
}
-void ExLineEdit::initStyleOption(QStyleOptionFrameV2 *option) const
+void ExLineEdit::initStyleOption(QStyleOptionFrame *option) const
{
option->initFrom(this);
option->rect = contentsRect();
@@ -144,7 +143,7 @@ void ExLineEdit::initStyleOption(QStyleOptionFrameV2 *option) const
if (hasEditFocus())
option->state |= QStyle::State_HasEditFocus;
#endif
- option->features = QStyleOptionFrameV2::None;
+ option->features = QStyleOptionFrame::None;
}
QSize ExLineEdit::sizeHint() const
@@ -189,7 +188,7 @@ bool ExLineEdit::event(QEvent *event)
void ExLineEdit::paintEvent(QPaintEvent *)
{
QPainter p(this);
- QStyleOptionFrameV2 panel;
+ QStyleOptionFrame panel;
initStyleOption(&panel);
style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this);
}
@@ -322,7 +321,7 @@ void UrlLineEdit::paintEvent(QPaintEvent *event)
ExLineEdit::paintEvent(event);
QPainter painter(this);
- QStyleOptionFrameV2 panel;
+ QStyleOptionFrame panel;
initStyleOption(&panel);
QRect backgroundRect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
if (m_webView && !hasFocus()) {
diff --git a/examples/webenginewidgets/demobrowser/urllineedit.h b/examples/webenginewidgets/demobrowser/urllineedit.h
new file mode 100644
index 000000000..06efcd528
--- /dev/null
+++ b/examples/webenginewidgets/demobrowser/urllineedit.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef URLLINEEDIT_H
+#define URLLINEEDIT_H
+
+#include <QtCore/QUrl>
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QStyleOptionFrame>
+
+QT_BEGIN_NAMESPACE
+class QLineEdit;
+QT_END_NAMESPACE
+
+class ClearButton;
+class ExLineEdit : public QWidget
+{
+ Q_OBJECT
+
+public:
+ ExLineEdit(QWidget *parent = 0);
+
+ inline QLineEdit *lineEdit() const { return m_lineEdit; }
+
+ void setLeftWidget(QWidget *widget);
+ QWidget *leftWidget() const;
+
+ QSize sizeHint() const;
+
+ QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+protected:
+ void focusInEvent(QFocusEvent *event);
+ void focusOutEvent(QFocusEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void resizeEvent(QResizeEvent *event);
+ void inputMethodEvent(QInputMethodEvent *e);
+ bool event(QEvent *event);
+
+protected:
+ void updateGeometries();
+ void initStyleOption(QStyleOptionFrame *option) const;
+
+ QWidget *m_leftWidget;
+ QLineEdit *m_lineEdit;
+ ClearButton *m_clearButton;
+};
+
+class UrlIconLabel;
+class WebView;
+class UrlLineEdit : public ExLineEdit
+{
+ Q_OBJECT
+
+public:
+ UrlLineEdit(QWidget *parent = 0);
+ void setWebView(WebView *webView);
+
+protected:
+ void paintEvent(QPaintEvent *event);
+ void focusOutEvent(QFocusEvent *event);
+
+private slots:
+ void webViewUrlChanged(const QUrl &url);
+ void webViewIconChanged();
+
+private:
+ QLinearGradient generateGradient(const QColor &color) const;
+ WebView *m_webView;
+ UrlIconLabel *m_iconLabel;
+ QColor m_defaultBaseColor;
+
+};
+
+
+#endif // URLLINEEDIT_H
diff --git a/examples/webenginewidgets/browser/webview.cpp b/examples/webenginewidgets/demobrowser/webview.cpp
index 99986642e..42f725fe8 100644
--- a/examples/webenginewidgets/browser/webview.cpp
+++ b/examples/webenginewidgets/demobrowser/webview.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
@@ -44,7 +43,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 +65,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 +173,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 +271,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 +302,15 @@ 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();
}
}
@@ -314,6 +324,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 +369,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 +398,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..6d9cd46ab 100644
--- a/examples/webenginewidgets/browser/webview.h
+++ b/examples/webenginewidgets/demobrowser/webview.h
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
@@ -65,8 +64,8 @@ public:
BrowserMainWindow *mainWindow();
protected:
- bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame);
- QWebEnginePage *createWindow(QWebEnginePage::WebWindowType type);
+ bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame) Q_DECL_OVERRIDE;
+ QWebEnginePage *createWindow(QWebEnginePage::WebWindowType type) Q_DECL_OVERRIDE;
#if !defined(QT_NO_UITOOLS)
QObject *createPlugin(const QString &classId, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues);
#endif
@@ -85,7 +84,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..fa7beffde 100644
--- a/examples/webenginewidgets/browser/xbel.cpp
+++ b/examples/webenginewidgets/demobrowser/xbel.cpp
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
diff --git a/examples/webenginewidgets/browser/xbel.h b/examples/webenginewidgets/demobrowser/xbel.h
index d95549dd8..b0a931431 100644
--- a/examples/webenginewidgets/browser/xbel.h
+++ b/examples/webenginewidgets/demobrowser/xbel.h
@@ -1,39 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the demonstration applications of the Qt Toolkit.
+** This file is part of the examples 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.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** 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.
+** "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.
**
-** 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.
**
+** 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$
**
diff --git a/examples/webenginewidgets/markdowneditor/3RDPARTY.md b/examples/webenginewidgets/markdowneditor/3RDPARTY.md
new file mode 100644
index 000000000..9e91ab302
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/3RDPARTY.md
@@ -0,0 +1,23 @@
+## markd license
+
+```
+Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+```
diff --git a/examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.png b/examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.png
new file mode 100644
index 000000000..9f456c4db
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.png
Binary files differ
diff --git a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
new file mode 100644
index 000000000..44b1246b3
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+/*!
+ \example webenginewidgets/markdowneditor
+ \title Markdown Editor Example
+ \ingroup webengine-widgetexamples
+ \brief Demonstrates how to integrate a web engine in a hybrid desktop
+ application.
+
+ \image markdowneditor-example.png
+
+ \e {Markdown Editor} demonstrates how to use QWebChannel and JavaScript
+ libraries to provide a rich text preview tool for a custom markup language.
+
+ \l{http://daringfireball.net/projects/markdown/}{Markdown} is a lightweight
+ markup language with a plain text formatting syntax.
+ Some services, such as \l{http://github.com}{github}, acknowledge the
+ format, and render the content as rich text when viewed in a browser.
+
+ The Markdown Editor main window is split into an editor and a preview area.
+ The editor supports the Markdown syntax and is implemented by using
+ QPlainTextEdit. The document is rendered as rich text in the preview area,
+ which is implemented by using QWebEngineView. To render the text, the
+ Markdown text is converted to HTML format with the help of a JavaScript
+ library inside the web engine. The preview is updated from the editor
+ through QWebChannel.
+
+ \include examples-run.qdocinc
+
+ \section1 Exposing Document Text
+
+ Because we expose the current Markdown text to be rendered to the web engine
+ through QWebChannel, we need to somehow make the current text available
+ through the Qt metatype system. This is done by using a dedicated
+ \c Document class that exposes the document text as a \c{Q_PROPERTY}:
+
+ \quotefromfile webenginewidgets/markdowneditor/document.h
+ \skipto class Document
+ \printto #endif
+
+ The \c Document class wraps a QString to be set on the C++ side with
+ the \c setText() method and exposes it at runtime as a \c text property
+ with a \c textChanged signal.
+
+ We define the \c setText method as follows:
+
+ \quotefromfile webenginewidgets/markdowneditor/document.cpp
+ \skipto Document::setText
+ \printuntil
+
+ \section1 Previewing Text
+
+ We implement our own \c PreviewPage class that publicly inherits from
+ \c QWebEnginePage:
+
+ \quotefromfile webenginewidgets/markdowneditor/previewpage.h
+ \skipto class PreviewPage
+ \printto #endif
+
+ We reimplement the virtual \c acceptNavigationRequest method to
+ stop the page from navigating away from the current document. Instead,
+ we redirect external links to the system browser:
+
+ \quotefromfile webenginewidgets/markdowneditor/previewpage.cpp
+ \skipto acceptNavigationRequest
+ \printuntil
+
+ \section1 Creating the Main Window
+
+ The \c MainWindow class inherits the QMainWindow class:
+
+ \quotefromfile webenginewidgets/markdowneditor/mainwindow.h
+ \skipto class MainWindow :
+ \printto endif
+
+ The class declares private slots that match the actions in the menu,
+ as well as the \c isModified() helper method.
+
+ The actual layout of the main window is specified in a \c .ui file.
+ The widgets and actions are available at runtime in the \c ui member
+ variable.
+
+ \c m_filePath holds the file path to the currently loaded document.
+ \c m_content is an instance of the \c Document class.
+
+ The actual setup of the different objects is done in the \c MainWindow
+ constructor:
+
+ \quotefromfile webenginewidgets/markdowneditor/mainwindow.cpp
+ \skipto MainWindow::MainWindow
+ \printto connect
+
+ The constructor first calls \c setupUi to construct the widgets and menu
+ actions according to the UI file. It then makes sure our custom
+ \c PreviewPage is used by the QWebEngineView instance in \c{ui->preview}.
+
+ \printto ui->preview
+
+ Here the \c textChanged signal of the editor is connected to a lambda that
+ updates the text in \c m_content. This object is then exposed to the JS side
+ by \c QWebChannel under the name \c{content}.
+
+ \printto connect
+
+ Now we can actually load the \e index.html file from the
+ resources. For more information about the file, see
+ \l{Creating an Index File}.
+
+ \printto defaultTextFile
+
+ The menu items are connected to the mapping member slots. The
+ \uicontrol Save item is activated or deactivated depending on whether
+ the user has edited the content.
+
+ \printuntil }
+
+ Finally, we load a default document \e default.md from the resources.
+
+ \section1 Creating an Index File
+
+ \quotefile webenginewidgets/markdowneditor/resources/index.html
+
+ In the \e index.html, we load a custom stylesheet and two JavaScript
+ libraries. \l{http://kevinburke.bitbucket.org/markdowncss/}{markdown.css} is
+ a markdown-friendly stylesheet created by Kevin Burke.
+ \l{https://github.com/chjj/marked}{marked.min.js} is a markdown parser and
+ compiler designed for speed written by Christopher Jeffrey and
+ \e qwebchannel.js is part of the \l{QWebChannel} module.
+
+ In the \c <body> element we first define a \c placeholder element, and
+ make it available as a JavaScript variable. We then define the \c updateText
+ helper method that updates the content of \c placeholder with the HTML
+ that the JavaScript method \c marked() returns.
+
+ Finally, we set up the web channel to access the \c content proxy object
+ and make sure that \c updateText() is called whenever \c content.text
+ changes.
+*/
+
diff --git a/examples/webenginewidgets/markdowneditor/document.cpp b/examples/webenginewidgets/markdowneditor/document.cpp
new file mode 100644
index 000000000..31dfa3d8a
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/document.cpp
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+#include "document.h"
+
+void Document::setText(const QString &text)
+{
+ if (text == m_text)
+ return;
+ m_text = text;
+ emit textChanged(m_text);
+}
diff --git a/examples/webenginewidgets/markdowneditor/document.h b/examples/webenginewidgets/markdowneditor/document.h
new file mode 100644
index 000000000..909ad4f36
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/document.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+#ifndef DOCUMENT_H
+#define DOCUMENT_H
+
+#include <QObject>
+#include <QString>
+
+class Document : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)
+public:
+ explicit Document(QObject *parent = nullptr) : QObject(parent) {}
+
+ void setText(const QString &text);
+
+signals:
+ void textChanged(const QString &text);
+
+private:
+ QString m_text;
+};
+
+#endif // DOCUMENT_H
diff --git a/examples/webenginewidgets/markdowneditor/main.cpp b/examples/webenginewidgets/markdowneditor/main.cpp
new file mode 100644
index 000000000..73fe58199
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+#include "document.h"
+#include "mainwindow.h"
+
+#include <QApplication>
+#include <QFile>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+
+ MainWindow window;
+ window.show();
+
+ return a.exec();
+}
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.cpp b/examples/webenginewidgets/markdowneditor/mainwindow.cpp
new file mode 100644
index 000000000..352b7944a
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/mainwindow.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+#include "mainwindow.h"
+#include "previewpage.h"
+#include "ui_mainwindow.h"
+
+#include <QFile>
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QTextStream>
+#include <QWebChannel>
+
+MainWindow::MainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow)
+{
+ ui->setupUi(this);
+
+ PreviewPage *page = new PreviewPage(this);
+ ui->preview->setPage(page);
+
+ connect(ui->editor, &QPlainTextEdit::textChanged,
+ [this]() { m_content.setText(ui->editor->toPlainText()); });
+
+ QWebChannel *channel = new QWebChannel(this);
+ channel->registerObject(QStringLiteral("content"), &m_content);
+ page->setWebChannel(channel);
+
+ ui->preview->setUrl(QUrl("qrc:/index.html"));
+
+ connect(ui->actionNew, &QAction::triggered, this, &MainWindow::onFileNew);
+ connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::onFileOpen);
+ connect(ui->actionSave, &QAction::triggered, this, &MainWindow::onFileSave);
+ connect(ui->actionSaveAs, &QAction::triggered, this, &MainWindow::onFileSaveAs);
+ connect(ui->actionExit, &QAction::triggered, this, &MainWindow::onExit);
+
+ connect(ui->editor->document(), &QTextDocument::modificationChanged,
+ ui->actionSave, &QAction::setEnabled);
+
+ QFile defaultTextFile(":/default.md");
+ defaultTextFile.open(QIODevice::ReadOnly);
+ ui->editor->setPlainText(defaultTextFile.readAll());
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+bool MainWindow::isModified() const
+{
+ return ui->editor->document()->isModified();
+}
+
+void MainWindow::onFileNew()
+{
+ if (isModified()) {
+ QMessageBox::StandardButton button = QMessageBox::question(this, windowTitle(),
+ tr("You have unsaved changes. Do you want to create a new document anyway?"));
+ if (button != QMessageBox::Yes)
+ return;
+ }
+
+ m_filePath.clear();
+ ui->editor->setPlainText(tr("## New document"));
+ ui->editor->document()->setModified(false);
+}
+
+void MainWindow::onFileOpen()
+{
+ if (isModified()) {
+ QMessageBox::StandardButton button = QMessageBox::question(this, windowTitle(),
+ tr("You have unsaved changes. Do you want to open a new document anyway?"));
+ if (button != QMessageBox::Yes)
+ return;
+ }
+
+ QString path = QFileDialog::getOpenFileName(this,
+ tr("Open MarkDown File"), "", tr("MarkDown File (*.md)"));
+ if (path.isEmpty())
+ return;
+
+ QFile f(path);
+ if (!f.open(QIODevice::ReadOnly)) {
+ QMessageBox::warning(this, windowTitle(),
+ tr("Could not open file %1: %2").arg(
+ QDir::toNativeSeparators(path), f.errorString()));
+ return;
+ }
+ m_filePath = path;
+ ui->editor->setPlainText(f.readAll());
+}
+
+void MainWindow::onFileSave()
+{
+ if (m_filePath.isEmpty()) {
+ onFileSaveAs();
+ return;
+ }
+
+ QFile f(m_filePath);
+ if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ QMessageBox::warning(this, windowTitle(),
+ tr("Could not write to file %1: %2").arg(
+ QDir::toNativeSeparators(m_filePath), f.errorString()));
+ return;
+ }
+ QTextStream str(&f);
+ str << ui->editor->toPlainText();
+
+ ui->editor->document()->setModified(false);
+}
+
+void MainWindow::onFileSaveAs()
+{
+ QString path = QFileDialog::getSaveFileName(this,
+ tr("Save MarkDown File"), "", tr("MarkDown File (*.md, *.markdown)"));
+ if (path.isEmpty())
+ return;
+ m_filePath = path;
+ onFileSave();
+}
+
+void MainWindow::onExit()
+{
+ if (isModified()) {
+ QMessageBox::StandardButton button = QMessageBox::question(this, windowTitle(),
+ tr("You have unsaved changes. Do you want to exit anyway?"));
+ if (button != QMessageBox::Yes)
+ return;
+ }
+ close();
+}
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.h b/examples/webenginewidgets/markdowneditor/mainwindow.h
new file mode 100644
index 000000000..596b5c504
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/mainwindow.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include "document.h"
+
+#include <QMainWindow>
+#include <QString>
+
+QT_BEGIN_NAMESPACE
+namespace Ui {
+class MainWindow;
+}
+QT_END_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+private slots:
+ void onFileNew();
+ void onFileOpen();
+ void onFileSave();
+ void onFileSaveAs();
+ void onExit();
+
+private:
+ bool isModified() const;
+
+ Ui::MainWindow *ui;
+ QString m_filePath;
+ Document m_content;
+};
+
+#endif // MAINWINDOW_H
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.ui b/examples/webenginewidgets/markdowneditor/mainwindow.ui
new file mode 100644
index 000000000..36ab352b7
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/mainwindow.ui
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>600</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MarkDown Editor</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QSplitter" name="splitter">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <widget class="QPlainTextEdit" name="editor"/>
+ <widget class="QWebEngineView" name="preview" native="true"/>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menu_File">
+ <property name="title">
+ <string>&amp;File</string>
+ </property>
+ <addaction name="actionNew"/>
+ <addaction name="actionOpen"/>
+ <addaction name="actionSave"/>
+ <addaction name="actionSaveAs"/>
+ <addaction name="separator"/>
+ <addaction name="actionExit"/>
+ </widget>
+ <addaction name="menu_File"/>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ <action name="actionOpen">
+ <property name="text">
+ <string>&amp;Open...</string>
+ </property>
+ <property name="toolTip">
+ <string>Open document</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+O</string>
+ </property>
+ </action>
+ <action name="actionSave">
+ <property name="text">
+ <string>&amp;Save</string>
+ </property>
+ <property name="toolTip">
+ <string>Save current document</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+S</string>
+ </property>
+ </action>
+ <action name="actionExit">
+ <property name="text">
+ <string>E&amp;xit</string>
+ </property>
+ <property name="toolTip">
+ <string>Exit editor</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Q</string>
+ </property>
+ </action>
+ <action name="actionSaveAs">
+ <property name="text">
+ <string>Save &amp;As...</string>
+ </property>
+ <property name="toolTip">
+ <string>Save document under different name</string>
+ </property>
+ </action>
+ <action name="actionNew">
+ <property name="text">
+ <string>&amp;New</string>
+ </property>
+ <property name="toolTip">
+ <string>Create new document</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+N</string>
+ </property>
+ </action>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QWebEngineView</class>
+ <extends>QWidget</extends>
+ <header>qwebengineview.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/webenginewidgets/markdowneditor/markdowneditor.pro b/examples/webenginewidgets/markdowneditor/markdowneditor.pro
new file mode 100644
index 000000000..bfd16698a
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/markdowneditor.pro
@@ -0,0 +1,28 @@
+TEMPLATE = app
+
+QT += webenginewidgets webchannel
+CONFIG += c++11
+
+HEADERS += \
+ mainwindow.h \
+ previewpage.h \
+ document.h
+
+SOURCES = \
+ main.cpp \
+ mainwindow.cpp \
+ previewpage.cpp \
+ document.cpp
+
+RESOURCES = \
+ resources/markdowneditor.qrc
+
+FORMS += \
+ mainwindow.ui
+
+DISTFILES += \
+ 3RDPARTY.md
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/markdowneditor
+INSTALLS += target
diff --git a/examples/webenginewidgets/markdowneditor/previewpage.cpp b/examples/webenginewidgets/markdowneditor/previewpage.cpp
new file mode 100644
index 000000000..a48e23175
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/previewpage.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+#include "previewpage.h"
+
+#include <QDesktopServices>
+
+bool PreviewPage::acceptNavigationRequest(const QUrl &url,
+ QWebEnginePage::NavigationType /*type*/,
+ bool /*isMainFrame*/)
+{
+ // Only allow qrc:/index.html.
+ if (url.scheme() == QString("qrc"))
+ return true;
+ QDesktopServices::openUrl(url);
+ return false;
+}
diff --git a/examples/webenginewidgets/markdowneditor/previewpage.h b/examples/webenginewidgets/markdowneditor/previewpage.h
new file mode 100644
index 000000000..c0ea2c79a
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/previewpage.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+#ifndef PREVIEWPAGE_H
+#define PREVIEWPAGE_H
+
+#include <QWebEnginePage>
+
+class PreviewPage : public QWebEnginePage
+{
+ Q_OBJECT
+public:
+ explicit PreviewPage(QObject *parent = nullptr) : QWebEnginePage(parent) {}
+
+protected:
+ bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame);
+};
+
+#endif // PREVIEWPAGE_H
diff --git a/examples/webenginewidgets/markdowneditor/resources/default.md b/examples/webenginewidgets/markdowneditor/resources/default.md
new file mode 100644
index 000000000..e5905b101
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/resources/default.md
@@ -0,0 +1,12 @@
+## Markdown Editor Example
+
+This example uses [QWebEngineView](http://doc.qt.io/qt-5/qwebengineview.html)
+to preview text written using the [Markdown](https://en.wikipedia.org/wiki/Markdown)
+syntax.
+
+### Acknowledgments
+
+The conversion from Markdown to HTML is done with the help of the
+[marked JavaScript library](https://github.com/chjj/marked) by _Christopher Jeffrey_.
+The [style sheet](http://kevinburke.bitbucket.org/markdowncss/markdown.css)
+was created by _Kevin Burke_.
diff --git a/examples/webenginewidgets/markdowneditor/resources/index.html b/examples/webenginewidgets/markdowneditor/resources/index.html
new file mode 100644
index 000000000..2f45479ed
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/resources/index.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html lang="en">
+<meta charset="utf-8">
+<head>
+ <link rel="stylesheet" type="text/css" href="markdown.css">
+ <script src="marked.min.js"></script>
+ <script src="qwebchannel.js"></script>
+</head>
+<body>
+ <div id="placeholder"></div>
+ <script>
+ 'use strict';
+
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ updateText(content.text);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
+</body>
+</html>
+
+
+
diff --git a/examples/webenginewidgets/markdowneditor/resources/markdown.css b/examples/webenginewidgets/markdowneditor/resources/markdown.css
new file mode 100644
index 000000000..24fc2ffe2
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/resources/markdown.css
@@ -0,0 +1,260 @@
+body{
+ margin: 0 auto;
+ font-family: Georgia, Palatino, serif;
+ color: #444444;
+ line-height: 1;
+ max-width: 960px;
+ padding: 30px;
+}
+h1, h2, h3, h4 {
+ color: #111111;
+ font-weight: 400;
+}
+h1, h2, h3, h4, h5, p {
+ margin-bottom: 24px;
+ padding: 0;
+}
+h1 {
+ font-size: 48px;
+}
+h2 {
+ font-size: 36px;
+ /* The bottom margin is small. It's designed to be used with gray meta text
+ * below a post title. */
+ margin: 24px 0 6px;
+}
+h3 {
+ font-size: 24px;
+}
+h4 {
+ font-size: 21px;
+}
+h5 {
+ font-size: 18px;
+}
+a {
+ color: #0099ff;
+ margin: 0;
+ padding: 0;
+ vertical-align: baseline;
+}
+a:hover {
+ text-decoration: none;
+ color: #ff6600;
+}
+a:visited {
+ color: purple;
+}
+ul, ol {
+ padding: 0;
+ margin: 0;
+}
+li {
+ line-height: 24px;
+}
+li ul, li ul {
+ margin-left: 24px;
+}
+p, ul, ol {
+ font-size: 16px;
+ line-height: 24px;
+ max-width: 540px;
+}
+pre {
+ padding: 0px 24px;
+ max-width: 800px;
+ white-space: pre-wrap;
+}
+code {
+ font-family: Consolas, Monaco, Andale Mono, monospace;
+ line-height: 1.5;
+ font-size: 13px;
+}
+aside {
+ display: block;
+ float: right;
+ width: 390px;
+}
+blockquote {
+ border-left:.5em solid #eee;
+ padding: 0 2em;
+ margin-left:0;
+ max-width: 476px;
+}
+blockquote cite {
+ font-size:14px;
+ line-height:20px;
+ color:#bfbfbf;
+}
+blockquote cite:before {
+ content: '\2014 \00A0';
+}
+
+blockquote p {
+ color: #666;
+ max-width: 460px;
+}
+hr {
+ width: 540px;
+ text-align: left;
+ margin: 0 auto 0 0;
+ color: #999;
+}
+
+/* Code below this line is copyright Twitter Inc. */
+
+button,
+input,
+select,
+textarea {
+ font-size: 100%;
+ margin: 0;
+ vertical-align: baseline;
+ *vertical-align: middle;
+}
+button, input {
+ line-height: normal;
+ *overflow: visible;
+}
+button::-moz-focus-inner, input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+button,
+input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ cursor: pointer;
+ -webkit-appearance: button;
+}
+input[type=checkbox], input[type=radio] {
+ cursor: pointer;
+}
+/* override default chrome & firefox settings */
+input:not([type="image"]), textarea {
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+
+input[type="search"] {
+ -webkit-appearance: textfield;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+label,
+input,
+select,
+textarea {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 13px;
+ font-weight: normal;
+ line-height: normal;
+ margin-bottom: 18px;
+}
+input[type=checkbox], input[type=radio] {
+ cursor: pointer;
+ margin-bottom: 0;
+}
+input[type=text],
+input[type=password],
+textarea,
+select {
+ display: inline-block;
+ width: 210px;
+ padding: 4px;
+ font-size: 13px;
+ font-weight: normal;
+ line-height: 18px;
+ height: 18px;
+ color: #808080;
+ border: 1px solid #ccc;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+select, input[type=file] {
+ height: 27px;
+ line-height: 27px;
+}
+textarea {
+ height: auto;
+}
+
+/* grey out placeholders */
+:-moz-placeholder {
+ color: #bfbfbf;
+}
+::-webkit-input-placeholder {
+ color: #bfbfbf;
+}
+
+input[type=text],
+input[type=password],
+select,
+textarea {
+ -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
+ -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
+ transition: border linear 0.2s, box-shadow linear 0.2s;
+ -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
+ -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
+}
+input[type=text]:focus, input[type=password]:focus, textarea:focus {
+ outline: none;
+ border-color: rgba(82, 168, 236, 0.8);
+ -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
+ -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
+}
+
+/* buttons */
+button {
+ display: inline-block;
+ padding: 4px 14px;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 13px;
+ line-height: 18px;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ background-color: #0064cd;
+ background-repeat: repeat-x;
+ background-image: -khtml-gradient(linear, left top, left bottom, from(#049cdb), to(#0064cd));
+ background-image: -moz-linear-gradient(top, #049cdb, #0064cd);
+ background-image: -ms-linear-gradient(top, #049cdb, #0064cd);
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #049cdb), color-stop(100%, #0064cd));
+ background-image: -webkit-linear-gradient(top, #049cdb, #0064cd);
+ background-image: -o-linear-gradient(top, #049cdb, #0064cd);
+ background-image: linear-gradient(top, #049cdb, #0064cd);
+ color: #fff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ border: 1px solid #004b9a;
+ border-bottom-color: #003f81;
+ -webkit-transition: 0.1s linear all;
+ -moz-transition: 0.1s linear all;
+ transition: 0.1s linear all;
+ border-color: #0064cd #0064cd #003f81;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+}
+button:hover {
+ color: #fff;
+ background-position: 0 -15px;
+ text-decoration: none;
+}
+button:active {
+ -webkit-box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+button::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
diff --git a/examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc b/examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc
new file mode 100644
index 000000000..8b7471a9c
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc
@@ -0,0 +1,9 @@
+<RCC>
+ <qresource prefix="/">
+ <file>index.html</file>
+ <file>qwebchannel.js</file>
+ <file>marked.min.js</file>
+ <file>default.md</file>
+ <file>markdown.css</file>
+ </qresource>
+</RCC>
diff --git a/examples/webenginewidgets/markdowneditor/resources/marked.min.js b/examples/webenginewidgets/markdowneditor/resources/marked.min.js
new file mode 100644
index 000000000..f3542fff0
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/resources/marked.min.js
@@ -0,0 +1,6 @@
+/**
+ * marked - a markdown parser
+ * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/chjj/marked
+ */
+(function(){var block={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:noop,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:noop,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+block.def.source+")")();block.blockquote=replace(block.blockquote)("def",block.def)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b";block.html=replace(block.html)("comment",/<!--[\s\S]*?-->/)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1","\\2")+"|"+block.list.source.replace("\\1","\\3")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm){if(this.options.tables){this.rules=block.tables}else{this.rules=block.gfm}}}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)};Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top,bq){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1){this.tokens.push({type:"space"})}}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm,"");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]||""});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i<item.align.length;i++){if(/^ *-+: *$/.test(item.align[i])){item.align[i]="right"}else if(/^ *:-+: *$/.test(item.align[i])){item.align[i]="center"}else if(/^ *:-+ *$/.test(item.align[i])){item.align[i]="left"}else{item.align[i]=null}}for(i=0;i<item.cells.length;i++){item.cells[i]=item.cells[i].split(/ *\| */)}this.tokens.push(item);continue}if(cap=this.rules.lheading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[2]==="="?1:2,text:cap[1]});continue}if(cap=this.rules.hr.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"hr"});continue}if(cap=this.rules.blockquote.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"blockquote_start"});cap=cap[0].replace(/^ *> ?/gm,"");this.token(cap,top,true);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length);bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i<l;i++){item=cap[i];space=item.length;item=item.replace(/^ *([*+-]|\d+\.) +/,"");if(~item.indexOf("\n ")){space-=item.length;item=!this.options.pedantic?item.replace(new RegExp("^ {1,"+space+"}","gm"),""):item.replace(/^ {1,4}/gm,"")}if(this.options.smartLists&&i!==l-1){b=block.bullet.exec(cap[i+1])[0];if(bull!==b&&!(bull.length>1&&b.length>1)){src=cap.slice(i+1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item.charAt(item.length-1)==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false,bq);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&(cap[1]==="pre"||cap[1]==="script"||cap[1]==="style"),text:cap[0]});continue}if(!bq&&top&&(cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i<item.align.length;i++){if(/^ *-+: *$/.test(item.align[i])){item.align[i]="right"}else if(/^ *:-+: *$/.test(item.align[i])){item.align[i]="center"}else if(/^ *:-+ *$/.test(item.align[i])){item.align[i]="left"}else{item.align[i]=null}}for(i=0;i<item.cells.length;i++){item.cells[i]=item.cells[i].replace(/^ *\| *| *\| *$/g,"").split(/ *\| */)}this.tokens.push(item);continue}if(top&&(cap=this.rules.paragraph.exec(src))){src=src.substring(cap[0].length);this.tokens.push({type:"paragraph",text:cap[1].charAt(cap[1].length-1)==="\n"?cap[1].slice(0,-1):cap[1]});continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"text",text:cap[0]});continue}if(src){throw new Error("Infinite loop on byte: "+src.charCodeAt(0))}}return this.tokens};var inline={escape:/^\\([\\`*{}\[\]()#+\-.!_>])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/};inline._inside=/(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;inline._href=/\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal;this.renderer=this.options.renderer||new Renderer;this.renderer.options=this.options;if(!this.links){throw new Error("Tokens array requires a `links` property.")}if(this.options.gfm){if(this.options.breaks){this.rules=inline.breaks}else{this.rules=inline.gfm}}else if(this.options.pedantic){this.rules=inline.pedantic}}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length);out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1].charAt(6)===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+=this.renderer.link(href,null,text);continue}if(!this.inLink&&(cap=this.rules.url.exec(src))){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+=this.renderer.link(href,null,text);continue}if(cap=this.rules.tag.exec(src)){if(!this.inLink&&/^<a /i.test(cap[0])){this.inLink=true}else if(this.inLink&&/^<\/a>/i.test(cap[0])){this.inLink=false}src=src.substring(cap[0].length);out+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(cap[0]):escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);this.inLink=true;out+=this.outputLink(cap,{href:cap[2],title:cap[3]});this.inLink=false;continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0].charAt(0);src=cap[0].substring(1)+src;continue}this.inLink=true;out+=this.outputLink(cap,link);this.inLink=false;continue}if(cap=this.rules.strong.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.strong(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.em(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.codespan(escape(cap[2],true));continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.br();continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.del(this.output(cap[1]));continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.text(escape(this.smartypants(cap[0])));continue}if(src){throw new Error("Infinite loop on byte: "+src.charCodeAt(0))}}return out};InlineLexer.prototype.outputLink=function(cap,link){var href=escape(link.href),title=link.title?escape(link.title):null;return cap[0].charAt(0)!=="!"?this.renderer.link(href,title,this.output(cap[1])):this.renderer.image(href,title,escape(cap[1]))};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…")};InlineLexer.prototype.mangle=function(text){if(!this.options.mangle)return text;var out="",l=text.length,i=0,ch;for(;i<l;i++){ch=text.charCodeAt(i);if(Math.random()>.5){ch="x"+ch.toString(16)}out+="&#"+ch+";"}return out};function Renderer(options){this.options=options||{}}Renderer.prototype.code=function(code,lang,escaped){if(this.options.highlight){var out=this.options.highlight(code,lang);if(out!=null&&out!==code){escaped=true;code=out}}if(!lang){return"<pre><code>"+(escaped?code:escape(code,true))+"\n</code></pre>"}return'<pre><code class="'+this.options.langPrefix+escape(lang,true)+'">'+(escaped?code:escape(code,true))+"\n</code></pre>\n"};Renderer.prototype.blockquote=function(quote){return"<blockquote>\n"+quote+"</blockquote>\n"};Renderer.prototype.html=function(html){return html};Renderer.prototype.heading=function(text,level,raw){return"<h"+level+' id="'+this.options.headerPrefix+raw.toLowerCase().replace(/[^\w]+/g,"-")+'">'+text+"</h"+level+">\n"};Renderer.prototype.hr=function(){return this.options.xhtml?"<hr/>\n":"<hr>\n"};Renderer.prototype.list=function(body,ordered){var type=ordered?"ol":"ul";return"<"+type+">\n"+body+"</"+type+">\n"};Renderer.prototype.listitem=function(text){return"<li>"+text+"</li>\n"};Renderer.prototype.paragraph=function(text){return"<p>"+text+"</p>\n"};Renderer.prototype.table=function(header,body){return"<table>\n"+"<thead>\n"+header+"</thead>\n"+"<tbody>\n"+body+"</tbody>\n"+"</table>\n"};Renderer.prototype.tablerow=function(content){return"<tr>\n"+content+"</tr>\n"};Renderer.prototype.tablecell=function(content,flags){var type=flags.header?"th":"td";var tag=flags.align?"<"+type+' style="text-align:'+flags.align+'">':"<"+type+">";return tag+content+"</"+type+">\n"};Renderer.prototype.strong=function(text){return"<strong>"+text+"</strong>"};Renderer.prototype.em=function(text){return"<em>"+text+"</em>"};Renderer.prototype.codespan=function(text){return"<code>"+text+"</code>"};Renderer.prototype.br=function(){return this.options.xhtml?"<br/>":"<br>"};Renderer.prototype.del=function(text){return"<del>"+text+"</del>"};Renderer.prototype.link=function(href,title,text){if(this.options.sanitize){try{var prot=decodeURIComponent(unescape(href)).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return""}if(prot.indexOf("javascript:")===0||prot.indexOf("vbscript:")===0){return""}}var out='<a href="'+href+'"';if(title){out+=' title="'+title+'"'}out+=">"+text+"</a>";return out};Renderer.prototype.image=function(href,title,text){var out='<img src="'+href+'" alt="'+text+'"';if(title){out+=' title="'+title+'"'}out+=this.options.xhtml?"/>":">";return out};Renderer.prototype.text=function(text){return text};function Parser(options){this.tokens=[];this.token=null;this.options=options||marked.defaults;this.options.renderer=this.options.renderer||new Renderer;this.renderer=this.options.renderer;this.renderer.options=this.options}Parser.parse=function(src,options,renderer){var parser=new Parser(options,renderer);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options,this.renderer);this.tokens=src.reverse();var out="";while(this.next()){out+=this.tok()}return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text;while(this.peek().type==="text"){body+="\n"+this.next().text}return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case"space":{return""}case"hr":{return this.renderer.hr()}case"heading":{return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text)}case"code":{return this.renderer.code(this.token.text,this.token.lang,this.token.escaped)}case"table":{var header="",body="",i,row,cell,flags,j;cell="";for(i=0;i<this.token.header.length;i++){flags={header:true,align:this.token.align[i]};cell+=this.renderer.tablecell(this.inline.output(this.token.header[i]),{header:true,align:this.token.align[i]})}header+=this.renderer.tablerow(cell);for(i=0;i<this.token.cells.length;i++){row=this.token.cells[i];cell="";for(j=0;j<row.length;j++){cell+=this.renderer.tablecell(this.inline.output(row[j]),{header:false,align:this.token.align[j]})}body+=this.renderer.tablerow(cell)}return this.renderer.table(header,body)}case"blockquote_start":{var body="";while(this.next().type!=="blockquote_end"){body+=this.tok()}return this.renderer.blockquote(body)}case"list_start":{var body="",ordered=this.token.ordered;while(this.next().type!=="list_end"){body+=this.tok()}return this.renderer.list(body,ordered)}case"list_item_start":{var body="";while(this.next().type!=="list_item_end"){body+=this.token.type==="text"?this.parseText():this.tok()}return this.renderer.listitem(body)}case"loose_item_start":{var body="";while(this.next().type!=="list_item_end"){body+=this.tok()}return this.renderer.listitem(body)}case"html":{var html=!this.token.pre&&!this.options.pedantic?this.inline.output(this.token.text):this.token.text;return this.renderer.html(html)}case"paragraph":{return this.renderer.paragraph(this.inline.output(this.token.text))}case"text":{return this.renderer.paragraph(this.parseText())}}};function escape(html,encode){return html.replace(!encode?/&(?!#?\w+;)/g:/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function unescape(html){return html.replace(/&([#\w]+);/g,function(_,n){n=n.toLowerCase();if(n==="colon")return":";if(n.charAt(0)==="#"){return n.charAt(1)==="x"?String.fromCharCode(parseInt(n.substring(2),16)):String.fromCharCode(+n.substring(1))}return""})}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i=1,target,key;for(;i<arguments.length;i++){target=arguments[i];for(key in target){if(Object.prototype.hasOwnProperty.call(target,key)){obj[key]=target[key]}}}return obj}function marked(src,opt,callback){if(callback||typeof opt==="function"){if(!callback){callback=opt;opt=null}opt=merge({},marked.defaults,opt||{});var highlight=opt.highlight,tokens,pending,i=0;try{tokens=Lexer.lex(src,opt)}catch(e){return callback(e)}pending=tokens.length;var done=function(err){if(err){opt.highlight=highlight;return callback(err)}var out;try{out=Parser.parse(tokens,opt)}catch(e){err=e}opt.highlight=highlight;return err?callback(err):callback(null,out)};if(!highlight||highlight.length<3){return done()}delete opt.highlight;if(!pending)return done();for(;i<tokens.length;i++){(function(token){if(token.type!=="code"){return--pending||done()}return highlight(token.text,token.lang,function(err,code){if(err)return done(err);if(code==null||code===token.text){return--pending||done()}token.text=code;token.escaped=true;--pending||done()})})(tokens[i])}return}try{if(opt)opt=merge({},marked.defaults,opt);return Parser.parse(Lexer.lex(src,opt),opt)}catch(e){e.message+="\nPlease report this to https://github.com/chjj/marked.";if((opt||marked.defaults).silent){return"<p>An error occurred:</p><pre>"+escape(e.message+"",true)+"</pre>"}throw e}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,sanitizer:null,mangle:true,smartLists:false,silent:false,highlight:null,langPrefix:"lang-",smartypants:false,headerPrefix:"",renderer:new Renderer,xhtml:false};marked.Parser=Parser;marked.parser=Parser.parse;marked.Renderer=Renderer;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;marked.parse=marked;if(typeof module!=="undefined"&&typeof exports==="object"){module.exports=marked}else if(typeof define==="function"&&define.amd){define(function(){return marked})}else{this.marked=marked}}).call(function(){return this||(typeof window!=="undefined"?window:global)}()); \ No newline at end of file
diff --git a/examples/webenginewidgets/markdowneditor/resources/qwebchannel.js b/examples/webenginewidgets/markdowneditor/resources/qwebchannel.js
new file mode 100644
index 000000000..d3d7f5e11
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/resources/qwebchannel.js
@@ -0,0 +1,419 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+"use strict";
+
+var QWebChannelMessageTypes = {
+ signal: 1,
+ propertyUpdate: 2,
+ init: 3,
+ idle: 4,
+ debug: 5,
+ invokeMethod: 6,
+ connectToSignal: 7,
+ disconnectFromSignal: 8,
+ setProperty: 9,
+ response: 10,
+};
+
+var QWebChannel = function(transport, initCallback)
+{
+ if (typeof transport !== "object" || typeof transport.send !== "function") {
+ console.error("The QWebChannel expects a transport object with a send function and onmessage callback property." +
+ " Given is: transport: " + typeof(transport) + ", transport.send: " + typeof(transport.send));
+ return;
+ }
+
+ var channel = this;
+ this.transport = transport;
+
+ this.send = function(data)
+ {
+ if (typeof(data) !== "string") {
+ data = JSON.stringify(data);
+ }
+ channel.transport.send(data);
+ }
+
+ this.transport.onmessage = function(message)
+ {
+ var data = message.data;
+ if (typeof data === "string") {
+ data = JSON.parse(data);
+ }
+ switch (data.type) {
+ case QWebChannelMessageTypes.signal:
+ channel.handleSignal(data);
+ break;
+ case QWebChannelMessageTypes.response:
+ channel.handleResponse(data);
+ break;
+ case QWebChannelMessageTypes.propertyUpdate:
+ channel.handlePropertyUpdate(data);
+ break;
+ default:
+ console.error("invalid message received:", message.data);
+ break;
+ }
+ }
+
+ this.execCallbacks = {};
+ this.execId = 0;
+ this.exec = function(data, callback)
+ {
+ if (!callback) {
+ // if no callback is given, send directly
+ channel.send(data);
+ return;
+ }
+ if (channel.execId === Number.MAX_VALUE) {
+ // wrap
+ channel.execId = Number.MIN_VALUE;
+ }
+ if (data.hasOwnProperty("id")) {
+ console.error("Cannot exec message with property id: " + JSON.stringify(data));
+ return;
+ }
+ data.id = channel.execId++;
+ channel.execCallbacks[data.id] = callback;
+ channel.send(data);
+ };
+
+ this.objects = {};
+
+ this.handleSignal = function(message)
+ {
+ var object = channel.objects[message.object];
+ if (object) {
+ object.signalEmitted(message.signal, message.args);
+ } else {
+ console.warn("Unhandled signal: " + message.object + "::" + message.signal);
+ }
+ }
+
+ this.handleResponse = function(message)
+ {
+ if (!message.hasOwnProperty("id")) {
+ console.error("Invalid response message received: ", JSON.stringify(message));
+ return;
+ }
+ channel.execCallbacks[message.id](message.data);
+ delete channel.execCallbacks[message.id];
+ }
+
+ this.handlePropertyUpdate = function(message)
+ {
+ for (var i in message.data) {
+ var data = message.data[i];
+ var object = channel.objects[data.object];
+ if (object) {
+ object.propertyUpdate(data.signals, data.properties);
+ } else {
+ console.warn("Unhandled property update: " + data.object + "::" + data.signal);
+ }
+ }
+ channel.exec({type: QWebChannelMessageTypes.idle});
+ }
+
+ this.debug = function(message)
+ {
+ channel.send({type: QWebChannelMessageTypes.debug, data: message});
+ };
+
+ channel.exec({type: QWebChannelMessageTypes.init}, function(data) {
+ for (var objectName in data) {
+ var object = new QObject(objectName, data[objectName], channel);
+ }
+ // now unwrap properties, which might reference other registered objects
+ for (var objectName in channel.objects) {
+ channel.objects[objectName].unwrapProperties();
+ }
+ if (initCallback) {
+ initCallback(channel);
+ }
+ channel.exec({type: QWebChannelMessageTypes.idle});
+ });
+};
+
+function QObject(name, data, webChannel)
+{
+ this.__id__ = name;
+ webChannel.objects[name] = this;
+
+ // List of callbacks that get invoked upon signal emission
+ this.__objectSignals__ = {};
+
+ // Cache of all properties, updated when a notify signal is emitted
+ this.__propertyCache__ = {};
+
+ var object = this;
+
+ // ----------------------------------------------------------------------
+
+ this.unwrapQObject = function(response)
+ {
+ if (response instanceof Array) {
+ // support list of objects
+ var ret = new Array(response.length);
+ for (var i = 0; i < response.length; ++i) {
+ ret[i] = object.unwrapQObject(response[i]);
+ }
+ return ret;
+ }
+ if (!response
+ || !response["__QObject*__"]
+ || response.id === undefined) {
+ return response;
+ }
+
+ var objectId = response.id;
+ if (webChannel.objects[objectId])
+ return webChannel.objects[objectId];
+
+ if (!response.data) {
+ console.error("Cannot unwrap unknown QObject " + objectId + " without data.");
+ return;
+ }
+
+ var qObject = new QObject( objectId, response.data, webChannel );
+ qObject.destroyed.connect(function() {
+ if (webChannel.objects[objectId] === qObject) {
+ delete webChannel.objects[objectId];
+ // reset the now deleted QObject to an empty {} object
+ // just assigning {} though would not have the desired effect, but the
+ // below also ensures all external references will see the empty map
+ // NOTE: this detour is necessary to workaround QTBUG-40021
+ var propertyNames = [];
+ for (var propertyName in qObject) {
+ propertyNames.push(propertyName);
+ }
+ for (var idx in propertyNames) {
+ delete qObject[propertyNames[idx]];
+ }
+ }
+ });
+ // here we are already initialized, and thus must directly unwrap the properties
+ qObject.unwrapProperties();
+ return qObject;
+ }
+
+ this.unwrapProperties = function()
+ {
+ for (var propertyIdx in object.__propertyCache__) {
+ object.__propertyCache__[propertyIdx] = object.unwrapQObject(object.__propertyCache__[propertyIdx]);
+ }
+ }
+
+ function addSignal(signalData, isPropertyNotifySignal)
+ {
+ var signalName = signalData[0];
+ var signalIndex = signalData[1];
+ object[signalName] = {
+ connect: function(callback) {
+ if (typeof(callback) !== "function") {
+ console.error("Bad callback given to connect to signal " + signalName);
+ return;
+ }
+
+ object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];
+ object.__objectSignals__[signalIndex].push(callback);
+
+ if (!isPropertyNotifySignal && signalName !== "destroyed") {
+ // only required for "pure" signals, handled separately for properties in propertyUpdate
+ // also note that we always get notified about the destroyed signal
+ webChannel.exec({
+ type: QWebChannelMessageTypes.connectToSignal,
+ object: object.__id__,
+ signal: signalIndex
+ });
+ }
+ },
+ disconnect: function(callback) {
+ if (typeof(callback) !== "function") {
+ console.error("Bad callback given to disconnect from signal " + signalName);
+ return;
+ }
+ object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];
+ var idx = object.__objectSignals__[signalIndex].indexOf(callback);
+ if (idx === -1) {
+ console.error("Cannot find connection of signal " + signalName + " to " + callback.name);
+ return;
+ }
+ object.__objectSignals__[signalIndex].splice(idx, 1);
+ if (!isPropertyNotifySignal && object.__objectSignals__[signalIndex].length === 0) {
+ // only required for "pure" signals, handled separately for properties in propertyUpdate
+ webChannel.exec({
+ type: QWebChannelMessageTypes.disconnectFromSignal,
+ object: object.__id__,
+ signal: signalIndex
+ });
+ }
+ }
+ };
+ }
+
+ /**
+ * Invokes all callbacks for the given signalname. Also works for property notify callbacks.
+ */
+ function invokeSignalCallbacks(signalName, signalArgs)
+ {
+ var connections = object.__objectSignals__[signalName];
+ if (connections) {
+ connections.forEach(function(callback) {
+ callback.apply(callback, signalArgs);
+ });
+ }
+ }
+
+ this.propertyUpdate = function(signals, propertyMap)
+ {
+ // update property cache
+ for (var propertyIndex in propertyMap) {
+ var propertyValue = propertyMap[propertyIndex];
+ object.__propertyCache__[propertyIndex] = propertyValue;
+ }
+
+ for (var signalName in signals) {
+ // Invoke all callbacks, as signalEmitted() does not. This ensures the
+ // property cache is updated before the callbacks are invoked.
+ invokeSignalCallbacks(signalName, signals[signalName]);
+ }
+ }
+
+ this.signalEmitted = function(signalName, signalArgs)
+ {
+ invokeSignalCallbacks(signalName, signalArgs);
+ }
+
+ function addMethod(methodData)
+ {
+ var methodName = methodData[0];
+ var methodIdx = methodData[1];
+ object[methodName] = function() {
+ var args = [];
+ var callback;
+ for (var i = 0; i < arguments.length; ++i) {
+ if (typeof arguments[i] === "function")
+ callback = arguments[i];
+ else
+ args.push(arguments[i]);
+ }
+
+ webChannel.exec({
+ "type": QWebChannelMessageTypes.invokeMethod,
+ "object": object.__id__,
+ "method": methodIdx,
+ "args": args
+ }, function(response) {
+ if (response !== undefined) {
+ var result = object.unwrapQObject(response);
+ if (callback) {
+ (callback)(result);
+ }
+ }
+ });
+ };
+ }
+
+ function bindGetterSetter(propertyInfo)
+ {
+ var propertyIndex = propertyInfo[0];
+ var propertyName = propertyInfo[1];
+ var notifySignalData = propertyInfo[2];
+ // initialize property cache with current value
+ // NOTE: if this is an object, it is not directly unwrapped as it might
+ // reference other QObject that we do not know yet
+ object.__propertyCache__[propertyIndex] = propertyInfo[3];
+
+ if (notifySignalData) {
+ if (notifySignalData[0] === 1) {
+ // signal name is optimized away, reconstruct the actual name
+ notifySignalData[0] = propertyName + "Changed";
+ }
+ addSignal(notifySignalData, true);
+ }
+
+ Object.defineProperty(object, propertyName, {
+ configurable: true,
+ get: function () {
+ var propertyValue = object.__propertyCache__[propertyIndex];
+ if (propertyValue === undefined) {
+ // This shouldn't happen
+ console.warn("Undefined value in property cache for property \"" + propertyName + "\" in object " + object.__id__);
+ }
+
+ return propertyValue;
+ },
+ set: function(value) {
+ if (value === undefined) {
+ console.warn("Property setter for " + propertyName + " called with undefined value!");
+ return;
+ }
+ object.__propertyCache__[propertyIndex] = value;
+ webChannel.exec({
+ "type": QWebChannelMessageTypes.setProperty,
+ "object": object.__id__,
+ "property": propertyIndex,
+ "value": value
+ });
+ }
+ });
+
+ }
+
+ // ----------------------------------------------------------------------
+
+ data.methods.forEach(addMethod);
+
+ data.properties.forEach(bindGetterSetter);
+
+ data.signals.forEach(function(signal) { addSignal(signal, false); });
+
+ for (var name in data.enums) {
+ object[name] = data.enums[name];
+ }
+}
+
+//required for use with nodejs
+if (typeof module === 'object') {
+ module.exports = {
+ QWebChannel: QWebChannel
+ };
+}
diff --git a/src/3rdparty b/src/3rdparty
-Subproject c503d7f64552e5dea3dbf5623672180fec4ad07
+Subproject 77b91185050176b88c446fdb1b33b92dd737dd8
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro
new file mode 100644
index 000000000..19b67876c
--- /dev/null
+++ b/src/core/api/core_api.pro
@@ -0,0 +1,58 @@
+TARGET = qtwebenginecoreapi$$qtPlatformTargetSuffix()
+DESTDIR = $$OUT_PWD/$$getConfigDir()
+
+TEMPLATE = lib
+
+CONFIG += staticlib c++11
+QT += network core-private
+QT_PRIVATE += webenginecoreheaders-private
+
+# 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 \
+ qwebenginecookiestore.h \
+ qwebenginecookiestore_p.h \
+ qwebengineurlrequestinterceptor.h \
+ qwebengineurlrequestinfo.h \
+ qwebengineurlrequestinfo_p.h \
+ qwebengineurlrequestjob.h \
+ qwebengineurlschemehandler.h
+
+SOURCES = \
+ qtwebenginecoreglobal.cpp \
+ qwebenginecookiestore.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.cpp b/src/core/api/qtwebenginecoreglobal.cpp
new file mode 100644
index 000000000..0e857d7d9
--- /dev/null
+++ b/src/core/api/qtwebenginecoreglobal.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** 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 "qtwebenginecoreglobal_p.h"
+
+#include <QGuiApplication>
+#include <QOpenGLContext>
+#include <QThread>
+
+QT_BEGIN_NAMESPACE
+Q_GUI_EXPORT void qt_gl_set_global_share_context(QOpenGLContext *context);
+Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
+QT_END_NAMESPACE
+
+namespace QtWebEngineCore {
+
+static QOpenGLContext *shareContext;
+
+static void deleteShareContext()
+{
+ delete shareContext;
+ shareContext = 0;
+}
+
+// ### Qt 6: unify this logic and Qt::AA_ShareOpenGLContexts.
+// 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.
+
+QWEBENGINE_PRIVATE_EXPORT void initialize()
+{
+#ifdef Q_OS_WIN32
+ qputenv("QT_D3DCREATE_MULTITHREADED", "1");
+#endif
+
+ // No need to override the shared context if QApplication already set one (e.g with Qt::AA_ShareOpenGLContexts).
+ if (qt_gl_global_share_context())
+ return;
+
+ QCoreApplication *app = QCoreApplication::instance();
+ if (!app) {
+ qFatal("QtWebEngine::initialize() must be called after the construction of the application object.");
+ return;
+ }
+ if (app->thread() != QThread::currentThread()) {
+ qFatal("QtWebEngine::initialize() must be called from the Qt gui thread.");
+ return;
+ }
+
+ if (shareContext)
+ return;
+
+ shareContext = new QOpenGLContext;
+ shareContext->create();
+ qAddPostRoutine(deleteShareContext);
+ qt_gl_set_global_share_context(shareContext);
+
+ // Classes like QOpenGLWidget check for the attribute
+ app->setAttribute(Qt::AA_ShareOpenGLContexts);
+}
+} // namespace QtWebEngineCore
diff --git a/src/core/api/qtwebenginecoreglobal.h b/src/core/api/qtwebenginecoreglobal.h
new file mode 100644
index 000000000..a17b355eb
--- /dev/null
+++ b/src/core/api/qtwebenginecoreglobal.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** 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>
+
+QT_BEGIN_NAMESPACE
+
+#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");
+
+QT_END_NAMESPACE
+
+#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..a8758df7d
--- /dev/null
+++ b/src/core/api/qwebenginecallback.h
@@ -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: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 <QtWebEngineCore/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() { }
+ void swap(QWebEngineCallback &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+ operator bool() const { return d; }
+private:
+ friend class QtWebEngineCore::CallbackDirectory;
+ QExplicitlySharedDataPointer<QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> > d;
+};
+
+Q_DECLARE_SHARED(QWebEngineCallback<int>)
+Q_DECLARE_SHARED(QWebEngineCallback<const QByteArray &>)
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineCallback<bool>)
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineCallback<const QString &>)
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineCallback<const QVariant &>)
+
+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..348fed464
--- /dev/null
+++ b/src/core/api/qwebenginecallback_p.h
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** 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
+
+//
+// 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.h"
+
+#include <QByteArray>
+#include <QHash>
+#include <QSharedData>
+#include <QString>
+#include <QVariant>
+#include <type_traits>
+
+// keep in sync with Q_DECLARE_SHARED... in qwebenginecallback.h
+#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);
+}
+
+#define CHECK_RELOCATABLE(x) \
+ Q_STATIC_ASSERT((QTypeInfoQuery<QWebEngineCallback< x > >::isRelocatable));
+FOR_EACH_TYPE(CHECK_RELOCATABLE)
+#undef CHECK_RELOCATABLE
+
+} // namespace QtWebEngineCore
+
+#endif // QWEBENGINECALLBACK_P_H
diff --git a/src/core/api/qwebenginecookiestore.cpp b/src/core/api/qwebenginecookiestore.cpp
new file mode 100644
index 000000000..5220073f3
--- /dev/null
+++ b/src/core/api/qwebenginecookiestore.cpp
@@ -0,0 +1,307 @@
+/****************************************************************************
+**
+** 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 "qwebenginecookiestore.h"
+#include "qwebenginecookiestore_p.h"
+
+#include <cookie_monster_delegate_qt.h>
+
+#include <QByteArray>
+#include <QUrl>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QtWebEngineCore;
+
+QWebEngineCookieStorePrivate::QWebEngineCookieStorePrivate()
+ : m_nextCallbackId(CallbackDirectory::ReservedCallbackIdsEnd)
+ , m_deleteSessionCookiesPending(false)
+ , m_deleteAllCookiesPending(false)
+ , m_getAllCookiesPending(false)
+ , delegate(0)
+{
+}
+
+void QWebEngineCookieStorePrivate::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 QWebEngineCookieStorePrivate::rejectPendingUserCookies()
+{
+ m_getAllCookiesPending = false;
+ m_deleteAllCookiesPending = false;
+ m_deleteSessionCookiesPending = false;
+ m_pendingUserCookies.clear();
+}
+
+void QWebEngineCookieStorePrivate::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 QWebEngineCookieStorePrivate::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 QWebEngineCookieStorePrivate::deleteSessionCookies()
+{
+ if (!delegate || !delegate->hasCookieMonster()) {
+ m_deleteSessionCookiesPending = true;
+ return;
+ }
+
+ delegate->deleteSessionCookies(CallbackDirectory::DeleteSessionCookiesCallbackId);
+}
+
+void QWebEngineCookieStorePrivate::deleteAllCookies()
+{
+ if (!delegate || !delegate->hasCookieMonster()) {
+ m_deleteAllCookiesPending = true;
+ m_deleteSessionCookiesPending = false;
+ return;
+ }
+
+ delegate->deleteAllCookies(CallbackDirectory::DeleteAllCookiesCallbackId);
+}
+
+void QWebEngineCookieStorePrivate::getAllCookies()
+{
+ if (!delegate || !delegate->hasCookieMonster()) {
+ m_getAllCookiesPending = true;
+ return;
+ }
+
+ delegate->getAllCookies(CallbackDirectory::GetAllCookiesCallbackId);
+}
+
+void QWebEngineCookieStorePrivate::onGetAllCallbackResult(qint64 callbackId, const QByteArray &cookieList)
+{
+ callbackDirectory.invoke(callbackId, cookieList);
+}
+void QWebEngineCookieStorePrivate::onSetCallbackResult(qint64 callbackId, bool success)
+{
+ callbackDirectory.invoke(callbackId, success);
+}
+
+void QWebEngineCookieStorePrivate::onDeleteCallbackResult(qint64 callbackId, int numCookies)
+{
+ callbackDirectory.invoke(callbackId, numCookies);
+}
+
+void QWebEngineCookieStorePrivate::onCookieChanged(const QNetworkCookie &cookie, bool removed)
+{
+ Q_Q(QWebEngineCookieStore);
+ if (removed)
+ Q_EMIT q->cookieRemoved(cookie);
+ else
+ Q_EMIT q->cookieAdded(cookie);
+}
+
+/*!
+ \class QWebEngineCookieStore
+ \inmodule QtWebEngineCore
+ \since 5.6
+ \brief The QWebEngineCookieStore 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.
+*/
+
+/*!
+ \fn void QWebEngineCookieStore::cookieAdded(const QNetworkCookie &cookie)
+
+ This signal is emitted whenever a new \a cookie is added to the cookie store.
+*/
+
+/*!
+ \fn void QWebEngineCookieStore::cookieRemoved(const QNetworkCookie &cookie)
+
+ This signal is emitted whenever a \a cookie is deleted from the cookie store.
+*/
+
+/*!
+ Creates a new QWebEngineCookieStore object with \a parent.
+*/
+
+QWebEngineCookieStore::QWebEngineCookieStore(QObject *parent)
+ : QObject(*new QWebEngineCookieStorePrivate, parent)
+{
+
+}
+
+/*!
+ Destroys this QWebEngineCookieStore object.
+*/
+
+QWebEngineCookieStore::~QWebEngineCookieStore()
+{
+
+}
+
+/*!
+ Adds \a cookie to the cookie store.
+ 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.
+
+ \note This operation is asynchronous.
+*/
+
+void QWebEngineCookieStore::setCookie(const QNetworkCookie &cookie, const QUrl &origin)
+{
+ //TODO: use callbacks or delete dummy ones
+ Q_D(QWebEngineCookieStore);
+ d->setCookie(QWebEngineCallback<bool>(), cookie, 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.
+
+ \note This operation is asynchronous.
+*/
+
+void QWebEngineCookieStore::deleteCookie(const QNetworkCookie &cookie, const QUrl &origin)
+{
+ Q_D(QWebEngineCookieStore);
+ d->deleteCookie(cookie, origin);
+}
+
+/*!
+ Loads all the cookies into the cookie store. The cookieAdded() signal is emitted on every
+ loaded cookie. Cookies are loaded automatically when the store gets initialized, which
+ in most cases happens on loading the first URL. However, calling this function is useful
+ if cookies should be listed before entering the web content.
+
+ \note This operation is asynchronous.
+*/
+
+void QWebEngineCookieStore::loadAllCookies()
+{
+ //TODO: use callbacks or delete dummy ones
+ Q_D(QWebEngineCookieStore);
+ if (d->m_getAllCookiesPending)
+ return;
+ d->callbackDirectory.registerCallback(CallbackDirectory::GetAllCookiesCallbackId, QWebEngineCallback<const QByteArray&>());
+ //this will trigger cookieAdded signal
+ d->getAllCookies();
+}
+
+/*!
+ Deletes all the session cookies in the cookie store. Session cookies do not have an
+ expiration date assigned to them.
+
+ \note This operation is asynchronous.
+ \sa loadAllCookies()
+*/
+
+void QWebEngineCookieStore::deleteSessionCookies()
+{
+ //TODO: use callbacks or delete dummy ones
+ Q_D(QWebEngineCookieStore);
+ if (d->m_deleteAllCookiesPending || d->m_deleteSessionCookiesPending)
+ return;
+ d->callbackDirectory.registerCallback(CallbackDirectory::DeleteSessionCookiesCallbackId, QWebEngineCallback<int>());
+ d->deleteSessionCookies();
+}
+
+/*!
+ Deletes all the cookies in the cookie store.
+ \note This operation is asynchronous.
+ \sa loadAllCookies()
+*/
+
+void QWebEngineCookieStore::deleteAllCookies()
+{
+ //TODO: use callbacks or delete dummy ones
+ Q_D(QWebEngineCookieStore);
+ if (d->m_deleteAllCookiesPending)
+ return;
+ d->callbackDirectory.registerCallback(CallbackDirectory::DeleteAllCookiesCallbackId, QWebEngineCallback<int>());
+ d->deleteAllCookies();
+}
+
+QT_END_NAMESPACE
diff --git a/src/core/api/qwebenginecookiestore.h b/src/core/api/qwebenginecookiestore.h
new file mode 100644
index 000000000..b1d625385
--- /dev/null
+++ b/src/core/api/qwebenginecookiestore.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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 QWEBENGINECOOKIESTORE_H
+#define QWEBENGINECOOKIESTORE_H
+
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtWebEngineCore/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 QWebEngineCookieStorePrivate;
+class QWEBENGINE_EXPORT QWebEngineCookieStore : public QObject {
+ Q_OBJECT
+
+public:
+ virtual ~QWebEngineCookieStore();
+
+ void setCookie(const QNetworkCookie &cookie, const QUrl &origin = QUrl());
+ void deleteCookie(const QNetworkCookie &cookie, const QUrl &origin = QUrl());
+ void deleteSessionCookies();
+ void deleteAllCookies();
+ void loadAllCookies();
+
+Q_SIGNALS:
+ void cookieAdded(const QNetworkCookie &cookie);
+ void cookieRemoved(const QNetworkCookie &cookie);
+
+private:
+ explicit QWebEngineCookieStore(QObject *parent = 0);
+ friend class QtWebEngineCore::BrowserContextAdapter;
+ friend class QtWebEngineCore::CookieMonsterDelegateQt;
+ Q_DISABLE_COPY(QWebEngineCookieStore)
+ Q_DECLARE_PRIVATE(QWebEngineCookieStore)
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QWebEngineCookieStore*)
+
+#endif // QWEBENGINECOOKIESTORE_H
diff --git a/src/webengine/api/qquickwebengineprofile_p_p.h b/src/core/api/qwebenginecookiestore_p.h
index 4df5f1934..41456cfdc 100644
--- a/src/webengine/api/qquickwebengineprofile_p_p.h
+++ b/src/core/api/qwebenginecookiestore_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QQUICKWEBENGINEPROFILE_P_P_H
-#define QQUICKWEBENGINEPROFILE_P_P_H
+#ifndef QWEBENGINECOOKIESTORE_P_H
+#define QWEBENGINECOOKIESTORE_P_H
//
// W A R N I N G
@@ -48,41 +48,59 @@
// We mean it.
//
-#include "browser_context_adapter_client.h"
-#include "qquickwebengineprofile_p.h"
+#include "qtwebenginecoreglobal_p.h"
-#include <QExplicitlySharedDataPointer>
-#include <QMap>
-#include <QPointer>
+#include "qwebenginecallback_p.h"
+#include "qwebenginecookiestore.h"
-QT_BEGIN_NAMESPACE
+#include <QVector>
+#include <QNetworkCookie>
+#include <QUrl>
+#include <QtCore/private/qobject_p.h>
+
+namespace QtWebEngineCore {
+class CookieMonsterDelegateQt;
+}
-class QQuickWebEngineDownloadItem;
-class QQuickWebEngineSettings;
+QT_BEGIN_NAMESPACE
-class QQuickWebEngineProfilePrivate : public QtWebEngineCore::BrowserContextAdapterClient {
+class QWEBENGINE_PRIVATE_EXPORT QWebEngineCookieStorePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QWebEngineCookieStore)
+ struct CookieData {
+ quint64 callbackId;
+ QNetworkCookie cookie;
+ QUrl origin;
+ };
+ friend class QTypeInfo<CookieData>;
public:
- Q_DECLARE_PUBLIC(QQuickWebEngineProfile)
- QQuickWebEngineProfilePrivate(QtWebEngineCore::BrowserContextAdapter* browserContext);
- ~QQuickWebEngineProfilePrivate();
+ QtWebEngineCore::CallbackDirectory callbackDirectory;
+ QVector<CookieData> m_pendingUserCookies;
+ quint64 m_nextCallbackId;
+ bool m_deleteSessionCookiesPending;
+ bool m_deleteAllCookiesPending;
+ bool m_getAllCookiesPending;
- QtWebEngineCore::BrowserContextAdapter *browserContext() const { return m_browserContextRef.data(); }
- QQuickWebEngineSettings *settings() const { return m_settings.data(); }
+ QtWebEngineCore::CookieMonsterDelegateQt *delegate;
- void cancelDownload(quint32 downloadId);
- void downloadDestroyed(quint32 downloadId);
+ QWebEngineCookieStorePrivate();
- void downloadRequested(DownloadItemInfo &info) Q_DECL_OVERRIDE;
- void downloadUpdated(const DownloadItemInfo &info) Q_DECL_OVERRIDE;
+ void processPendingUserCookies();
+ void rejectPendingUserCookies();
+ 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();
-private:
- friend class QQuickWebEngineViewPrivate;
- QQuickWebEngineProfile *q_ptr;
- QScopedPointer<QQuickWebEngineSettings> m_settings;
- QExplicitlySharedDataPointer<QtWebEngineCore::BrowserContextAdapter> m_browserContextRef;
- QMap<quint32, QPointer<QQuickWebEngineDownloadItem> > m_ongoingDownloads;
+ 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);
};
+Q_DECLARE_TYPEINFO(QWebEngineCookieStorePrivate::CookieData, Q_MOVABLE_TYPE);
+
QT_END_NAMESPACE
-#endif // QQUICKWEBENGINEPROFILE_P_P_H
+#endif // QWEBENGINECOOKIESTORE_P_H
diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
new file mode 100644
index 000000000..e53d9afb6
--- /dev/null
+++ b/src/core/api/qwebengineurlrequestinfo.cpp
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** 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 void 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.
+
+ \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)
+ , changed(false)
+{
+}
+
+/*!
+ \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;
+}
+
+/*!
+ \internal
+*/
+bool QWebEngineUrlRequestInfo::changed() const
+{
+ Q_D(const QWebEngineUrlRequestInfo);
+ return d->changed;
+}
+
+/*!
+ 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->changed = true;
+ 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->changed = true;
+ d->shouldBlockRequest = shouldBlock;
+}
+
+/*!
+ Sets the request header \a name to \a value for this request.
+*/
+
+void QWebEngineUrlRequestInfo::setHttpHeader(const QByteArray &name, const QByteArray &value)
+{
+ Q_D(QWebEngineUrlRequestInfo);
+ d->changed = true;
+ 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..9a13b3faf
--- /dev/null
+++ b/src/core/api/qwebengineurlrequestinfo.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** 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 <QtWebEngineCore/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;
+ bool changed() const;
+
+ void block(bool shouldBlock);
+ void redirect(const QUrl &url);
+ void setHttpHeader(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/webenginewidgets/api/qwebengineurlschemehandler_p_p.h b/src/core/api/qwebengineurlrequestinfo_p.h
index d349d7d8c..c78a93613 100644
--- a/src/webenginewidgets/api/qwebengineurlschemehandler_p_p.h
+++ b/src/core/api/qwebengineurlrequestinfo_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QWEBENGINEURLSCHEMEHANDLER_P_H
-#define QWEBENGINEURLSCHEMEHANDLER_P_H
+#ifndef QWEBENGINEURLREQUESTINFO_P_H
+#define QWEBENGINEURLREQUESTINFO_P_H
//
// W A R N I N G
@@ -48,32 +48,43 @@
// We mean it.
//
-#include "qwebengineurlschemehandler_p.h"
+#include "qtwebenginecoreglobal_p.h"
-#include "custom_url_scheme_handler.h"
+#include "qwebengineurlrequestinfo.h"
-#include <QPointer>
+#include <QByteArray>
+#include <QHash>
+#include <QUrl>
-QT_BEGIN_NAMESPACE
+namespace net {
+class URLRequest;
+}
-class QWebEngineProfile;
-class QWebEngineUrlRequestJob;
-class QWebEngineUrlSchemeHandler;
+QT_BEGIN_NAMESPACE
-class QWebEngineUrlSchemeHandlerPrivate : public QtWebEngineCore::CustomUrlSchemeHandler {
+class QWebEngineUrlRequestInfoPrivate
+{
+ Q_DECLARE_PUBLIC(QWebEngineUrlRequestInfo)
public:
- Q_DECLARE_PUBLIC(QWebEngineUrlSchemeHandler)
+ QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRequestInfo::ResourceType resource
+ , QWebEngineUrlRequestInfo::NavigationType navigation
+ , const QUrl &u
+ , const QUrl &fpu
+ , const QByteArray &m);
- QWebEngineUrlSchemeHandlerPrivate(const QByteArray &, QWebEngineUrlSchemeHandler *, QWebEngineProfile *);
- virtual ~QWebEngineUrlSchemeHandlerPrivate();
+ QWebEngineUrlRequestInfo::ResourceType resourceType;
+ QWebEngineUrlRequestInfo::NavigationType navigationType;
+ bool shouldBlockRequest;
- virtual bool handleJob(QtWebEngineCore::URLRequestCustomJobDelegate*) Q_DECL_OVERRIDE;
+ QUrl url;
+ QUrl firstPartyUrl;
+ const QByteArray method;
+ bool changed;
+ QHash<QByteArray, QByteArray> extraHeaders;
-private:
- QWebEngineUrlSchemeHandler *q_ptr;
- QPointer<QWebEngineProfile> m_profile;
+ QWebEngineUrlRequestInfo *q_ptr;
};
QT_END_NAMESPACE
-#endif // QWEBENGINEURLSCHEMEHANDLER_P_H
+#endif // QWEBENGINEURLREQUESTINFO_P_H
diff --git a/src/core/api/qwebengineurlrequestinterceptor.h b/src/core/api/qwebengineurlrequestinterceptor.h
new file mode 100644
index 000000000..a3b7cf979
--- /dev/null
+++ b/src/core/api/qwebengineurlrequestinterceptor.h
@@ -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$
+**
+****************************************************************************/
+
+#ifndef QWEBENINGEURLREQUESTINTERCEPTOR_H
+#define QWEBENINGEURLREQUESTINTERCEPTOR_H
+
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtWebEngineCore/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 void 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..922299fd9 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 <QtWebEngineCore/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/webenginewidgets/api/qwebengineurlschemehandler_p.h b/src/core/api/qwebengineurlschemehandler.cpp
index 7de87dff2..485db0b4b 100644
--- a/src/webenginewidgets/api/qwebengineurlschemehandler_p.h
+++ b/src/core/api/qwebengineurlschemehandler.cpp
@@ -34,50 +34,52 @@
**
****************************************************************************/
-#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 "qtwebenginewidgetsglobal.h"
-
-#include <QtCore/QByteArray>
-#include <QtCore/QIODevice>
-#include <QtCore/QObject>
-#include <QtCore/QScopedPointer>
-#include <QtCore/QUrl>
+#include "qwebengineurlschemehandler.h"
+
+#include "qwebengineurlrequestjob.h"
QT_BEGIN_NAMESPACE
-class QWebEngineProfile;
-class QWebEngineUrlRequestJob;
-class QWebEngineUrlSchemeHandlerPrivate;
+/*!
+ \class QWebEngineUrlSchemeHandler
+ \brief The QWebEngineUrlSchemeHandler is a base class for handling custom URL schemes.
+ \since 5.6
-class QWEBENGINEWIDGETS_EXPORT QWebEngineUrlSchemeHandler : public QObject {
- Q_OBJECT
-public:
- QWebEngineUrlSchemeHandler(const QByteArray &scheme, QWebEngineProfile *profile, QObject *parent = 0);
- virtual ~QWebEngineUrlSchemeHandler();
+ To implement a custom URL scheme for QtWebEngine, you must write a class derived from this class,
+ and reimplement requestStarted().
- QByteArray scheme() const;
+ \inmodule QtWebEngineCore
- virtual void requestStarted(QWebEngineUrlRequestJob*) = 0;
+*/
-private:
- Q_DECLARE_PRIVATE(QWebEngineUrlSchemeHandler)
- friend class QWebEngineProfilePrivate;
- QScopedPointer<QWebEngineUrlSchemeHandlerPrivate> d_ptr;
-};
+/*!
+ Constructs a new URL scheme handler.
-QT_END_NAMESPACE
+ 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 _q_destroyedUrlSchemeHandler(this);
+}
+
+/*!
+ \fn void QWebEngineUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *request)
-#endif // QWEBENGINEURLSCHEMEHANDLER_H
+ 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/core/custom_url_scheme_handler.h b/src/core/api/qwebengineurlschemehandler.h
index 745f0eb4c..d9fc15250 100644
--- a/src/core/custom_url_scheme_handler.h
+++ b/src/core/api/qwebengineurlschemehandler.h
@@ -34,38 +34,38 @@
**
****************************************************************************/
-#ifndef CUSTOM_URL_SCHEME_HANDLER_H_
-#define CUSTOM_URL_SCHEME_HANDLER_H_
+#ifndef QWEBENGINEURLSCHEMEHANDLER_H
+#define QWEBENGINEURLSCHEMEHANDLER_H
-#include "qtwebenginecoreglobal.h"
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
-#include <QtCore/QByteArray>
-#include <QtCore/QScopedPointer>
-
-QT_FORWARD_DECLARE_CLASS(QIODevice)
+#include <QtCore/qobject.h>
namespace QtWebEngineCore {
+class URLRequestContextGetterQt;
+}
+
+QT_BEGIN_NAMESPACE
-class BrowserContextAdapter;
-class CustomProtocolHandler;
-class URLRequestCustomJobDelegate;
+class QWebEngineUrlRequestJob;
-class QWEBENGINE_EXPORT CustomUrlSchemeHandler {
+class QWEBENGINE_EXPORT QWebEngineUrlSchemeHandler : public QObject {
+ Q_OBJECT
public:
- explicit CustomUrlSchemeHandler(const QByteArray &);
- ~CustomUrlSchemeHandler();
+ QWebEngineUrlSchemeHandler(QObject *parent = 0);
+ ~QWebEngineUrlSchemeHandler();
- QByteArray scheme() const;
- void setScheme(const QByteArray &);
- CustomProtocolHandler *createProtocolHandler();
+ virtual void requestStarted(QWebEngineUrlRequestJob*) = 0;
- virtual bool handleJob(URLRequestCustomJobDelegate*) = 0;
+#ifndef Q_QDOC
+Q_SIGNALS:
+ void _q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*);
+#endif
private:
- QByteArray m_scheme;
+ Q_DISABLE_COPY(QWebEngineUrlSchemeHandler)
};
+QT_END_NAMESPACE
-} // namespace
-
-#endif // CUSTOM_URL_SCHEME_HANDLER_H_
+#endif // QWEBENGINEURLSCHEMEHANDLER_H
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..52674e8bd 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"
@@ -51,7 +52,6 @@
#include <QCoreApplication>
#include <QDir>
#include <QString>
-#include <QStringBuilder>
#include <QStandardPaths>
namespace {
@@ -133,6 +133,23 @@ DownloadManagerDelegateQt *BrowserContextAdapter::downloadManagerDelegate()
return m_downloadManagerDelegate.data();
}
+QWebEngineCookieStore *BrowserContextAdapter::cookieStore()
+{
+ if (!m_cookieStore)
+ m_cookieStore.reset(new QWebEngineCookieStore);
+ return m_cookieStore.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 +247,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 +346,7 @@ void BrowserContextAdapter::setHttpCacheMaxSize(int maxSize)
m_browserContext->url_request_getter_->updateHttpCache();
}
-QVector<CustomUrlSchemeHandler*> &BrowserContextAdapter::customUrlSchemeHandlers()
+QHash<QByteArray, QWebEngineUrlSchemeHandler *> &BrowserContextAdapter::customUrlSchemeHandlers()
{
return m_customUrlSchemeHandlers;
}
@@ -337,7 +354,38 @@ QVector<CustomUrlSchemeHandler*> &BrowserContextAdapter::customUrlSchemeHandlers
void BrowserContextAdapter::updateCustomUrlSchemeHandlers()
{
if (m_browserContext->url_request_getter_.get())
- m_browserContext->url_request_getter_->updateStorageSettings();
+ m_browserContext->url_request_getter_->updateJobFactory();
+}
+
+bool BrowserContextAdapter::removeCustomUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
+{
+ bool removedOneOrMore = false;
+ auto it = m_customUrlSchemeHandlers.begin();
+ while (it != m_customUrlSchemeHandlers.end()) {
+ if (it.value() == handler) {
+ it = m_customUrlSchemeHandlers.erase(it);
+ removedOneOrMore = true;
+ continue;
+ }
+ ++it;
+ }
+ 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()
@@ -347,4 +395,31 @@ 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(','));
+ QString out;
+ Q_FOREACH (const QString& str, list) {
+ if (!out.isEmpty())
+ out.append(QLatin1Char(','));
+ out.append(str.split(QLatin1Char(';')).first());
+ }
+ return out;
+}
+
+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..97a4dca4a 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/qwebenginecookiestore.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();
+ QWebEngineCookieStore *cookieStore();
+
+ 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<QWebEngineCookieStore> m_cookieStore;
+ 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_adapter_client.h b/src/core/browser_context_adapter_client.h
index 4a57b75c4..efa889e75 100644
--- a/src/core/browser_context_adapter_client.h
+++ b/src/core/browser_context_adapter_client.h
@@ -64,6 +64,7 @@ public:
const int state;
const qint64 totalBytes;
const qint64 receivedBytes;
+ const QString mimeType;
QString path;
bool accepted;
diff --git a/src/core/browser_context_qt.cpp b/src/core/browser_context_qt.cpp
index 7f285b1e5..d21f963a9 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,9 +135,21 @@ content::SSLHostStateDelegate* BrowserContextQt::GetSSLHostStateDelegate()
return 0;
}
-net::URLRequestContextGetter *BrowserContextQt::CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers)
+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, content::URLRequestInterceptorScopedVector request_interceptors)
{
- url_request_getter_ = new URLRequestContextGetterQt(m_adapter, protocol_handlers);
+ url_request_getter_ = new URLRequestContextGetterQt(m_adapter, protocol_handlers, request_interceptors.Pass());
return url_request_getter_.get();
}
diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h
index af36b55ab..9deb42b56 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
@@ -71,14 +72,18 @@ public:
virtual storage::SpecialStoragePolicy *GetSpecialStoragePolicy() Q_DECL_OVERRIDE;
virtual content::PushMessagingService* GetPushMessagingService() Q_DECL_OVERRIDE;
virtual content::SSLHostStateDelegate* GetSSLHostStateDelegate() Q_DECL_OVERRIDE;
- net::URLRequestContextGetter *CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers);
+ net::URLRequestContextGetter *CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors);
+ 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..de49d8826 100644
--- a/src/core/chrome_qt.gyp
+++ b/src/core/chrome_qt.gyp
@@ -16,11 +16,13 @@
'<(SHARED_INTERMEDIATE_DIR)/chrome', # Needed to include grit-generated files in localized_error.cc
],
'sources': [
- '<(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/localized_error.cc',
- '<(chromium_src_dir)/chrome/common/localized_error.h',
+ '<(DEPTH)/chrome/browser/media/desktop_streams_registry.cc',
+ '<(DEPTH)/chrome/browser/media/desktop_streams_registry.h',
+ '<(DEPTH)/chrome/browser/media/desktop_media_list.h',
+ '<(DEPTH)/chrome/common/chrome_switches.cc',
+ '<(DEPTH)/chrome/common/chrome_switches.h',
+ '<(DEPTH)/chrome/common/localized_error.cc',
+ '<(DEPTH)/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..ae36a0d7f 100644
--- a/src/core/common/qt_messages.h
+++ b/src/core/common/qt_messages.h
@@ -25,12 +25,15 @@ IPC_STRUCT_TRAITS_END()
// RenderView messages
// These are messages sent from the browser to the renderer process.
-IPC_MESSAGE_ROUTED1(QtRenderViewObserver_FetchDocumentMarkup,
+IPC_MESSAGE_ROUTED1(RenderViewObserverQt_FetchDocumentMarkup,
uint64 /* requestId */)
-IPC_MESSAGE_ROUTED1(QtRenderViewObserver_FetchDocumentInnerText,
+IPC_MESSAGE_ROUTED1(RenderViewObserverQt_FetchDocumentInnerText,
uint64 /* requestId */)
+IPC_MESSAGE_ROUTED1(RenderViewObserverQt_SetBackgroundColor,
+ uint32 /* color */)
+
IPC_MESSAGE_ROUTED1(WebChannelIPCTransport_Message, std::vector<char> /*binaryJSON*/)
// User scripts messages
@@ -48,14 +51,14 @@ IPC_MESSAGE_CONTROL0(UserScriptController_ClearScripts)
// WebContents messages
// These are messages sent from the renderer back to the browser process.
-IPC_MESSAGE_ROUTED2(QtRenderViewObserverHost_DidFetchDocumentMarkup,
+IPC_MESSAGE_ROUTED2(RenderViewObserverHostQt_DidFetchDocumentMarkup,
uint64 /* requestId */,
base::string16 /* markup */)
-IPC_MESSAGE_ROUTED2(QtRenderViewObserverHost_DidFetchDocumentInnerText,
+IPC_MESSAGE_ROUTED2(RenderViewObserverHostQt_DidFetchDocumentInnerText,
uint64 /* requestId */,
base::string16 /* innerText */)
-IPC_MESSAGE_ROUTED0(QtRenderViewObserverHost_DidFirstVisuallyNonEmptyLayout)
+IPC_MESSAGE_ROUTED0(RenderViewObserverHostQt_DidFirstVisuallyNonEmptyLayout)
IPC_MESSAGE_ROUTED1(WebChannelIPCTransportHost_SendMessage, std::vector<char> /*binaryJSON*/)
diff --git a/src/core/common/user_script_data.h b/src/core/common/user_script_data.h
index 3dfec0ec3..d0856e02a 100644
--- a/src/core/common/user_script_data.h
+++ b/src/core/common/user_script_data.h
@@ -60,4 +60,10 @@ struct UserScriptData {
uint64 scriptId;
};
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_TYPEINFO(UserScriptData, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
#endif // USER_SCRIPT_DATA_H
diff --git a/src/core/config/desktop_linux.pri b/src/core/config/desktop_linux.pri
index 7f27659e3..f0bf6cb23 100644
--- a/src/core/config/desktop_linux.pri
+++ b/src/core/config/desktop_linux.pri
@@ -1,23 +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
-
-!contains(QT_CONFIG, pulseaudio): GYP_CONFIG += use_pulseaudio=0
+ enable_plugins=1 \
-!contains(QT_CONFIG, system-harfbuzz): GYP_CONFIG += use_system_harfbuzz=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 8d9a848e8..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 \
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
-!contains(QT_CONFIG, system-harfbuzz): GYP_CONFIG += use_system_harfbuzz=0
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
new file mode 100644
index 000000000..9868d6848
--- /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
+!contains(QT_CONFIG, glib): GYP_CONFIG += use_glib=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..1e875f308 100644
--- a/src/core/config/windows.pri
+++ b/src/core/config/windows.pri
@@ -28,3 +28,46 @@ contains(QT_CONFIG, angle) {
GYP_ARGS += "-D qt_gl=\"opengl\""
}
+defineTest(usingMSVC32BitCrossCompiler) {
+ CL_DIR =
+ for(dir, QMAKE_PATH_ENV) {
+ exists($$dir/cl.exe) {
+ CL_DIR = $$dir
+ break()
+ }
+ }
+ isEmpty(CL_DIR): {
+ warning(Cannot determine location of cl.exe.)
+ return(false)
+ }
+ CL_DIR = $$system_path($$CL_DIR)
+ CL_DIR = $$split(CL_DIR, \\)
+ CL_PLATFORM = $$last(CL_DIR)
+ equals(CL_PLATFORM, amd64_x86): return(true)
+ return(false)
+}
+
+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"
+
+ # The check below is ugly, but necessary, as it seems to be the only reliable way to detect if the host
+ # architecture is 32 bit. QMAKE_HOST.arch does not work as it returns the architecture that the toolchain
+ # is building for, not the system's actual architecture.
+ PROGRAM_FILES_X86 = $$(ProgramW6432)
+ isEmpty(PROGRAM_FILES_X86): GYP_ARGS += "-D windows_sdk_path=\"C:/Program Files/Windows Kits/8.1\""
+
+ contains(QT_ARCH, "i386"):!usingMSVC32BitCrossCompiler() {
+ # The 32 bit MSVC linker runs out of memory if we do not remove all debug information.
+ GYP_CONFIG += fastbuild=2
+ }
+} 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..078874da1 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);
}
@@ -374,7 +384,7 @@ content::AccessTokenStore *ContentBrowserClientQt::CreateAccessTokenStore()
net::URLRequestContextGetter* ContentBrowserClientQt::CreateRequestContext(content::BrowserContext* browser_context, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors)
{
- return static_cast<BrowserContextQt*>(browser_context)->CreateRequestContext(protocol_handlers);
+ return static_cast<BrowserContextQt*>(browser_context)->CreateRequestContext(protocol_handlers, request_interceptors.Pass());
}
content::QuotaPermissionContext *ContentBrowserClientQt::CreateQuotaPermissionContext()
@@ -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..3e5b96b41 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -36,14 +36,123 @@
#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>
+
+#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)
+ QString winDir = QDir::fromNativeSeparators(qgetenv("WINDIR"));
+ if (winDir.isEmpty())
+ winDir = QString::fromLatin1("C:/Windows");
+ QDir pluginDir(winDir + "/System32/Macromed/Flash");
+ pluginDir.setFilter(QDir::Files);
+ Q_FOREACH (const QFileInfo &info, pluginDir.entryInfoList(QStringList("pepflashplayer*.dll")))
+ pluginPaths << info.absoluteFilePath();
+#endif
+#if defined(Q_OS_OSX)
+ pluginPaths << "/Library/Internet Plug-Ins/PepperFlashPlayer/PepperFlashPlayer.plugin"; // Mac OS X
+#endif
+#if defined(Q_OS_LINUX)
+ pluginPaths << "/opt/google/chrome/PepperFlash/libpepflashplayer.so" // Google Chrome
+ << "/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::exists(*it))
+ continue;
+ plugins->push_back(CreatePepperFlashInfo(QtWebEngineCore::toFilePath(*it), std::string()));
+ }
+}
+
+void AddPepperFlashFromCommandLine(std::vector<content::PepperPluginInfo>* plugins)
+{
+ const base::CommandLine::StringType flash_path = base::CommandLine::ForCurrentProcess()->GetSwitchValueNative(switches::kPpapiFlashPath);
+ if (flash_path.empty() || !QFile::exists(QtWebEngineCore::toQt(flash_path)))
+ 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>
namespace QtWebEngineCore {
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..493743385
--- /dev/null
+++ b/src/core/cookie_monster_delegate_qt.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** 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/qwebenginecookiestore.h"
+#include "api/qwebenginecookiestore_p.h"
+#include "type_conversion.h"
+
+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(QWebEngineCookieStorePrivate *client, qint64 callbackId, bool success) {
+ client->onSetCallbackResult(callbackId, success);
+}
+
+static void onDeleteCookiesCallback(QWebEngineCookieStorePrivate *client, qint64 callbackId, int numCookies) {
+ client->onDeleteCallbackResult(callbackId, numCookies);
+}
+
+static void onGetAllCookiesCallback(QWebEngineCookieStorePrivate *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)
+{
+ if (!monster && !m_cookieMonster)
+ return;
+
+ m_cookieMonster = monster;
+
+ if (!m_client)
+ return;
+
+ if (monster)
+ m_client->d_func()->processPendingUserCookies();
+ else
+ m_client->d_func()->rejectPendingUserCookies();
+}
+
+void CookieMonsterDelegateQt::setClient(QWebEngineCookieStore *client)
+{
+ m_client = client;
+
+ if (!m_client)
+ return;
+
+ m_client->d_func()->delegate = this;
+
+ if (hasCookieMonster())
+ m_client->d_func()->processPendingUserCookies();
+}
+
+bool CookieMonsterDelegateQt::canSetCookie(const QUrl &firstPartyUrl, const QByteArray &cookieLine, const QUrl &url)
+{
+ // TODO: should be used for FilterRequest implementation
+ return true;
+}
+
+void CookieMonsterDelegateQt::OnCookieChanged(const net::CanonicalCookie& cookie, bool removed, ChangeCause cause)
+{
+ if (!m_client)
+ return;
+ m_client->d_func()->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..c9f27c2bc
--- /dev/null
+++ b/src/core/cookie_monster_delegate_qt.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** 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 <QNetworkCookie>
+#include <QPointer>
+
+QT_FORWARD_DECLARE_CLASS(QWebEngineCookieStore)
+
+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<QWebEngineCookieStore> 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(QWebEngineCookieStore *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..09eee496f 100644
--- a/src/core/core.pro
+++ b/src/core/core.pro
@@ -1,20 +1,26 @@
TEMPLATE = subdirs
+# core_headers is a dummy module to syncqt the headers so we can
+# use them by later targets
+core_headers.file = core_headers.pro
+
# core_gyp_generator.pro is a dummy .pro file that is used by qmake
# to generate our main .gyp file
core_gyp_generator.file = core_gyp_generator.pro
+core_gyp_generator.depends = core_headers
# gyp_run.pro calls gyp through gyp_qtwebengine on the qmake step, and ninja on the make step.
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 +34,8 @@ SUBDIRS += core_gyp_generator \
gyp_run.depends += gyp_configure_host gyp_configure_target
SUBDIRS += gyp_configure_host gyp_configure_target
}
+
+SUBDIRS += gyp_run \
+ core_headers \
+ core_api \
+ core_module
diff --git a/src/core/core_common.pri b/src/core/core_common.pri
index cefde4302..9c29aea71 100644
--- a/src/core/core_common.pri
+++ b/src/core/core_common.pri
@@ -3,10 +3,10 @@
TARGET = QtWebEngineCore
QT += qml quick webchannel
-QT_PRIVATE += quick-private gui-private core-private
+QT_PRIVATE += quick-private gui-private core-private webenginecoreheaders-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..0685abd7e 100644
--- a/src/core/core_gyp_generator.pro
+++ b/src/core/core_gyp_generator.pro
@@ -11,6 +11,7 @@ include(core_common.pri)
# Defining keywords such as 'signal' clashes with the chromium code base.
DEFINES += QT_NO_KEYWORDS \
+ QT_USE_QSTRINGBUILDER \
Q_FORWARD_DECLARE_OBJC_CLASS=QT_FORWARD_DECLARE_CLASS \
QTWEBENGINEPROCESS_NAME=\\\"$$QTWEBENGINEPROCESS_NAME\\\" \
QTWEBENGINECORE_VERSION_STR=\\\"$$MODULE_VERSION\\\" \
@@ -18,17 +19,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 +44,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,12 +59,19 @@ 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_view_observer_host_qt.cpp \
render_widget_host_view_qt.cpp \
renderer/content_renderer_client_qt.cpp \
- renderer/qt_render_view_observer.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/render_frame_observer_qt.cpp \
+ renderer/render_view_observer_qt.cpp \
renderer/user_script_controller.cpp \
renderer/web_channel_ipc_transport.cpp \
resource_bundle_qt.cpp \
@@ -89,6 +99,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 +115,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,14 +131,20 @@ 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_view_observer_host_qt.h \
render_widget_host_view_qt.h \
render_widget_host_view_qt_delegate.h \
renderer/content_renderer_client_qt.h \
- renderer/qt_render_view_observer.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/render_frame_observer_qt.h \
+ renderer/render_view_observer_qt.h \
renderer/user_script_controller.h \
renderer/web_channel_ipc_transport.h \
resource_context_qt.h \
diff --git a/src/core/core_headers.pro b/src/core/core_headers.pro
new file mode 100644
index 000000000..ebafe58ec
--- /dev/null
+++ b/src/core/core_headers.pro
@@ -0,0 +1,5 @@
+TARGET = QtWebEngineCore
+CONFIG += no_private_module header_module internal_module
+MODULE = webenginecoreheaders
+
+load(qt_module)
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index e6a36332f..5300fdbbc 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,40 +62,37 @@ 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
resources.CONFIG += no_check_exist
- resources.path = $$[QT_INSTALL_DATA]
+ resources.path = $$[QT_INSTALL_DATA]/resources
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
+ icu.path = $$[QT_INSTALL_DATA]/resources
+ INSTALLS += icu locales resources
}
!contains(QT_CONFIG, qt_framework): contains(QT_CONFIG, private_tests) {
- ICU_TARGET = $$shell_path($$[QT_INSTALL_DATA/get]/icudtl.dat)
- ICU_FILE = $$shell_path($$OUT_PWD/$$getConfigDir()/icudtl.dat)
- icu_rule.target = $$ICU_TARGET
- 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
+ #
+ # Copy essential files to the qtbase build directory (for non-installed developer builds)
+ #
+
+ icudt2build.input = icu.files
+ icudt2build.output = $$[QT_INSTALL_DATA/get]/resources/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
+ icudt2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
+ icudt2build.name = COPY ${QMAKE_FILE_IN}
+ icudt2build.CONFIG = no_link no_clean target_predeps
+
+ resources2build.input = resources.files
+ resources2build.output = $$[QT_INSTALL_DATA/get]/resources/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
+ resources2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
+ resources2build.name = COPY ${QMAKE_FILE_IN}
+ resources2build.CONFIG = no_link no_clean target_predeps
+
+ QMAKE_EXTRA_COMPILERS += icudt2build resources2build
}
}
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..07b3131ce 100644
--- a/src/core/delegated_frame_node.cpp
+++ b/src/core/delegated_frame_node.cpp
@@ -57,6 +57,7 @@
#include "cc/quads/checkerboard_draw_quad.h"
#include "cc/quads/debug_border_draw_quad.h"
#include "cc/quads/draw_quad.h"
+#include "cc/quads/io_surface_draw_quad.h"
#include "cc/quads/render_pass_draw_quad.h"
#include "cc/quads/solid_color_draw_quad.h"
#include "cc/quads/stream_video_draw_quad.h"
@@ -76,6 +77,14 @@
#include <EGL/eglext.h>
#endif
+#ifndef GL_TIMEOUT_IGNORED
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#endif
+
+#ifndef GL_TEXTURE_RECTANGLE
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#endif
+
namespace QtWebEngineCore {
class MailboxTexture : public QSGTexture, protected QOpenGLFunctions {
@@ -127,7 +136,7 @@ private:
QSGGeometry m_geometry;
};
-static inline QSharedPointer<QSGLayer> findRenderPassLayer(const cc::RenderPassId &id, const QList<QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > > &list)
+static inline QSharedPointer<QSGLayer> findRenderPassLayer(const cc::RenderPassId &id, const QVector<QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > > &list)
{
typedef QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > Pair;
Q_FOREACH (const Pair &pair, list)
@@ -161,9 +170,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 +214,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 +222,6 @@ static void waitChromiumSync(gfx::TransferableFence *sync)
Q_ASSERT(glWaitSync_);
}
glWaitSync_(sync->arb.sync, 0, GL_TIMEOUT_IGNORED);
-#endif
break;
}
}
@@ -250,7 +257,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 +266,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 +414,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 +449,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 +576,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 +624,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,36 +635,54 @@ 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
- StreamVideoNode *svideoNode = new StreamVideoNode(texture);
+ StreamVideoNode *svideoNode = new StreamVideoNode(texture, false, ExternalTarget);
svideoNode->setRect(toQt(squad->rect));
svideoNode->setTextureMatrix(toQt(squad->matrix.matrix()));
currentLayerChain->appendChildNode(svideoNode);
break;
#endif
- } default:
+ }
+ case cc::DrawQuad::IO_SURFACE_CONTENT: {
+ const cc::IOSurfaceDrawQuad *ioquad = cc::IOSurfaceDrawQuad::MaterialCast(quad);
+ ResourceHolder *resource = findAndHoldResource(ioquad->io_surface_resource_id(), resourceCandidates);
+ MailboxTexture *texture = static_cast<MailboxTexture *>(initAndHoldTexture(resource, quad->ShouldDrawWithBlending()));
+ texture->setTarget(GL_TEXTURE_RECTANGLE);
+
+ bool flip = ioquad->orientation != cc::IOSurfaceDrawQuad::FLIPPED;
+ StreamVideoNode *svideoNode = new StreamVideoNode(texture, flip, RectangleTarget);
+ QMatrix4x4 matrix;
+ matrix.scale(ioquad->io_surface_size.width(), ioquad->io_surface_size.height());
+ svideoNode->setRect(toQt(ioquad->rect));
+ svideoNode->setTextureMatrix(matrix);
+ currentLayerChain->appendChildNode(svideoNode);
+ break;
+ }
+ default:
qWarning("Unimplemented quad material: %d", quad->material);
}
}
diff --git a/src/core/delegated_frame_node.h b/src/core/delegated_frame_node.h
index 60a1535d2..eed03fadd 100644
--- a/src/core/delegated_frame_node.h
+++ b/src/core/delegated_frame_node.h
@@ -90,9 +90,9 @@ private:
QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData;
struct SGObjects {
- QList<QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > > renderPassLayers;
- QList<QSharedPointer<QSGRootNode> > renderPassRootNodes;
- QList<QSharedPointer<QSGTexture> > textureStrongRefs;
+ QVector<QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > > renderPassLayers;
+ QVector<QSharedPointer<QSGRootNode> > renderPassRootNodes;
+ QVector<QSharedPointer<QSGTexture> > textureStrongRefs;
} m_sgObjects;
int m_numPendingSyncPoints;
QMap<uint32, gfx::TransferableFence> m_mailboxGLFences;
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..d0224c834
--- /dev/null
+++ b/src/core/doc/src/qtwebenginecore-module.qdoc
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** 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{Qt WebEngine QML Types}{Qt WebEngine} or
+ \l{Qt WebEngine Widgets C++ Classes}{Qt WebEngine Widgets} modules.
+
+ To link against the module, add this line to your qmake project file:
+
+ \snippet qtwebenginecore_build_snippet.qdoc 0
+
+ However, \c webenginecore is implied by adding \c webengine or \c webenginewidgets.
+*/
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index e9af98fd8..6d29af76a 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -46,6 +46,7 @@
#include <QFile>
#include <QFileInfo>
#include <QMap>
+#include <QMimeDatabase>
#include <QStandardPaths>
#include "browser_context_adapter.h"
@@ -102,23 +103,28 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i
return true;
}
- std::string suggestedFilename = item->GetSuggestedFilename();
+ QString suggestedFilename = toQt(item->GetSuggestedFilename());
+ QString mimeTypeString = toQt(item->GetMimeType());
- if (suggestedFilename.empty())
- suggestedFilename = net::HttpContentDisposition(item->GetContentDisposition(), std::string()).filename();
+ if (suggestedFilename.isEmpty())
+ suggestedFilename = toQt(net::HttpContentDisposition(item->GetContentDisposition(), std::string()).filename());
- if (suggestedFilename.empty())
- suggestedFilename = item->GetTargetFilePath().AsUTF8Unsafe();
+ if (suggestedFilename.isEmpty())
+ suggestedFilename = toQt(item->GetTargetFilePath().AsUTF8Unsafe());
- if (suggestedFilename.empty())
- suggestedFilename = item->GetURL().ExtractFileName();
+ if (suggestedFilename.isEmpty())
+ suggestedFilename = toQt(item->GetURL().ExtractFileName());
- if (suggestedFilename.empty())
- suggestedFilename = "qwe_download";
+ if (suggestedFilename.isEmpty()) {
+ suggestedFilename = QStringLiteral("qwe_download");
+ QMimeType mimeType = QMimeDatabase().mimeTypeForName(mimeTypeString);
+ if (mimeType.isValid() && !mimeType.preferredSuffix().isEmpty())
+ suggestedFilename += QStringLiteral(".") + mimeType.preferredSuffix();
+ }
QDir defaultDownloadDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
- QFileInfo suggestedFile(defaultDownloadDirectory.absoluteFilePath(QString::fromStdString(suggestedFilename)));
+ QFileInfo suggestedFile(defaultDownloadDirectory.absoluteFilePath(suggestedFilename));
QString suggestedFilePath = suggestedFile.absoluteFilePath();
QString tmpFileBase = QString("%1%2%3").arg(suggestedFile.absolutePath()).arg(QDir::separator()).arg(suggestedFile.baseName());
@@ -139,6 +145,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i
item->GetState(),
item->GetTotalBytes(),
item->GetReceivedBytes(),
+ mimeTypeString,
suggestedFilePath,
false /* accepted */
};
@@ -191,6 +198,7 @@ void DownloadManagerDelegateQt::OnDownloadUpdated(content::DownloadItem *downloa
download->GetState(),
download->GetTotalBytes(),
download->GetReceivedBytes(),
+ toQt(download->GetMimeType()),
QString(),
true /* accepted */
};
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..dea1a2225 100644
--- a/src/core/gyp_run.pro
+++ b/src/core/gyp_run.pro
@@ -28,8 +28,7 @@ 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"
+!warnings_are_errors: GYP_CONFIG += disable_fatal_linker_warnings=1
# 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.
@@ -40,58 +39,64 @@ 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(QT_ARCH, "arm64"): GYP_CONFIG += target_arch=arm64
-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..485ea8d94 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();
@@ -74,6 +74,7 @@ private:
QGeoPositionInfoSource *m_positionInfoSource;
void postToLocationProvider(const base::Closure &task);
+ friend class LocationProviderQt;
};
QtPositioningHelper::QtPositioningHelper(LocationProviderQt *provider)
@@ -85,18 +86,44 @@ QtPositioningHelper::QtPositioningHelper(LocationProviderQt *provider)
QtPositioningHelper::~QtPositioningHelper()
{
- m_locationProvider->m_positioningHelper = 0;
+ if (m_locationProvider)
+ m_locationProvider->m_positioningHelper = 0;
}
-bool QtPositioningHelper::start(bool highAccuracy)
+static bool isHighAccuracySource(const QGeoPositionInfoSource *source)
+{
+ return source->supportedPositioningMethods().testFlag(
+ QGeoPositionInfoSource::SatellitePositioningMethods);
+}
+
+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;
+ }
+
+ // Find high accuracy source if the default source is not already one.
+ if (highAccuracy && !isHighAccuracySource(m_positionInfoSource)) {
+ Q_FOREACH (const QString &name, QGeoPositionInfoSource::availableSources()) {
+ if (name == m_positionInfoSource->sourceName())
+ continue;
+ QGeoPositionInfoSource *source = QGeoPositionInfoSource::createSource(name, this);
+ if (source && isHighAccuracySource(source)) {
+ delete m_positionInfoSource;
+ m_positionInfoSource = source;
+ break;
+ }
+ delete source;
+ }
+ m_positionInfoSource->setPreferredPositioningMethods(
+ QGeoPositionInfoSource::SatellitePositioningMethods);
+ }
connect(m_positionInfoSource, &QGeoPositionInfoSource::positionUpdated, this, &QtPositioningHelper::updatePosition);
// disambiguate the error getter and the signal in QGeoPositionInfoSource.
@@ -105,7 +132,7 @@ bool QtPositioningHelper::start(bool highAccuracy)
connect(m_positionInfoSource, &QGeoPositionInfoSource::updateTimeout, this, &QtPositioningHelper::timeout);
m_positionInfoSource->startUpdates();
- return true;
+ return;
}
void QtPositioningHelper::stop()
@@ -198,7 +225,10 @@ LocationProviderQt::LocationProviderQt()
LocationProviderQt::~LocationProviderQt()
{
- m_positioningHelper->deleteLater();
+ if (m_positioningHelper) {
+ m_positioningHelper->m_locationProvider = 0;
+ m_positioningHelper->deleteLater();
+ }
}
bool LocationProviderQt::StartProvider(bool highAccuracy)
@@ -208,7 +238,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..6fdabcd4c 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,70 @@ 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);
+ interceptor->interceptRequest(requestInfo);
+ if (requestInfo.changed()) {
+ 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 +219,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..b322e507e
--- /dev/null
+++ b/src/core/permission_manager_qt.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** 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();
+ while (it != m_requests.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();
+ while (it != m_requests.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..6dfc60c39
--- /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;
+ };
+ QVector<Request> m_requests;
+ struct Subscriber {
+ int id;
+ PermissionType type;
+ QUrl origin;
+ base::Callback<void(content::PermissionStatus)> callback;
+ };
+ int m_subscriberCount;
+ QVector<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..96b48e2ca 100644
--- a/src/core/qtwebengine.gypi
+++ b/src/core/qtwebengine.gypi
@@ -8,14 +8,19 @@
'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',
+ '<(chromium_src_dir)/components/components.gyp:web_cache_browser',
+ '<(chromium_src_dir)/components/components.gyp:web_cache_renderer',
'<(chromium_src_dir)/content/content.gyp:content',
'<(chromium_src_dir)/content/content.gyp:content_app_browser',
'<(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 +86,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/qt_render_view_observer_host.cpp b/src/core/render_view_observer_host_qt.cpp
index 97d001ed6..03c9d241f 100644
--- a/src/core/qt_render_view_observer_host.cpp
+++ b/src/core/render_view_observer_host_qt.cpp
@@ -34,7 +34,7 @@
**
****************************************************************************/
-#include "qt_render_view_observer_host.h"
+#include "render_view_observer_host_qt.h"
#include "common/qt_messages.h"
#include "content/public/browser/web_contents.h"
@@ -44,31 +44,31 @@
namespace QtWebEngineCore {
-QtRenderViewObserverHost::QtRenderViewObserverHost(content::WebContents *webContents, WebContentsAdapterClient *adapterClient)
+RenderViewObserverHostQt::RenderViewObserverHostQt(content::WebContents *webContents, WebContentsAdapterClient *adapterClient)
: content::WebContentsObserver(webContents)
, m_adapterClient(adapterClient)
{
}
-void QtRenderViewObserverHost::fetchDocumentMarkup(quint64 requestId)
+void RenderViewObserverHostQt::fetchDocumentMarkup(quint64 requestId)
{
- Send(new QtRenderViewObserver_FetchDocumentMarkup(routing_id(), requestId));
+ Send(new RenderViewObserverQt_FetchDocumentMarkup(routing_id(), requestId));
}
-void QtRenderViewObserverHost::fetchDocumentInnerText(quint64 requestId)
+void RenderViewObserverHostQt::fetchDocumentInnerText(quint64 requestId)
{
- Send(new QtRenderViewObserver_FetchDocumentInnerText(routing_id(), requestId));
+ Send(new RenderViewObserverQt_FetchDocumentInnerText(routing_id(), requestId));
}
-bool QtRenderViewObserverHost::OnMessageReceived(const IPC::Message& message)
+bool RenderViewObserverHostQt::OnMessageReceived(const IPC::Message& message)
{
bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(QtRenderViewObserverHost, message)
- IPC_MESSAGE_HANDLER(QtRenderViewObserverHost_DidFetchDocumentMarkup,
+ IPC_BEGIN_MESSAGE_MAP(RenderViewObserverHostQt, message)
+ IPC_MESSAGE_HANDLER(RenderViewObserverHostQt_DidFetchDocumentMarkup,
onDidFetchDocumentMarkup)
- IPC_MESSAGE_HANDLER(QtRenderViewObserverHost_DidFetchDocumentInnerText,
+ IPC_MESSAGE_HANDLER(RenderViewObserverHostQt_DidFetchDocumentInnerText,
onDidFetchDocumentInnerText)
- IPC_MESSAGE_HANDLER(QtRenderViewObserverHost_DidFirstVisuallyNonEmptyLayout,
+ IPC_MESSAGE_HANDLER(RenderViewObserverHostQt_DidFirstVisuallyNonEmptyLayout,
onDidFirstVisuallyNonEmptyLayout)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -76,17 +76,17 @@ bool QtRenderViewObserverHost::OnMessageReceived(const IPC::Message& message)
}
-void QtRenderViewObserverHost::onDidFetchDocumentMarkup(quint64 requestId, const base::string16& markup)
+void RenderViewObserverHostQt::onDidFetchDocumentMarkup(quint64 requestId, const base::string16& markup)
{
m_adapterClient->didFetchDocumentMarkup(requestId, toQt(markup));
}
-void QtRenderViewObserverHost::onDidFetchDocumentInnerText(quint64 requestId, const base::string16& innerText)
+void RenderViewObserverHostQt::onDidFetchDocumentInnerText(quint64 requestId, const base::string16& innerText)
{
m_adapterClient->didFetchDocumentInnerText(requestId, toQt(innerText));
}
-void QtRenderViewObserverHost::onDidFirstVisuallyNonEmptyLayout()
+void RenderViewObserverHostQt::onDidFirstVisuallyNonEmptyLayout()
{
RenderWidgetHostViewQt *rwhv = static_cast<RenderWidgetHostViewQt*>(web_contents()->GetRenderWidgetHostView());
if (rwhv)
diff --git a/src/core/qt_render_view_observer_host.h b/src/core/render_view_observer_host_qt.h
index 148fcb9da..2683e5807 100644
--- a/src/core/qt_render_view_observer_host.h
+++ b/src/core/render_view_observer_host_qt.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QT_RENDER_VIEW_OBSERVER_HOST_H
-#define QT_RENDER_VIEW_OBSERVER_HOST_H
+#ifndef RENDER_VIEW_OBSERVER_HOST_QT_H
+#define RENDER_VIEW_OBSERVER_HOST_QT_H
#include "content/public/browser/web_contents_observer.h"
@@ -49,10 +49,10 @@ namespace QtWebEngineCore {
class WebContentsAdapterClient;
-class QtRenderViewObserverHost : public content::WebContentsObserver
+class RenderViewObserverHostQt : public content::WebContentsObserver
{
public:
- QtRenderViewObserverHost(content::WebContents*, WebContentsAdapterClient *adapterClient);
+ RenderViewObserverHostQt(content::WebContents*, WebContentsAdapterClient *adapterClient);
void fetchDocumentMarkup(quint64 requestId);
void fetchDocumentInnerText(quint64 requestId);
@@ -67,4 +67,4 @@ private:
} // namespace QtWebEngineCore
-#endif // QT_RENDER_VIEW_OBSERVER_HOST_H
+#endif // RENDER_VIEW_OBSERVER_HOST_QT_H
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index e4770cc72..4a773bc19 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>
@@ -72,6 +75,7 @@
#include <QTextFormat>
#include <QKeyEvent>
#include <QMouseEvent>
+#include <QPixmap>
#include <QScreen>
#include <QStyleHints>
#include <QVariant>
@@ -142,7 +146,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 +184,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 +200,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 +239,7 @@ private:
QList<QTouchEvent::TouchPoint> touchPoints;
base::TimeTicks eventTime;
Action action;
+ const uint32 eventId;
int flags;
int index;
float dpiScale;
@@ -410,6 +417,15 @@ 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 RenderViewObserverQt_SetBackgroundColor(m_host->GetRoutingID(), color));
+}
+
// Return value indicates whether the mouse is locked successfully or not.
bool RenderWidgetHostViewQt::LockMouse()
{
@@ -428,27 +444,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;
@@ -536,7 +536,12 @@ void RenderWidgetHostViewQt::UpdateCursor(const content::WebCursor &webCursor)
shape = Qt::ClosedHandCursor;
break;
case blink::WebCursorInfo::TypeCustom:
- // FIXME: Extract from the CursorInfo.
+ if (cursorInfo.custom_image.colorType() == SkColorType::kN32_SkColorType) {
+ QImage cursor = toQImage(cursorInfo.custom_image, QImage::Format_ARGB32);
+ m_delegate->updateCursor(QCursor(QPixmap::fromImage(cursor)));
+ return;
+ }
+ // Use arrow cursor as fallback in case the Chromium implementation changes.
shape = Qt::ArrowCursor;
break;
default:
@@ -571,8 +576,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 +610,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 +698,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 +727,12 @@ void RenderWidgetHostViewQt::notifyResize()
void RenderWidgetHostViewQt::notifyShown()
{
- WasShown();
+ m_host->WasShown(ui::LatencyInfo());
}
void RenderWidgetHostViewQt::notifyHidden()
{
- WasHidden();
+ m_host->WasHidden();
}
void RenderWidgetHostViewQt::windowBoundsChanged()
@@ -814,7 +822,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()
@@ -828,16 +836,12 @@ 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);
+ bool causesScrollingIfUncancelled = true;
+ blink::WebTouchEvent touchEvent = ui::CreateWebTouchEventFromMotionEvent(motionEvent,
+ causesScrollingIfUncancelled);
m_host->ForwardTouchEventWithLatencyInfo(touchEvent, CreateLatencyInfo(touchEvent));
}
@@ -937,14 +941,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..261b9c581 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -40,18 +40,22 @@
#include "chrome/common/localized_error.h"
#include "components/error_page/common/error_page_params.h"
#include "components/visitedlink/renderer/visitedlink_slave.h"
+#include "components/web_cache/renderer/web_cache_render_process_observer.h"
#include "content/public/renderer/render_frame.h"
#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_view_observer.h"
+#include "renderer/render_frame_observer_qt.h"
+#include "renderer/render_view_observer_qt.h"
#include "renderer/user_script_controller.h"
#include "grit/renderer_resources.h"
@@ -59,6 +63,7 @@
namespace QtWebEngineCore {
static const char kHttpErrorDomain[] = "http";
+static const char kQrcSchemeQt[] = "qrc";
ContentRendererClientQt::ContentRendererClientQt()
{
@@ -73,18 +78,28 @@ void ContentRendererClientQt::RenderThreadStarted()
content::RenderThread *renderThread = content::RenderThread::Get();
renderThread->RegisterExtension(WebChannelIPCTransport::getV8Extension());
m_visitedLinkSlave.reset(new visitedlink::VisitedLinkSlave);
+ m_webCacheObserver.reset(new web_cache::WebCacheRenderProcessObserver());
renderThread->AddObserver(m_visitedLinkSlave.data());
+ renderThread->AddObserver(m_webCacheObserver.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)
{
// RenderViewObservers destroy themselves with their RenderView.
- new QtRenderViewObserver(render_view);
+ new RenderViewObserverQt(render_view, m_webCacheObserver.data());
new WebChannelIPCTransport(render_view);
UserScriptController::instance()->renderViewCreated(render_view);
}
+void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame* render_frame)
+{
+ new QtWebEngineCore::RenderFrameObserverQt(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 +120,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..eb55156ad 100644
--- a/src/core/renderer/content_renderer_client_qt.h
+++ b/src/core/renderer/content_renderer_client_qt.h
@@ -45,6 +45,10 @@ namespace visitedlink {
class VisitedLinkSlave;
}
+namespace web_cache {
+class WebCacheRenderProcessObserver;
+}
+
namespace QtWebEngineCore {
class ContentRendererClientQt : public content::ContentRendererClient {
@@ -53,7 +57,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
@@ -64,6 +68,7 @@ public:
private:
QScopedPointer<visitedlink::VisitedLinkSlave> m_visitedLinkSlave;
+ QScopedPointer<web_cache::WebCacheRenderProcessObserver> m_webCacheObserver;
};
} // namespace
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/render_frame_observer_qt.cpp b/src/core/renderer/render_frame_observer_qt.cpp
new file mode 100644
index 000000000..8130cc53a
--- /dev/null
+++ b/src/core/renderer/render_frame_observer_qt.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 "render_frame_observer_qt.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 {
+
+RenderFrameObserverQt::RenderFrameObserverQt(content::RenderFrame* render_frame)
+ : RenderFrameObserver(render_frame)
+{
+}
+
+RenderFrameObserverQt::~RenderFrameObserverQt()
+{
+}
+
+#if defined(ENABLE_PLUGINS)
+void RenderFrameObserverQt::DidCreatePepperPlugin(content::RendererPpapiHost* host)
+{
+ host->GetPpapiHost()->AddHostFactoryFilter(
+ scoped_ptr<ppapi::host::HostFactory>(
+ new PepperRendererHostFactoryQt(host)));
+}
+#endif
+
+} // namespace QtWebEngineCore
diff --git a/src/core/renderer/render_frame_observer_qt.h b/src/core/renderer/render_frame_observer_qt.h
new file mode 100644
index 000000000..4835e442e
--- /dev/null
+++ b/src/core/renderer/render_frame_observer_qt.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** 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 RENDER_FRAME_OBSERVER_QT_H
+#define RENDER_FRAME_OBSERVER_QT_H
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "content/public/renderer/render_frame_observer.h"
+
+
+namespace content {
+class RenderFrame;
+}
+
+namespace QtWebEngineCore {
+
+class RenderFrameObserverQt : public content::RenderFrameObserver {
+public:
+ explicit RenderFrameObserverQt(content::RenderFrame* render_frame);
+ ~RenderFrameObserverQt();
+
+#if defined(ENABLE_PLUGINS)
+ void DidCreatePepperPlugin(content::RendererPpapiHost* host) override;
+#endif
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(RenderFrameObserverQt);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // RENDER_FRAME_OBSERVER_QT_H
diff --git a/src/core/renderer/qt_render_view_observer.cpp b/src/core/renderer/render_view_observer_qt.cpp
index 83534dadd..47efd07e4 100644
--- a/src/core/renderer/qt_render_view_observer.cpp
+++ b/src/core/renderer/render_view_observer_qt.cpp
@@ -34,49 +34,65 @@
**
****************************************************************************/
-#include "renderer/qt_render_view_observer.h"
+#include "renderer/render_view_observer_qt.h"
#include "common/qt_messages.h"
+#include "components/web_cache/renderer/web_cache_render_process_observer.h"
#include "content/public/renderer/render_view.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebView.h"
-QtRenderViewObserver::QtRenderViewObserver(content::RenderView* render_view)
+RenderViewObserverQt::RenderViewObserverQt(
+ content::RenderView* render_view,
+ web_cache::WebCacheRenderProcessObserver* web_cache_render_process_observer)
: content::RenderViewObserver(render_view)
+ , m_web_cache_render_process_observer(web_cache_render_process_observer)
{
}
-void QtRenderViewObserver::onFetchDocumentMarkup(quint64 requestId)
+void RenderViewObserverQt::onFetchDocumentMarkup(quint64 requestId)
{
- Send(new QtRenderViewObserverHost_DidFetchDocumentMarkup(
+ Send(new RenderViewObserverHostQt_DidFetchDocumentMarkup(
routing_id(),
requestId,
render_view()->GetWebView()->mainFrame()->contentAsMarkup()));
}
-void QtRenderViewObserver::onFetchDocumentInnerText(quint64 requestId)
+void RenderViewObserverQt::onFetchDocumentInnerText(quint64 requestId)
{
- Send(new QtRenderViewObserverHost_DidFetchDocumentInnerText(
+ Send(new RenderViewObserverHostQt_DidFetchDocumentInnerText(
routing_id(),
requestId,
render_view()->GetWebView()->mainFrame()->contentAsText(std::numeric_limits<std::size_t>::max())));
}
-void QtRenderViewObserver::OnFirstVisuallyNonEmptyLayout()
+void RenderViewObserverQt::onSetBackgroundColor(quint32 color)
{
- Send(new QtRenderViewObserverHost_DidFirstVisuallyNonEmptyLayout(routing_id()));
+ render_view()->GetWebView()->setBaseBackgroundColor(color);
}
-bool QtRenderViewObserver::OnMessageReceived(const IPC::Message& message)
+void RenderViewObserverQt::OnFirstVisuallyNonEmptyLayout()
+{
+ Send(new RenderViewObserverHostQt_DidFirstVisuallyNonEmptyLayout(routing_id()));
+}
+
+bool RenderViewObserverQt::OnMessageReceived(const IPC::Message& message)
{
bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(QtRenderViewObserver, message)
- IPC_MESSAGE_HANDLER(QtRenderViewObserver_FetchDocumentMarkup, onFetchDocumentMarkup)
- IPC_MESSAGE_HANDLER(QtRenderViewObserver_FetchDocumentInnerText, onFetchDocumentInnerText)
+ IPC_BEGIN_MESSAGE_MAP(RenderViewObserverQt, message)
+ IPC_MESSAGE_HANDLER(RenderViewObserverQt_FetchDocumentMarkup, onFetchDocumentMarkup)
+ IPC_MESSAGE_HANDLER(RenderViewObserverQt_FetchDocumentInnerText, onFetchDocumentInnerText)
+ IPC_MESSAGE_HANDLER(RenderViewObserverQt_SetBackgroundColor, onSetBackgroundColor)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
+
+void RenderViewObserverQt::Navigate(const GURL &)
+{
+ if (m_web_cache_render_process_observer)
+ m_web_cache_render_process_observer->ExecutePendingClearCache();
+}
diff --git a/src/core/renderer/qt_render_view_observer.h b/src/core/renderer/render_view_observer_qt.h
index cb77cd0c9..166dcc9ea 100644
--- a/src/core/renderer/qt_render_view_observer.h
+++ b/src/core/renderer/render_view_observer_qt.h
@@ -33,26 +33,35 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#ifndef QT_RENDER_VIEW_OBSERVER_H
-#define QT_RENDER_VIEW_OBSERVER_H
+#ifndef RENDER_VIEW_OBSERVER_QT_H
+#define RENDER_VIEW_OBSERVER_QT_H
#include "content/public/renderer/render_view_observer.h"
#include <QtGlobal>
-class QtRenderViewObserver : public content::RenderViewObserver {
+namespace web_cache {
+class WebCacheRenderProcessObserver;
+}
+
+class RenderViewObserverQt : public content::RenderViewObserver {
public:
- QtRenderViewObserver(content::RenderView* render_view);
+ RenderViewObserverQt(content::RenderView* render_view,
+ web_cache::WebCacheRenderProcessObserver* web_cache_render_process_observer);
private:
void onFetchDocumentMarkup(quint64 requestId);
void onFetchDocumentInnerText(quint64 requestId);
+ void onSetBackgroundColor(quint32 color);
void OnFirstVisuallyNonEmptyLayout() Q_DECL_OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) Q_DECL_OVERRIDE;
+ virtual void Navigate(const GURL& url) Q_DECL_OVERRIDE;
+
+ web_cache::WebCacheRenderProcessObserver* m_web_cache_render_process_observer;
- DISALLOW_COPY_AND_ASSIGN(QtRenderViewObserver);
+ DISALLOW_COPY_AND_ASSIGN(RenderViewObserverQt);
};
-#endif // QT_RENDER_VIEW_OBSERVER_H
+#endif // RENDER_VIEW_OBSERVER_QT_H
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/devtools_discovery_page.html b/src/core/resources/devtools_discovery_page.html
index 7aac74932..d37dbfcf4 100644
--- a/src/core/resources/devtools_discovery_page.html
+++ b/src/core/resources/devtools_discovery_page.html
@@ -3,44 +3,68 @@
<title>QtWebEngine Remote Debugging</title>
<style>
body {
- background-color: rgb(245, 245, 245);
+ color: #222;
font-family: Helvetica, Arial, sans-serif;
+ margin: 0;
text-shadow: rgba(255, 255, 255, 0.496094) 0px 1px 0px;
}
#caption {
- color: black;
font-size: 16px;
- margin-top: 30px;
- margin-bottom: 0px;
- margin-left: 70px;
+ margin-top: 15px;
+ margin-bottom: 10px;
+ margin-left: 20px;
height: 20px;
text-align: left;
}
#items {
- margin-left: 60px;
- margin-right: 60px;
- -webkit-box-orient: horizontal;
- -webkit-box-lines: multiple;
+ display: flex;
+ flex-direction: column;
+ margin: 10px;
+}
+
+.item {
+ color: #222;
+ display: flex;
+ flex-direction: row;
+ text-decoration: none;
+ padding: 10px;
+ -webkit-transition-property: background-color, border-color;
+ -webkit-transition: background-color 0.15s, 0.15s;
+ -webkit-transition-delay: 0ms, 0ms;
}
-.frontend_ref {
+.item:not(.connected):hover {
+ background-color: rgba(242, 242, 242, 1);
+ border-color: rgba(110, 116, 128, 1);
color: black;
- text-decoration: initial;
}
-.text {
- background: no-repeat 0;
- background-size: 16px;
- font-size: 12px;
- margin: 4px 0px 0px 4px;
+.item.connected:hover {
+ border-color: rgba(184, 184, 184, 1);
+ color: rgb(110, 116, 128);
+}
+
+.description {
+ display: flex;
+ flex-direction: column;
+}
+
+.title, .subtitle {
+ font-size: 13px;
+ margin: 4px 0px 0px 6px;
overflow: hidden;
- padding: 2px 0px 0px 20px;
- text-align: left;
- text-overflow: ellipsis;
- white-space: nowrap;
+ padding-left: 20px;
}
+
+.title {
+ background-repeat: no-repeat;
+ background-size: 16px;
+ font-size: 15px;
+}
+
+
</style>
<script>
@@ -74,35 +98,43 @@ function overrideFrontendUrl(item) {
}
function appendItem(item_object) {
- var frontend_ref;
+ var item_element;
if (item_object.devtoolsFrontendUrl) {
- frontend_ref = document.createElement('a');
- frontend_ref.href = overrideFrontendUrl(item_object);
- frontend_ref.title = item_object.title;
+ item_element = document.createElement('a');
+ item_element.href = overrideFrontendUrl(item_object);
+ item_element.title = item_object.title;
} else {
- frontend_ref = document.createElement('div');
- frontend_ref.title = 'The tab already has an active debug session';
+ item_element = document.createElement('div');
+ item_element.className = 'connected';
+ item_element.title = 'The tab already has an active debug session';
}
- frontend_ref.className = 'frontend_ref';
+ item_element.classList.add('item');
- var text = document.createElement('div');
- text.className = 'text';
- text.innerText = item_object.description || item_object.title;
- text.style.cssText = 'background-image:url(' +
- item_object.faviconUrl + ')';
- frontend_ref.appendChild(text);
+ var description = document.createElement('div');
+ description.className = 'description';
- var item = document.createElement('p');
- item.appendChild(frontend_ref);
+ var title = document.createElement('div');
+ title.className = 'title';
+ title.textContent = item_object.description || item_object.title;
+ title.style.cssText = 'background-image:url(' +
+ item_object.faviconUrl + ')';
+ description.appendChild(title);
- document.getElementById('items').appendChild(item);
+ var subtitle = document.createElement('div');
+ subtitle.className = 'subtitle';
+ subtitle.textContent = (item_object.url || '').substring(0, 300);
+ description.appendChild(subtitle);
+
+ item_element.appendChild(description);
+
+ document.getElementById('items').appendChild(item_element);
}
</script>
</head>
<body onload='onLoad()'>
<div id='caption'>Inspectable pages</div>
+ <hr>
<div id='items'>
</div>
- <hr>
</body>
</html>
diff --git a/src/core/resources/resources.gyp b/src/core/resources/resources.gyp
index 4d653df12..143f21f9d 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',
@@ -77,15 +77,15 @@
['qt_install_data != ""', {
'copies': [
{
- 'destination': '<(qt_install_data)',
+ 'destination': '<(qt_install_data)/resources',
'files': [ '<(SHARED_INTERMEDIATE_DIR)/repack/qtwebengine_resources.pak' ],
},
{
- 'destination': '<(qt_install_data)',
+ 'destination': '<(qt_install_data)/resources',
'files': [ '<(SHARED_INTERMEDIATE_DIR)/repack/qtwebengine_resources_100p.pak' ],
},
{
- 'destination': '<(qt_install_data)',
+ 'destination': '<(qt_install_data)/resources',
'files': [ '<(SHARED_INTERMEDIATE_DIR)/repack/qtwebengine_resources_200p.pak' ],
},
],
diff --git a/src/core/stream_video_node.cpp b/src/core/stream_video_node.cpp
index a5a6041f3..fdae5fee2 100644
--- a/src/core/stream_video_node.cpp
+++ b/src/core/stream_video_node.cpp
@@ -38,9 +38,12 @@
#include <QtQuick/qsgtexture.h>
+namespace QtWebEngineCore {
+
class StreamVideoMaterialShader : public QSGMaterialShader
{
public:
+ StreamVideoMaterialShader(TextureTarget target) : m_target(target) { }
virtual void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial);
virtual char const *const *attributeNames() const Q_DECL_OVERRIDE {
@@ -55,7 +58,7 @@ public:
protected:
virtual const char *vertexShader() const Q_DECL_OVERRIDE {
// Keep in sync with cc::VertexShaderVideoTransform
- const char *shader =
+ static const char *shader =
"attribute highp vec4 a_position;\n"
"attribute mediump vec2 a_texCoord;\n"
"uniform highp mat4 matrix;\n"
@@ -70,7 +73,7 @@ protected:
virtual const char *fragmentShader() const Q_DECL_OVERRIDE {
// Keep in sync with cc::FragmentShaderRGBATexAlpha
- static const char *shader =
+ static const char *shaderExternal =
"#extension GL_OES_EGL_image_external : require\n"
"varying mediump vec2 v_texCoord;\n"
"uniform samplerExternalOES s_texture;\n"
@@ -79,7 +82,19 @@ protected:
" lowp vec4 texColor = texture2D(s_texture, v_texCoord);\n"
" gl_FragColor = texColor * alpha;\n"
"}";
- return shader;
+ static const char *shader2DRect =
+ "#extension GL_ARB_texture_rectangle : require\n"
+ "varying mediump vec2 v_texCoord;\n"
+ "uniform sampler2DRect s_texture;\n"
+ "uniform lowp float alpha;\n"
+ "void main() {\n"
+ " lowp vec4 texColor = texture2DRect(s_texture, v_texCoord);\n"
+ " gl_FragColor = texColor * alpha;\n"
+ "}";
+ if (m_target == ExternalTarget)
+ return shaderExternal;
+ else
+ return shader2DRect;
}
virtual void initialize() {
@@ -93,6 +108,7 @@ protected:
int m_id_texMatrix;
int m_id_sTexture;
int m_id_opacity;
+ TextureTarget m_target;
};
void StreamVideoMaterialShader::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
@@ -113,31 +129,38 @@ void StreamVideoMaterialShader::updateState(const RenderState &state, QSGMateria
program()->setUniformValue(m_id_texMatrix, mat->m_texMatrix);
}
-StreamVideoMaterial::StreamVideoMaterial(QSGTexture *texture)
+StreamVideoMaterial::StreamVideoMaterial(QSGTexture *texture, TextureTarget target)
: m_texture(texture)
+ , m_target(target)
{
}
QSGMaterialShader *StreamVideoMaterial::createShader() const
{
- return new StreamVideoMaterialShader;
+ return new StreamVideoMaterialShader(m_target);
}
-StreamVideoNode::StreamVideoNode(QSGTexture *texture)
+StreamVideoNode::StreamVideoNode(QSGTexture *texture, bool flip, TextureTarget target)
: m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
+ , m_flip(flip)
{
setGeometry(&m_geometry);
setFlag(QSGNode::OwnsMaterial);
- m_material = new StreamVideoMaterial(texture);
+ m_material = new StreamVideoMaterial(texture, target);
setMaterial(m_material);
}
void StreamVideoNode::setRect(const QRectF &rect)
{
- QSGGeometry::updateTexturedRectGeometry(geometry(), rect, QRectF(0, 0, 1, 1));
+ if (m_flip)
+ QSGGeometry::updateTexturedRectGeometry(geometry(), rect, QRectF(0, 1, 1, -1));
+ else
+ QSGGeometry::updateTexturedRectGeometry(geometry(), rect, QRectF(0, 0, 1, 1));
}
void StreamVideoNode::setTextureMatrix(const QMatrix4x4 &matrix)
{
m_material->m_texMatrix = matrix;
}
+
+} // namespace
diff --git a/src/core/stream_video_node.h b/src/core/stream_video_node.h
index f808bb609..92c640811 100644
--- a/src/core/stream_video_node.h
+++ b/src/core/stream_video_node.h
@@ -40,19 +40,22 @@
#include <QtQuick/qsgmaterial.h>
#include <QtQuick/qsgnode.h>
-QT_BEGIN_NAMESPACE
-class QSGTexture;
-QT_END_NAMESPACE
+QT_FORWARD_DECLARE_CLASS(QSGTexture)
+
+namespace QtWebEngineCore {
// These classes duplicate, QtQuick style, the logic of GLRenderer::DrawStreamVideoQuad.
// Their behavior should stay as close as possible to GLRenderer.
+enum TextureTarget { ExternalTarget, RectangleTarget };
+
class StreamVideoMaterial : public QSGMaterial
{
public:
- StreamVideoMaterial(QSGTexture *texture);
+ StreamVideoMaterial(QSGTexture *texture, TextureTarget target);
- virtual QSGMaterialType *type() const Q_DECL_OVERRIDE{
+ virtual QSGMaterialType *type() const Q_DECL_OVERRIDE
+ {
static QSGMaterialType theType;
return &theType;
}
@@ -61,18 +64,22 @@ public:
QSGTexture *m_texture;
QMatrix4x4 m_texMatrix;
+ TextureTarget m_target;
};
class StreamVideoNode : public QSGGeometryNode
{
public:
- StreamVideoNode(QSGTexture *texture);
+ StreamVideoNode(QSGTexture *texture, bool flip, TextureTarget target);
void setRect(const QRectF &rect);
void setTextureMatrix(const QMatrix4x4 &matrix);
private:
QSGGeometry m_geometry;
+ bool m_flip;
StreamVideoMaterial *m_material;
};
+} // namespace
+
#endif // STREAM_VIDEO_NODE_H
diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h
index 66fcd4dd0..eb874a26d 100644
--- a/src/core/type_conversion.h
+++ b/src/core/type_conversion.h
@@ -40,16 +40,21 @@
#include <QColor>
#include <QDateTime>
#include <QDir>
+#include <QImage>
#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 "third_party/skia/include/utils/SkMatrix44.h"
+#include "net/cookies/canonical_cookie.h"
+#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/rect.h"
+#include "third_party/skia/include/core/SkPixelRef.h"
+#include "third_party/skia/include/utils/SkMatrix44.h"
+#include "ui/gfx/geometry/rect.h"
#include "url/gurl.h"
namespace QtWebEngineCore {
@@ -92,6 +97,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 +132,17 @@ 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 QImage toQImage(const SkBitmap &bitmap, QImage::Format format)
+{
+ SkPixelRef *pixelRef = bitmap.pixelRef();
+ return QImage((uchar *)pixelRef->pixels(), bitmap.width(), bitmap.height(), format);
+}
+
inline QMatrix4x4 toQt(const SkMatrix44 &m)
{
QMatrix4x4 qtMatrix(
@@ -142,6 +163,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 c2e592bc5..618354d1c 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"
@@ -65,14 +64,19 @@
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/file_protocol_handler.h"
#include "net/url_request/ftp_protocol_handler.h"
+#include "net/url_request/url_request_intercepting_job_factory.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 "qwebenginecookiestore.h"
+#include "qwebenginecookiestore_p.h"
#include "type_conversion.h"
namespace QtWebEngineCore {
@@ -81,9 +85,11 @@ static const char kQrcSchemeQt[] = "qrc";
using content::BrowserThread;
-URLRequestContextGetterQt::URLRequestContextGetterQt(BrowserContextAdapter *browserContext, content::ProtocolHandlerMap *protocolHandlers)
+URLRequestContextGetterQt::URLRequestContextGetterQt(BrowserContextAdapter *browserContext, content::ProtocolHandlerMap *protocolHandlers, content::URLRequestInterceptorScopedVector request_interceptors)
: m_ignoreCertificateErrors(false)
, m_browserContext(browserContext)
+ , m_cookieDelegate(new CookieMonsterDelegateQt())
+ , m_requestInterceptors(request_interceptors.Pass())
{
std::swap(m_protocolHandlers, *protocolHandlers);
@@ -100,7 +106,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 +123,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));
}
@@ -157,34 +163,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());
@@ -211,8 +210,10 @@ void URLRequestContextGetterQt::generateCookieStore()
Q_ASSERT(m_storage);
m_updateCookieStore = 0;
- // 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.
+ // Unset it first to get a chance to destroy and flush the old cookie store before opening a new on possibly the same file.
m_storage->set_cookie_store(0);
+ m_cookieDelegate->setCookieMonster(0);
+ m_cookieDelegate->setClient(m_browserContext->cookieStore());
net::CookieStore* cookieStore = 0;
switch (m_browserContext->persistentCookiesPolicy()) {
@@ -221,7 +222,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:
@@ -229,7 +231,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:
@@ -237,11 +240,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()
@@ -250,13 +258,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()
@@ -267,6 +294,13 @@ void URLRequestContextGetterQt::updateHttpCache()
}
}
+void URLRequestContextGetterQt::updateJobFactory()
+{
+ Q_ASSERT(m_jobFactory);
+
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateJobFactory, this));
+}
+
static bool doNetworkSessionParamsMatch(const net::HttpNetworkSession::Params &first, const net::HttpNetworkSession::Params &second)
{
if (first.transport_security_state != second.transport_security_state)
@@ -362,26 +396,39 @@ void URLRequestContextGetterQt::generateHttpCache()
void URLRequestContextGetterQt::generateJobFactory()
{
Q_ASSERT(m_urlRequestContext);
- 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();
+ m_jobFactory.reset();
+ scoped_ptr<net::URLRequestJobFactoryImpl> jobFactory(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());
+ jobFactory->SetProtocolHandler(it->first, it->second.release());
+ }
- m_jobFactory->SetProtocolHandler(url::kDataScheme, new net::DataProtocolHandler());
- m_jobFactory->SetProtocolHandler(url::kFileScheme, new net::FileProtocolHandler(
+ jobFactory->SetProtocolHandler(url::kDataScheme, new net::DataProtocolHandler());
+ jobFactory->SetProtocolHandler(url::kFileScheme, new net::FileProtocolHandler(
content::BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
- m_jobFactory->SetProtocolHandler(kQrcSchemeQt, new QrcProtocolHandlerQt());
- m_jobFactory->SetProtocolHandler(url::kFtpScheme,
+ jobFactory->SetProtocolHandler(kQrcSchemeQt, new QrcProtocolHandlerQt());
+ 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)
+ jobFactory->SetProtocolHandler(it.key().toStdString(), new CustomProtocolHandler(it.value()));
+
+ // Set up interceptors in the reverse order.
+ scoped_ptr<net::URLRequestJobFactory> topJobFactory = jobFactory.Pass();
+
+ for (content::URLRequestInterceptorScopedVector::reverse_iterator i = m_requestInterceptors.rbegin(); i != m_requestInterceptors.rend(); ++i)
+ topJobFactory.reset(new net::URLRequestInterceptingJobFactory(topJobFactory.Pass(), make_scoped_ptr(*i)));
+
+ m_requestInterceptors.weak_clear();
+
+ m_jobFactory = topJobFactory.Pass();
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 dc861f8da..8740c65a2 100644
--- a/src/core/url_request_context_getter_qt.h
+++ b/src/core/url_request_context_getter_qt.h
@@ -50,12 +50,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;
}
@@ -65,7 +67,7 @@ class BrowserContextAdapter;
class URLRequestContextGetterQt : public net::URLRequestContextGetter {
public:
- explicit URLRequestContextGetterQt(BrowserContextAdapter *browserContext, content::ProtocolHandlerMap *protocolHandlers);
+ explicit URLRequestContextGetterQt(BrowserContextAdapter *browserContext, content::ProtocolHandlerMap *protocolHandlers, content::URLRequestInterceptorScopedVector request_interceptors);
virtual net::URLRequestContext *GetURLRequestContext() Q_DECL_OVERRIDE;
virtual scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() const Q_DECL_OVERRIDE;
@@ -75,6 +77,7 @@ public:
void updateUserAgent();
void updateCookieStore();
void updateHttpCache();
+ void updateJobFactory();
private:
virtual ~URLRequestContextGetterQt();
@@ -96,10 +99,14 @@ 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::URLRequestJobFactory> m_jobFactory;
scoped_ptr<net::DhcpProxyScriptFetcherFactory> m_dhcpProxyScriptFetcherFactory;
+ scoped_refptr<CookieMonsterDelegateQt> m_cookieDelegate;
+ content::URLRequestInterceptorScopedVector m_requestInterceptors;
+
+ 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..907f71c2e 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,13 +54,14 @@ 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)
, m_error(0)
, m_started(false)
- , m_weakFactory(this)
+ , m_weakFactoryIO(this)
+ , m_weakFactoryUI(this)
{
}
@@ -77,7 +79,7 @@ URLRequestCustomJob::~URLRequestCustomJob()
void URLRequestCustomJob::Start()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, base::Bind(&URLRequestCustomJob::startAsync, m_weakFactory.GetWeakPtr()));
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, base::Bind(&URLRequestCustomJob::startAsync, m_weakFactoryIO.GetWeakPtr()));
}
void URLRequestCustomJob::Kill()
@@ -92,7 +94,8 @@ void URLRequestCustomJob::Kill()
if (m_device && m_device->isOpen())
m_device->close();
m_device = 0;
- m_weakFactory.InvalidateWeakPtrs();
+ m_weakFactoryIO.InvalidateWeakPtrs();
+ m_weakFactoryUI.InvalidateWeakPtrs();
URLRequestJob::Kill();
}
@@ -150,7 +153,7 @@ void URLRequestCustomJob::setReplyDevice(QIODevice *device)
m_device->open(QIODevice::ReadOnly);
if (m_device && m_device->isReadable())
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyStarted, m_weakFactory.GetWeakPtr()));
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyStarted, m_weakFactoryUI.GetWeakPtr()));
else
fail(ERR_INVALID_URL);
}
@@ -178,7 +181,7 @@ void URLRequestCustomJob::redirect(const GURL &url)
QMutexLocker lock(&m_mutex);
m_redirect = url;
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyStarted, m_weakFactory.GetWeakPtr()));
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyStarted, m_weakFactoryUI.GetWeakPtr()));
}
void URLRequestCustomJob::abort()
@@ -188,7 +191,7 @@ void URLRequestCustomJob::abort()
if (m_device && m_device->isOpen())
m_device->close();
m_device = 0;
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyCanceled, m_weakFactory.GetWeakPtr()));
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyCanceled, m_weakFactoryUI.GetWeakPtr()));
}
void URLRequestCustomJob::notifyCanceled()
@@ -213,19 +216,23 @@ void URLRequestCustomJob::fail(int error)
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
QMutexLocker lock(&m_mutex);
m_error = error;
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyFailure, m_weakFactory.GetWeakPtr()));
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyFailure, m_weakFactoryUI.GetWeakPtr()));
}
void URLRequestCustomJob::notifyFailure()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- QMutexLocker lock(&m_mutex);
+ m_mutex.lock();
if (m_device)
m_device->close();
- if (m_started)
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, m_error));
+ const URLRequestStatus status(URLRequestStatus::FAILED, m_error);
+ const bool started = m_started;
+ m_mutex.unlock();
+
+ if (started)
+ NotifyDone(status);
else
- NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, m_error));
+ NotifyStartError(status);
}
void URLRequestCustomJob::startAsync()
@@ -236,7 +243,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..be5cae43c 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,13 +81,14 @@ 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;
GURL m_redirect;
bool m_started;
- base::WeakPtrFactory<URLRequestCustomJob> m_weakFactory;
+ base::WeakPtrFactory<URLRequestCustomJob> m_weakFactoryIO;
+ base::WeakPtrFactory<URLRequestCustomJob> m_weakFactoryUI;
friend class URLRequestCustomJobDelegate;
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..608dbf7e7 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -45,7 +45,8 @@
#include "browser_context_adapter.h"
#include "browser_context_qt.h"
#include "media_capture_devices_dispatcher.h"
-#include "qt_render_view_observer_host.h"
+#include "qwebenginecallback_p.h"
+#include "render_view_observer_host_qt.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,11 +380,12 @@ 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.
d->webContentsDelegate.reset(new WebContentsDelegateQt(d->webContents.get(), adapterClient));
- d->renderViewObserverHost.reset(new QtRenderViewObserverHost(d->webContents.get(), adapterClient));
+ d->renderViewObserverHost.reset(new RenderViewObserverHostQt(d->webContents.get(), adapterClient));
// Let the WebContent's view know about the WebContentsAdapterClient.
WebContentsViewQt* contentsView = static_cast<WebContentsViewQt*>(static_cast<content::WebContentsImpl*>(d->webContents.get())->GetView());
@@ -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 5d9e034c5..6902a202f 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;
@@ -161,12 +209,13 @@ public:
virtual void adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect & initialGeometry) = 0;
virtual bool isBeingAdopted() = 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;
@@ -178,7 +227,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;
@@ -186,7 +235,9 @@ 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 requestGeometryChange(const QRect &geometry) = 0;
virtual void allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) = 0;
virtual BrowserContextAdapter* browserContextAdapter() = 0;
diff --git a/src/core/web_contents_adapter_p.h b/src/core/web_contents_adapter_p.h
index 505f803b2..22f295b32 100644
--- a/src/core/web_contents_adapter_p.h
+++ b/src/core/web_contents_adapter_p.h
@@ -62,7 +62,7 @@ class WebEngineContext;
namespace QtWebEngineCore {
class BrowserContextAdapter;
-class QtRenderViewObserverHost;
+class RenderViewObserverHostQt;
class UserScriptControllerHost;
class WebChannelIPCTransportHost;
class WebContentsAdapterClient;
@@ -76,7 +76,7 @@ public:
QExplicitlySharedDataPointer<BrowserContextAdapter> browserContextAdapter;
scoped_ptr<content::WebContents> webContents;
scoped_ptr<WebContentsDelegateQt> webContentsDelegate;
- scoped_ptr<QtRenderViewObserverHost> renderViewObserverHost;
+ scoped_ptr<RenderViewObserverHostQt> renderViewObserverHost;
scoped_ptr<WebChannelIPCTransportHost> webChannelTransport;
QWebChannel *webChannel;
WebContentsAdapterClient *adapterClient;
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 14f2eda5a..81f16970d 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"
@@ -49,12 +51,14 @@
#include "web_engine_settings.h"
#include "web_engine_visited_links_manager.h"
+#include "components/web_cache/browser/web_cache_manager.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/favicon_url.h"
#include "content/public/common/file_chooser_params.h"
@@ -63,6 +67,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.
@@ -108,7 +114,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()));
@@ -127,7 +133,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)
@@ -177,13 +183,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;
@@ -234,36 +241,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)
@@ -289,6 +304,17 @@ void WebContentsDelegateQt::RequestMediaAccessPermission(content::WebContents *w
MediaCaptureDevicesDispatcher::GetInstance()->processMediaAccessRequest(m_viewClient, web_contents, request, callback);
}
+void WebContentsDelegateQt::MoveContents(content::WebContents *source, const gfx::Rect &pos)
+{
+ Q_UNUSED(source)
+ m_viewClient->requestGeometryChange(toQt(pos));
+}
+
+bool WebContentsDelegateQt::IsPopupOrPanel(const content::WebContents *source) const
+{
+ return source->HasOpener();
+}
+
void WebContentsDelegateQt::UpdateTargetURL(content::WebContents* source, const GURL& url)
{
Q_UNUSED(source)
@@ -303,6 +329,11 @@ void WebContentsDelegateQt::DidNavigateAnyFrame(content::RenderFrameHost* render
m_viewClient->browserContextAdapter()->visitedLinksManager()->addUrl(params.url);
}
+void WebContentsDelegateQt::WasShown()
+{
+ web_cache::WebCacheManager::GetInstance()->ObserveActivity(web_contents()->GetRenderProcessHost()->GetID());
+}
+
void WebContentsDelegateQt::RequestToLockMouse(content::WebContents *web_contents, bool user_gesture, bool last_unlocked_by_target)
{
Q_UNUSED(user_gesture);
@@ -340,28 +371,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)
@@ -382,4 +406,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..356b2df88 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -39,10 +39,12 @@
#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"
#include "javascript_dialog_manager_qt.h"
+#include <QtCore/qvector.h>
#include <QtCore/qcompilerdetection.h>
QT_FORWARD_DECLARE_CLASS(CertificateErrorController)
@@ -72,49 +74,53 @@ 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;
virtual void FindReply(content::WebContents *source, int request_id, int number_of_matches, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update) Q_DECL_OVERRIDE;
virtual void RequestMediaAccessPermission(content::WebContents* web_contents, const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback) Q_DECL_OVERRIDE;
+ virtual void MoveContents(content::WebContents *source, const gfx::Rect &pos) Q_DECL_OVERRIDE;
+ virtual bool IsPopupOrPanel(const content::WebContents *source) const Q_DECL_OVERRIDE;
virtual void UpdateTargetURL(content::WebContents* source, const GURL& url) Q_DECL_OVERRIDE;
virtual void RequestToLockMouse(content::WebContents *web_contents, bool user_gesture, bool last_unlocked_by_target) Q_DECL_OVERRIDE;
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;
+ virtual void WasShown() 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;
- QList<int64> m_loadingErrorFrameList;
+ QVector<int64> m_loadingErrorFrameList;
};
} // namespace QtWebEngineCore
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..9c8a6c757 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -85,6 +85,10 @@
using namespace QtWebEngineCore;
+QT_BEGIN_NAMESPACE
+Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
+QT_END_NAMESPACE
+
namespace {
scoped_refptr<WebEngineContext> sContext;
@@ -101,7 +105,7 @@ void destroyContext()
bool usingANGLE()
{
#if defined(Q_OS_WIN)
- return QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES;
+ return qt_gl_global_share_context()->isOpenGLES();
#else
return false;
#endif
@@ -153,6 +157,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.
@@ -198,38 +203,39 @@ WebEngineContext::WebEngineContext()
, m_browserRunner(content::BrowserMainRunner::Create())
, m_globalQObject(new QObject())
{
- QList<QByteArray> args;
+ QVector<QByteArray> args;
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();
@@ -237,14 +243,12 @@ WebEngineContext::WebEngineContext()
parsedCommandLine->AppendSwitch(switches::kDisableGpu);
} else {
const char *glType = 0;
- switch (QOpenGLContext::openGLModuleType()) {
- case QOpenGLContext::LibGL:
- glType = gfx::kGLImplementationDesktopName;
- break;
- case QOpenGLContext::LibGLES:
+ if (qt_gl_global_share_context()->isOpenGLES()) {
glType = gfx::kGLImplementationEGLName;
- break;
+ } else {
+ glType = gfx::kGLImplementationDesktopName;
}
+
parsedCommandLine->AppendSwitchASCII(switches::kUseGL, glType);
}
@@ -260,13 +264,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..cfe5556de 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -52,7 +52,6 @@
#include <QLibraryInfo>
#include <QStandardPaths>
#include <QString>
-#include <QStringBuilder>
#ifndef QTWEBENGINEPROCESS_NAME
#error "No name defined for QtWebEngine's process"
@@ -138,7 +137,7 @@ QString subProcessPath()
}
Q_FOREACH (const QString &candidate, candidatePaths) {
- if (QFileInfo(candidate).exists()) {
+ if (QFileInfo::exists(candidate)) {
processPath = candidate;
break;
}
@@ -162,18 +161,16 @@ QString pluginsPath()
if (!initialized) {
initialized = true;
-
const QStringList directories = QCoreApplication::libraryPaths();
Q_FOREACH (const QString &dir, directories) {
const QString candidate = dir % "/" % QLatin1String("qtwebengine");
- if (QFileInfo(candidate).exists()) {
+ if (QFileInfo::exists(candidate)) {
pluginsPath = candidate;
break;
}
}
if (pluginsPath.isEmpty()) {
- qWarning("Qt WebEngine Plugins directory not found. Trying fallback directory... Plugins as for example video codecs MAY NOT work.");
pluginsPath = fallbackDir();
}
}
@@ -205,26 +202,57 @@ QString localesPath()
#endif
}
-QString libraryDataPath()
+QString icuDataPath()
{
#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
return getResourcesPath(frameworkBundle());
#else
static bool initialized = false;
- static QString potentialDataPath = QLibraryInfo::location(QLibraryInfo::DataPath);
+ static QString potentialResourcesPath = QLibraryInfo::location(QLibraryInfo::DataPath) % QLatin1String("/resources");
if (!initialized) {
initialized = true;
- if (!QFileInfo::exists(potentialDataPath)) {
- qWarning("Qt WebEngine data directory not found at location %s. Trying application directory...", qPrintable(potentialDataPath));
- potentialDataPath = QCoreApplication::applicationDirPath();
+ if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/icudtl.dat"))) {
+ qWarning("Qt WebEngine ICU data not found at %s. Trying parent directory...", qPrintable(potentialResourcesPath));
+ potentialResourcesPath = QLibraryInfo::location(QLibraryInfo::DataPath);
+ }
+ if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/icudtl.dat"))) {
+ qWarning("Qt WebEngine ICU data not found at %s. Trying application directory...", qPrintable(potentialResourcesPath));
+ potentialResourcesPath = QCoreApplication::applicationDirPath();
+ }
+ if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/icudtl.dat"))) {
+ qWarning("Qt WebEngine ICU data not found at %s. Trying fallback directory... The application MAY NOT work.", qPrintable(potentialResourcesPath));
+ potentialResourcesPath = fallbackDir();
+ }
+ }
+
+ return potentialResourcesPath;
+#endif
+}
+
+QString resourcesDataPath()
+{
+#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
+ return getResourcesPath(frameworkBundle());
+#else
+ static bool initialized = false;
+ static QString potentialResourcesPath = QLibraryInfo::location(QLibraryInfo::DataPath) % QLatin1String("/resources");
+ if (!initialized) {
+ initialized = true;
+ if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/qtwebengine_resources.pak"))) {
+ qWarning("Qt WebEngine resources not found at %s. Trying parent directory...", qPrintable(potentialResourcesPath));
+ potentialResourcesPath = QLibraryInfo::location(QLibraryInfo::DataPath);
+ }
+ if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/qtwebengine_resources.pak"))) {
+ qWarning("Qt WebEngine resources not found at %s. Trying application directory...", qPrintable(potentialResourcesPath));
+ potentialResourcesPath = QCoreApplication::applicationDirPath();
}
- if (!QFileInfo::exists(potentialDataPath)) {
- qWarning("Qt WebEngine data directory not found at location %s. Trying fallback directory... The application MAY NOT work.", qPrintable(potentialDataPath));
- potentialDataPath = fallbackDir();
+ if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/qtwebengine_resources.pak"))) {
+ qWarning("Qt WebEngine resources not found at %s. Trying fallback directory... The application MAY NOT work.", qPrintable(potentialResourcesPath));
+ potentialResourcesPath = fallbackDir();
}
}
- return potentialDataPath;
+ return potentialResourcesPath;
#endif
}
} // namespace
@@ -234,11 +262,11 @@ base::FilePath WebEngineLibraryInfo::getPath(int key)
QString directory;
switch (key) {
case QT_RESOURCES_PAK:
- return toFilePath(libraryDataPath() % QLatin1String("/qtwebengine_resources.pak"));
+ return toFilePath(resourcesDataPath() % QLatin1String("/qtwebengine_resources.pak"));
case QT_RESOURCES_100P_PAK:
- return toFilePath(libraryDataPath() % QLatin1String("/qtwebengine_resources_100p.pak"));
+ return toFilePath(resourcesDataPath() % QLatin1String("/qtwebengine_resources_100p.pak"));
case QT_RESOURCES_200P_PAK:
- return toFilePath(libraryDataPath() % QLatin1String("/qtwebengine_resources_200p.pak"));
+ return toFilePath(resourcesDataPath() % QLatin1String("/qtwebengine_resources_200p.pak"));
case base::FILE_EXE:
case content::CHILD_PROCESS_EXE:
return toFilePath(subProcessPath());
@@ -254,7 +282,7 @@ base::FilePath WebEngineLibraryInfo::getPath(int key)
directory = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
break;
case base::DIR_QT_LIBRARY_DATA:
- return toFilePath(libraryDataPath());
+ return toFilePath(icuDataPath());
case content::DIR_MEDIA_LIBS:
return toFilePath(pluginsPath());
case ui::DIR_LOCALES:
@@ -276,7 +304,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..ff67ed6a6 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -46,6 +46,10 @@
namespace QtWebEngineCore {
+QHash<WebEngineSettings::Attribute, bool> WebEngineSettings::m_defaultAttributes;
+QHash<WebEngineSettings::FontFamily, QString> WebEngineSettings::m_defaultFontFamilies;
+QHash<WebEngineSettings::FontSize, int> WebEngineSettings::m_defaultFontSizes;
+
static const int batchTimerTimeout = 0;
class BatchTimer : public QTimer {
@@ -132,9 +136,12 @@ bool WebEngineSettings::testAttribute(WebEngineSettings::Attribute attr) const
void WebEngineSettings::resetAttribute(WebEngineSettings::Attribute attr)
{
- if (!parentSettings) // FIXME: Set initial defaults.
- return;
- m_attributes.remove(attr);
+ if (!parentSettings) {
+ Q_ASSERT(m_defaultAttributes.contains(attr));
+ m_attributes.insert(attr, m_defaultAttributes.value(attr));
+ } else {
+ m_attributes.remove(attr);
+ }
scheduleApplyRecursively();
}
@@ -155,9 +162,12 @@ QString WebEngineSettings::fontFamily(WebEngineSettings::FontFamily which)
void WebEngineSettings::resetFontFamily(WebEngineSettings::FontFamily which)
{
- if (!parentSettings) // FIXME: Set initial defaults.
- return;
- m_fontFamilies.remove(which);
+ if (!parentSettings) {
+ Q_ASSERT(m_defaultFontFamilies.contains(which));
+ m_fontFamilies.insert(which, m_defaultFontFamilies.value(which));
+ } else {
+ m_fontFamilies.remove(which);
+ }
scheduleApplyRecursively();
}
@@ -178,9 +188,12 @@ int WebEngineSettings::fontSize(WebEngineSettings::FontSize type) const
void WebEngineSettings::resetFontSize(WebEngineSettings::FontSize type)
{
- if (!parentSettings) // FIXME: Set initial defaults.
- return;
- m_fontSizes.remove(type);
+ if (!parentSettings) {
+ Q_ASSERT(m_defaultFontSizes.contains(type));
+ m_fontSizes.insert(type, m_defaultFontSizes.value(type));
+ } else {
+ m_fontSizes.remove(type);
+ }
scheduleApplyRecursively();
}
@@ -199,43 +212,54 @@ QString WebEngineSettings::defaultTextEncoding() const
void WebEngineSettings::initDefaults(bool offTheRecord)
{
- // Initialize the default settings.
- m_attributes.insert(AutoLoadImages, true);
- m_attributes.insert(JavascriptEnabled, true);
- m_attributes.insert(JavascriptCanOpenWindows, true);
- m_attributes.insert(JavascriptCanAccessClipboard, false);
- m_attributes.insert(LinksIncludedInFocusChain, true);
- m_attributes.insert(LocalStorageEnabled, !offTheRecord);
- m_attributes.insert(LocalContentCanAccessRemoteUrls, false);
- m_attributes.insert(XSSAuditingEnabled, false);
- m_attributes.insert(SpatialNavigationEnabled, false);
- m_attributes.insert(LocalContentCanAccessFileUrls, true);
- m_attributes.insert(HyperlinkAuditingEnabled, false);
- m_attributes.insert(ScrollAnimatorEnabled, false);
- m_attributes.insert(ErrorPageEnabled, true);
-
- // Default fonts
- QFont defaultFont;
- defaultFont.setStyleHint(QFont::Serif);
- m_fontFamilies.insert(StandardFont, defaultFont.defaultFamily());
- m_fontFamilies.insert(SerifFont, defaultFont.defaultFamily());
-
- defaultFont.setStyleHint(QFont::Fantasy);
- m_fontFamilies.insert(FantasyFont, defaultFont.defaultFamily());
-
- defaultFont.setStyleHint(QFont::Cursive);
- m_fontFamilies.insert(CursiveFont, defaultFont.defaultFamily());
-
- defaultFont.setStyleHint(QFont::SansSerif);
- m_fontFamilies.insert(SansSerifFont, defaultFont.defaultFamily());
-
- defaultFont.setStyleHint(QFont::Monospace);
- m_fontFamilies.insert(FixedFont, defaultFont.defaultFamily());
-
- m_fontSizes.insert(MinimumFontSize, 0);
- m_fontSizes.insert(MinimumLogicalFontSize, 6);
- m_fontSizes.insert(DefaultFixedFontSize, 13);
- m_fontSizes.insert(DefaultFontSize, 16);
+ if (m_defaultAttributes.isEmpty()) {
+ // Initialize the default settings.
+ m_defaultAttributes.insert(AutoLoadImages, true);
+ m_defaultAttributes.insert(JavascriptEnabled, true);
+ m_defaultAttributes.insert(JavascriptCanOpenWindows, true);
+ m_defaultAttributes.insert(JavascriptCanAccessClipboard, false);
+ m_defaultAttributes.insert(LinksIncludedInFocusChain, true);
+ m_defaultAttributes.insert(LocalStorageEnabled, !offTheRecord);
+ m_defaultAttributes.insert(LocalContentCanAccessRemoteUrls, false);
+ m_defaultAttributes.insert(XSSAuditingEnabled, false);
+ m_defaultAttributes.insert(SpatialNavigationEnabled, false);
+ m_defaultAttributes.insert(LocalContentCanAccessFileUrls, true);
+ m_defaultAttributes.insert(HyperlinkAuditingEnabled, false);
+ m_defaultAttributes.insert(ScrollAnimatorEnabled, false);
+ m_defaultAttributes.insert(ErrorPageEnabled, true);
+ m_defaultAttributes.insert(PluginsEnabled, false);
+ m_defaultAttributes.insert(FullScreenSupportEnabled, false);
+ }
+ m_attributes = m_defaultAttributes;
+
+ if (m_defaultFontFamilies.isEmpty()) {
+ // Default fonts
+ QFont defaultFont;
+ defaultFont.setStyleHint(QFont::Serif);
+ m_defaultFontFamilies.insert(StandardFont, defaultFont.defaultFamily());
+ m_defaultFontFamilies.insert(SerifFont, defaultFont.defaultFamily());
+
+ defaultFont.setStyleHint(QFont::Fantasy);
+ m_defaultFontFamilies.insert(FantasyFont, defaultFont.defaultFamily());
+
+ defaultFont.setStyleHint(QFont::Cursive);
+ m_defaultFontFamilies.insert(CursiveFont, defaultFont.defaultFamily());
+
+ defaultFont.setStyleHint(QFont::SansSerif);
+ m_defaultFontFamilies.insert(SansSerifFont, defaultFont.defaultFamily());
+
+ defaultFont.setStyleHint(QFont::Monospace);
+ m_defaultFontFamilies.insert(FixedFont, defaultFont.defaultFamily());
+ }
+ m_fontFamilies = m_defaultFontFamilies;
+
+ if (m_defaultFontSizes.isEmpty()) {
+ m_defaultFontSizes.insert(MinimumFontSize, 0);
+ m_defaultFontSizes.insert(MinimumLogicalFontSize, 6);
+ m_defaultFontSizes.insert(DefaultFixedFontSize, 13);
+ m_defaultFontSizes.insert(DefaultFontSize, 16);
+ }
+ m_fontSizes = m_defaultFontSizes;
m_defaultEncoding = QStringLiteral("ISO-8859-1");
}
@@ -277,6 +301,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..3d3d734d0 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.
@@ -134,6 +136,10 @@ private:
WebEngineSettings *parentSettings;
QSet<WebEngineSettings *> childSettings;
+ static QHash<Attribute, bool> m_defaultAttributes;
+ static QHash<FontFamily, QString> m_defaultFontFamilies;
+ static QHash<FontSize, int> m_defaultFontSizes;
+
friend class BatchTimer;
friend class WebContentsAdapter;
};
diff --git a/src/core/yuv_video_node.cpp b/src/core/yuv_video_node.cpp
index 23528c8ec..7deeb5802 100644
--- a/src/core/yuv_video_node.cpp
+++ b/src/core/yuv_video_node.cpp
@@ -40,6 +40,8 @@
#include <QtGui/qopenglfunctions.h>
#include <QtQuick/qsgtexture.h>
+namespace QtWebEngineCore {
+
class YUVVideoMaterialShader : public QSGMaterialShader
{
public:
@@ -61,12 +63,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 +80,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 +107,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 +122,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 +144,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 +184,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 +200,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 +248,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 +302,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 +331,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 +353,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);
}
@@ -276,3 +371,5 @@ void YUVVideoNode::setRect(const QRectF &rect)
{
QSGGeometry::updateTexturedRectGeometry(geometry(), rect, QRectF(0, 0, 1, 1));
}
+
+} // namespace
diff --git a/src/core/yuv_video_node.h b/src/core/yuv_video_node.h
index f96df56ce..5b13879d3 100644
--- a/src/core/yuv_video_node.h
+++ b/src/core/yuv_video_node.h
@@ -40,9 +40,9 @@
#include <QtQuick/qsgmaterial.h>
#include <QtQuick/qsgnode.h>
-QT_BEGIN_NAMESPACE
-class QSGTexture;
-QT_END_NAMESPACE
+QT_FORWARD_DECLARE_CLASS(QSGTexture)
+
+namespace QtWebEngineCore {
// These classes duplicate, QtQuick style, the logic of GLRenderer::DrawYUVVideoQuad.
// Their behavior should stay as close as possible to GLRenderer.
@@ -50,9 +50,17 @@ 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 {
+ virtual QSGMaterialType *type() const Q_DECL_OVERRIDE
+ {
static QSGMaterialType theType;
return &theType;
}
@@ -63,15 +71,23 @@ 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{
+ virtual QSGMaterialType *type() const Q_DECL_OVERRIDE
+ {
static QSGMaterialType theType;
return &theType;
}
@@ -85,7 +101,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:
@@ -93,4 +111,6 @@ private:
YUVVideoMaterial *m_material;
};
+} // namespace
+
#endif // YUV_VIDEO_NODE_H
diff --git a/src/process/process.pro b/src/process/process.pro
index 5526b0f1c..6174e53bf 100644
--- a/src/process/process.pro
+++ b/src/process/process.pro
@@ -8,24 +8,23 @@ load(qt_build_paths)
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
+ # FIXME: remove the following workaround with proper rpath handling or
+ # patching of the installed QtWebEngineProcess binary.
+ # Since QtWebEngineCore is now built as a framework, we need to pull
+ # in and fixup its dependencies as well.
+ QT += webenginecore
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) "
+ "$(TARGET); "
+ linked_frameworks = QtQuick QtQml QtNetwork QtCore QtGui QtWebChannel
+ for (current_framework, linked_frameworks) {
+ QMAKE_POST_LINK += "xcrun install_name_tool -change " \
+ "`xcrun otool -X -L $(TARGET) | grep $${current_framework} | cut -d ' ' -f 1` " \
+ "@executable_path/../../../../../../../$${current_framework}.framework/$${current_framework} " \
+ "$(TARGET);"
+ }
} else {
CONFIG -= app_bundle
win32: DESTDIR = $$MODULE_BASE_OUTDIR/bin
diff --git a/src/webengine/api/qquickwebenginecertificateerror.cpp b/src/webengine/api/qquickwebenginecertificateerror.cpp
index 202d201b3..ea9b2bc11 100644
--- a/src/webengine/api/qquickwebenginecertificateerror.cpp
+++ b/src/webengine/api/qquickwebenginecertificateerror.cpp
@@ -61,13 +61,13 @@ public:
/*!
\qmltype WebEngineCertificateError
\instantiates QQuickWebEngineCertificateError
- \inqmlmodule QtWebEngine 1.1
+ \inqmlmodule QtWebEngine
\since QtWebEngine 1.1
- \brief A utility class for accepting or denying certificate exceptions when a certificate error occurs.
+ \brief A utility type for ignoring certificate errors or rejecting erroneous certificates.
- This class contains information about a certificate error that happened and provides a way to accept or
- deny a certificate exception.
+ This QML type contains information about a certificate error that occurred and provides a way
+ to ignore the error or reject the certificate.
\sa WebEngineView::certificateError
*/
@@ -86,8 +86,9 @@ QQuickWebEngineCertificateError::~QQuickWebEngineCertificateError()
/*!
\qmlmethod void WebEngineCertificateError::defer()
- This function should be called when there is a need to postpone the decision to ignore or not the certificate error. This is useful to
- wait for user input. When called it will pause the url request until WebEngineCertificateError::ignoreCertificateError() or
+ This function should be called when there is a need to postpone the decision whether to ignore a
+ certificate error, for example, while waiting for user input. When called, the function pauses the
+ URL request until WebEngineCertificateError::ignoreCertificateError() or
WebEngineCertificateError::rejectCertificate() is called.
*/
void QQuickWebEngineCertificateError::defer()
@@ -98,7 +99,7 @@ void QQuickWebEngineCertificateError::defer()
/*!
\qmlmethod void WebEngineCertificateError::ignoreCertificateError()
- The certificate error is ignored and the WebEngineView continues to load the requested url.
+ The certificate error is ignored, and the web engine view continues to load the requested URL.
*/
void QQuickWebEngineCertificateError::ignoreCertificateError()
{
@@ -114,7 +115,7 @@ void QQuickWebEngineCertificateError::ignoreCertificateError()
/*!
\qmlmethod void WebEngineCertificateError::rejectCertificate()
- The WebEngineView stops loading the requested url.
+ The certificate is rejected, and the web engine view stops loading the requested URL.
*/
void QQuickWebEngineCertificateError::rejectCertificate()
{
@@ -148,7 +149,8 @@ QUrl QQuickWebEngineCertificateError::url() const
The type of the error.
- \value SslPinnedKeyNotInCertificateChain The certificate did not match the built-in public key pins for the host name.
+ \value SslPinnedKeyNotInCertificateChain The certificate did not match the built-in public keys
+ pinned for the host name.
\value CertificateCommonNameInvalid The certificate's common name did not match the host name.
\value CertificateDateInvalid The certificate is not valid at the current date and time.
\value CertificateAuthorityInvalid The certificate is not signed by a trusted authority.
@@ -184,7 +186,7 @@ QString QQuickWebEngineCertificateError::description() const
\qmlproperty bool WebEngineCertificateError::overridable
\readonly
- A boolean that indicates if the certificate error can be overridden and accepted.
+ A boolean that indicates whether the certificate error can be overridden and ignored.
*/
bool QQuickWebEngineCertificateError::overridable() const
{
diff --git a/src/webengine/api/qquickwebenginecertificateerror_p.h b/src/webengine/api/qquickwebenginecertificateerror_p.h
index 6f54528d4..7deeac932 100644
--- a/src/webengine/api/qquickwebenginecertificateerror_p.h
+++ b/src/webengine/api/qquickwebenginecertificateerror_p.h
@@ -62,7 +62,6 @@ class Q_WEBENGINE_EXPORT QQuickWebEngineCertificateError : public QObject {
Q_PROPERTY(Error error READ error)
Q_PROPERTY(QString description READ description)
Q_PROPERTY(bool overridable READ overridable)
- Q_ENUMS(Error)
public:
@@ -82,6 +81,7 @@ public:
CertificateWeakKey = -211,
CertificateNameConstraintViolation = -212,
};
+ Q_ENUM(Error)
QQuickWebEngineCertificateError(const QSharedPointer<CertificateErrorController> &controller, QObject *parent = 0);
~QQuickWebEngineCertificateError();
diff --git a/src/webengine/api/qquickwebenginedownloaditem.cpp b/src/webengine/api/qquickwebenginedownloaditem.cpp
index e04cff2c4..2c1ec1ce9 100644
--- a/src/webengine/api/qquickwebenginedownloaditem.cpp
+++ b/src/webengine/api/qquickwebenginedownloaditem.cpp
@@ -36,7 +36,7 @@
#include "qquickwebenginedownloaditem_p.h"
#include "qquickwebenginedownloaditem_p_p.h"
-#include "qquickwebengineprofile_p_p.h"
+#include "qquickwebengineprofile_p.h"
using QtWebEngineCore::BrowserContextAdapterClient;
@@ -76,7 +76,7 @@ QQuickWebEngineDownloadItemPrivate::~QQuickWebEngineDownloadItemPrivate()
/*!
\qmltype WebEngineDownloadItem
\instantiates QQuickWebEngineDownloadItem
- \inqmlmodule QtWebEngine 1.1
+ \inqmlmodule QtWebEngine
\since QtWebEngine 1.1
\brief Provides information about a download.
@@ -217,6 +217,18 @@ qint64 QQuickWebEngineDownloadItem::receivedBytes() const
}
/*!
+ \qmlproperty QString WebEngineDownloadItem::mimeType
+
+ Holds the MIME type of the download.
+*/
+
+QString QQuickWebEngineDownloadItem::mimeType() const
+{
+ Q_D(const QQuickWebEngineDownloadItem);
+ return d->mimeType;
+}
+
+/*!
\qmlproperty QString WebEngineDownloadItem::path
Holds the full target path where data is being downloaded to.
@@ -227,7 +239,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/qquickwebenginedownloaditem_p.h b/src/webengine/api/qquickwebenginedownloaditem_p.h
index 9a30eb4ca..124cea1a5 100644
--- a/src/webengine/api/qquickwebenginedownloaditem_p.h
+++ b/src/webengine/api/qquickwebenginedownloaditem_p.h
@@ -69,12 +69,13 @@ public:
DownloadCancelled,
DownloadInterrupted
};
- Q_ENUMS(DownloadState)
+ Q_ENUM(DownloadState)
Q_PROPERTY(quint32 id READ id CONSTANT FINAL)
Q_PROPERTY(DownloadState state READ state NOTIFY stateChanged)
Q_PROPERTY(qint64 totalBytes READ totalBytes NOTIFY totalBytesChanged)
Q_PROPERTY(qint64 receivedBytes READ receivedBytes NOTIFY receivedBytesChanged)
+ Q_PROPERTY(QString mimeType READ mimeType NOTIFY mimeTypeChanged REVISION 1)
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
Q_INVOKABLE void accept();
@@ -84,6 +85,7 @@ public:
DownloadState state() const;
qint64 totalBytes() const;
qint64 receivedBytes() const;
+ QString mimeType() const;
QString path() const;
void setPath(QString path);
@@ -91,6 +93,7 @@ Q_SIGNALS:
void stateChanged();
void receivedBytesChanged();
void totalBytesChanged();
+ void mimeTypeChanged();
void pathChanged();
private:
diff --git a/src/webengine/api/qquickwebenginedownloaditem_p_p.h b/src/webengine/api/qquickwebenginedownloaditem_p_p.h
index 230f322b5..8e502c736 100644
--- a/src/webengine/api/qquickwebenginedownloaditem_p_p.h
+++ b/src/webengine/api/qquickwebenginedownloaditem_p_p.h
@@ -50,7 +50,7 @@
#include "browser_context_adapter_client.h"
#include "qquickwebenginedownloaditem_p.h"
-#include "qquickwebengineprofile_p.h"
+#include "qquickwebengineprofile.h"
#include <private/qtwebengineglobal_p.h>
#include <QString>
#include <QPointer>
@@ -71,6 +71,7 @@ public:
QQuickWebEngineDownloadItem::DownloadState downloadState;
qint64 totalBytes;
qint64 receivedBytes;
+ QString mimeType;
QString downloadPath;
void update(const QtWebEngineCore::BrowserContextAdapterClient::DownloadItemInfo &info);
diff --git a/src/webengine/api/qquickwebenginehistory.cpp b/src/webengine/api/qquickwebenginehistory.cpp
index 9a737fbbe..d56dbc7a7 100644
--- a/src/webengine/api/qquickwebenginehistory.cpp
+++ b/src/webengine/api/qquickwebenginehistory.cpp
@@ -54,7 +54,7 @@ QQuickWebEngineHistoryListModelPrivate::~QQuickWebEngineHistoryListModelPrivate(
int QQuickWebEngineHistoryListModelPrivate::count() const
{
if (!adapter())
- return -1;
+ return 0;
return adapter()->navigationEntryCount();
}
@@ -65,6 +65,8 @@ int QQuickWebEngineHistoryListModelPrivate::index(int index) const
int QQuickWebEngineHistoryListModelPrivate::offsetForIndex(int index) const
{
+ if (!adapter())
+ return index;
return index - adapter()->currentNavigationEntryIndex();
}
@@ -81,7 +83,7 @@ QQuickWebEngineBackHistoryListModelPrivate::QQuickWebEngineBackHistoryListModelP
int QQuickWebEngineBackHistoryListModelPrivate::count() const
{
if (!adapter())
- return -1;
+ return 0;
return adapter()->currentNavigationEntryIndex();
}
@@ -104,12 +106,14 @@ QQuickWebEngineForwardHistoryListModelPrivate::QQuickWebEngineForwardHistoryList
int QQuickWebEngineForwardHistoryListModelPrivate::count() const
{
if (!adapter())
- return -1;
+ return 0;
return adapter()->navigationEntryCount() - adapter()->currentNavigationEntryIndex() - 1;
}
int QQuickWebEngineForwardHistoryListModelPrivate::index(int i) const
{
+ if (!adapter())
+ return i + 1;
return adapter()->currentNavigationEntryIndex() + i + 1;
}
@@ -118,6 +122,26 @@ int QQuickWebEngineForwardHistoryListModelPrivate::offsetForIndex(int index) con
return index + 1;
}
+/*!
+ \qmltype WebEngineHistoryListModel
+ \instantiates QQuickWebEngineHistoryListModel
+ \inqmlmodule QtWebEngine
+ \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 +209,67 @@ QQuickWebEngineHistoryPrivate::~QQuickWebEngineHistoryPrivate()
{
}
+/*!
+ \qmltype WebEngineHistory
+ \instantiates QQuickWebEngineHistory
+ \inqmlmodule QtWebEngine
+ \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 +279,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 +294,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 +309,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/qquickwebengineloadrequest.cpp b/src/webengine/api/qquickwebengineloadrequest.cpp
index e94fa7eb9..e39d7b4d1 100644
--- a/src/webengine/api/qquickwebengineloadrequest.cpp
+++ b/src/webengine/api/qquickwebengineloadrequest.cpp
@@ -59,7 +59,7 @@ public:
/*!
\qmltype WebEngineLoadRequest
\instantiates QQuickWebEngineLoadRequest
- \inqmlmodule QtWebEngine 1.0
+ \inqmlmodule QtWebEngine
\since QtWebEngine 1.0
\brief A utility type for the WebEngineView::loadingChanged signal.
diff --git a/src/webengine/api/qquickwebenginenewviewrequest.cpp b/src/webengine/api/qquickwebenginenewviewrequest.cpp
index f66a44e5f..74729ddf1 100644
--- a/src/webengine/api/qquickwebenginenewviewrequest.cpp
+++ b/src/webengine/api/qquickwebenginenewviewrequest.cpp
@@ -42,7 +42,7 @@
/*!
\qmltype WebEngineNewViewRequest
\instantiates QQuickWebEngineNewViewRequest
- \inqmlmodule QtWebEngine 1.1
+ \inqmlmodule QtWebEngine
\since QtWebEngine 1.1
\brief A utility type for the WebEngineView::newViewRequested signal.
@@ -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..27457729f 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -34,12 +34,13 @@
**
****************************************************************************/
-#include "qquickwebengineprofile_p.h"
+#include "qquickwebengineprofile.h"
#include "qquickwebenginedownloaditem_p.h"
#include "qquickwebenginedownloaditem_p_p.h"
-#include "qquickwebengineprofile_p_p.h"
+#include "qquickwebengineprofile_p.h"
#include "qquickwebenginesettings_p.h"
+#include "qwebenginecookiestore.h"
#include <QQmlEngine>
@@ -50,12 +51,77 @@ using QtWebEngineCore::BrowserContextAdapter;
QT_BEGIN_NAMESPACE
+
+/*!
+ \class QQuickWebEngineProfile
+ \brief The QQuickWebEngineProfile class provides a web-engine profile shared by multiple pages.
+ \since 5.6
+
+ \inmodule QtWebEngine
+
+ QQuickWebEngineProfile 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.
+
+ The default profile is a built-in profile that all web pages not specifically created with
+ another profile belong to.
+*/
+
+/*!
+ \enum QQuickWebEngineProfile::HttpCacheType
+
+ This enum describes the HTTP cache type:
+
+ \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 QQuickWebEngineProfile::PersistentCookiesPolicy
+
+ 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 \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.
+*/
+
+/*!
+ \fn QQuickWebEngineProfile::downloadRequested(QQuickWebEngineDownloadItem *download)
+
+ This signal is emitted whenever a download has been triggered.
+ The \a download argument holds the state of the download.
+ The download has to be explicitly accepted with
+ \c{QQuickWebEngineDownloadItem::accept()} or it will be
+ cancelled by default.
+ The download item is parented by the profile. If it is not accepted, it
+ will be deleted immediately after the signal emission.
+ This signal cannot be used with a queued connection.
+*/
+
+/*!
+ \fn QQuickWebEngineProfile::downloadFinished(QQuickWebEngineDownloadItem *download)
+
+ This signal is emitted whenever downloading stops, because it finished successfully, was
+ cancelled, or was interrupted (for example, because connectivity was lost).
+ The \a download argument holds the state of the finished download instance.
+*/
+
QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(BrowserContextAdapter* browserContext)
: m_settings(new QQuickWebEngineSettings())
, m_browserContextRef(browserContext)
{
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()
@@ -89,6 +155,7 @@ void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
itemPrivate->downloadId = info.id;
itemPrivate->downloadState = QQuickWebEngineDownloadItem::DownloadRequested;
itemPrivate->totalBytes = info.totalBytes;
+ itemPrivate->mimeType = info.mimeType;
itemPrivate->downloadPath = info.path;
QQuickWebEngineDownloadItem *download = new QQuickWebEngineDownloadItem(itemPrivate, q);
@@ -129,12 +196,13 @@ void QQuickWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info
/*!
\qmltype WebEngineProfile
\instantiates QQuickWebEngineProfile
- \inqmlmodule QtWebEngine 1.1
+ \inqmlmodule QtWebEngine
\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.
@@ -157,9 +225,15 @@ void QQuickWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info
The \a download argument holds the state of the finished download instance.
*/
-QQuickWebEngineProfile::QQuickWebEngineProfile()
- : d_ptr(new QQuickWebEngineProfilePrivate(new BrowserContextAdapter(false)))
+/*!
+ Constructs a new profile with the parent \a parent.
+*/
+QQuickWebEngineProfile::QQuickWebEngineProfile(QObject *parent)
+ : QObject(parent),
+ d_ptr(new QQuickWebEngineProfilePrivate(new BrowserContextAdapter(false)))
{
+ // Sets up the global WebEngineContext
+ QQuickWebEngineProfile::defaultProfile();
d_ptr->q_ptr = this;
}
@@ -170,6 +244,9 @@ QQuickWebEngineProfile::QQuickWebEngineProfile(QQuickWebEngineProfilePrivate *pr
d_ptr->q_ptr = this;
}
+/*!
+ \internal
+*/
QQuickWebEngineProfile::~QQuickWebEngineProfile()
{
}
@@ -183,6 +260,15 @@ QQuickWebEngineProfile::~QQuickWebEngineProfile()
\sa WebEngineProfile::persistentStoragePath, WebEngineProfile::cachePath
*/
+/*!
+ \property QQuickWebEngineProfile::storageName
+
+ The storage name that is used to create separate subdirectories for each profile that uses
+ the disk for storing persistent data and cache.
+
+ \sa QQuickWebEngineProfile::persistentStoragePath, QQuickWebEngineProfile::cachePath
+*/
+
QString QQuickWebEngineProfile::storageName() const
{
const Q_D(QQuickWebEngineProfile);
@@ -213,6 +299,16 @@ void QQuickWebEngineProfile::setStorageName(const QString &name)
An off-the-record profile forces cookies, the HTTP cache, and other normally persistent data
to be stored only in memory.
*/
+
+
+/*!
+ \property QQuickWebEngineProfile::offTheRecord
+
+ Whether the web engine profile is \e off-the-record.
+ An off-the-record profile forces cookies, the HTTP cache, and other normally persistent data
+ to be stored only in memory.
+*/
+
bool QQuickWebEngineProfile::isOffTheRecord() const
{
const Q_D(QQuickWebEngineProfile);
@@ -244,6 +340,18 @@ void QQuickWebEngineProfile::setOffTheRecord(bool offTheRecord)
QStandardPaths::writableLocation(QStandardPaths::DataLocation) in a directory named using
storageName.
*/
+
+/*!
+ \property QQuickWebEngineProfile::persistentStoragePath
+
+ The path to the location where the persistent data for the browser and web content are
+ stored. Persistent data includes persistent cookies, HTML5 local storage, and visited links.
+
+ By default, the storage is located below
+ QStandardPaths::writableLocation(QStandardPaths::DataLocation) in a directory named using
+ storageName.
+*/
+
QString QQuickWebEngineProfile::persistentStoragePath() const
{
const Q_D(QQuickWebEngineProfile);
@@ -268,6 +376,17 @@ void QQuickWebEngineProfile::setPersistentStoragePath(const QString &path)
below QStandardPaths::writableLocation(QStandardPaths::CacheLocation) in a directory named using
storageName.
*/
+
+/*!
+ \property QQuickWebEngineProfile::cachePath
+
+ The path to the location where the profile's caches are stored, in particular the HTTP cache.
+
+ By default, the caches are stored
+ below QStandardPaths::writableLocation(QStandardPaths::CacheLocation) in a directory named using
+ storageName.
+*/
+
QString QQuickWebEngineProfile::cachePath() const
{
const Q_D(QQuickWebEngineProfile);
@@ -288,6 +407,13 @@ void QQuickWebEngineProfile::setCachePath(const QString &path)
The user-agent string sent with HTTP to identify the browser.
*/
+
+/*!
+ \property QQuickWebEngineProfile::httpUserAgent
+
+ The user-agent string sent with HTTP to identify the browser.
+*/
+
QString QQuickWebEngineProfile::httpUserAgent() const
{
const Q_D(QQuickWebEngineProfile);
@@ -316,6 +442,14 @@ void QQuickWebEngineProfile::setHttpUserAgent(const QString &userAgent)
Uses a disk cache. This is the default value.
*/
+/*!
+ \property QQuickWebEngineProfile::httpCacheType
+
+ This enumeration describes the type of the HTTP cache.
+
+ If the profile is off-the-record, MemoryHttpCache is returned.
+*/
+
QQuickWebEngineProfile::HttpCacheType QQuickWebEngineProfile::httpCacheType() const
{
const Q_D(QQuickWebEngineProfile);
@@ -346,6 +480,13 @@ void QQuickWebEngineProfile::setHttpCacheType(QQuickWebEngineProfile::HttpCacheT
Both session and persistent cookies are saved to and restored from disk.
*/
+/*!
+ \property QQuickWebEngineProfile::persistentCookiesPolicy
+
+ This enumeration describes the policy of cookie persistency.
+ If the profile is off-the-record, NoPersistentCookies is returned.
+*/
+
QQuickWebEngineProfile::PersistentCookiesPolicy QQuickWebEngineProfile::persistentCookiesPolicy() const
{
const Q_D(QQuickWebEngineProfile);
@@ -369,6 +510,16 @@ void QQuickWebEngineProfile::setPersistentCookiesPolicy(QQuickWebEngineProfile::
\sa httpCacheType
*/
+
+/*!
+ \property QQuickWebEngineProfile::httpCacheMaximumSize
+
+ The maximum size of the HTTP cache. If \c 0, the size will be controlled automatically by
+ QtWebEngine. The default value is \c 0.
+
+ \sa httpCacheType
+*/
+
int QQuickWebEngineProfile::httpCacheMaximumSize() const
{
const Q_D(QQuickWebEngineProfile);
@@ -384,6 +535,42 @@ 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
+*/
+
+/*!
+ \property QQuickWebEngineProfile::httpAcceptLanguage
+
+ The value of the Accept-Language HTTP request-header field.
+*/
+
+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();
+}
+
+/*!
+ Returns the default profile.
+
+ The default profile uses the storage name "Default".
+
+ \sa storageName()
+*/
QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile()
{
static QQuickWebEngineProfile *profile = new QQuickWebEngineProfile(
@@ -392,6 +579,113 @@ QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile()
return profile;
}
+/*!
+ Returns the cookie store singleton, if one has been set.
+*/
+QWebEngineCookieStore *QQuickWebEngineProfile::cookieStore() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return d->browserContext()->cookieStore();
+}
+
+/*!
+ Registers a request interceptor singleton \a interceptor to intercept URL requests.
+
+ The profile does not take ownership of the pointer.
+
+ \sa QWebEngineUrlRequestInterceptor
+*/
+void QQuickWebEngineProfile::setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
+{
+ Q_D(QQuickWebEngineProfile);
+ d->browserContext()->setRequestInterceptor(interceptor);
+}
+
+/*!
+ Returns the custom URL scheme handler register for the URL scheme \a scheme.
+*/
+const QWebEngineUrlSchemeHandler *QQuickWebEngineProfile::urlSchemeHandler(const QByteArray &scheme) const
+{
+ const Q_D(QQuickWebEngineProfile);
+ if (d->browserContext()->customUrlSchemeHandlers().contains(scheme))
+ return d->browserContext()->customUrlSchemeHandlers().value(scheme);
+ return 0;
+}
+
+static bool checkInternalScheme(const QByteArray &scheme)
+{
+ static QSet<QByteArray> internalSchemes;
+ if (internalSchemes.isEmpty()) {
+ internalSchemes << QByteArrayLiteral("qrc") << QByteArrayLiteral("data") << QByteArrayLiteral("blob")
+ << QByteArrayLiteral("http") << QByteArrayLiteral("ftp") << QByteArrayLiteral("javascript");
+ }
+ return internalSchemes.contains(scheme);
+}
+
+/*!
+ Registers a handler \a handler for custom URL scheme \a scheme in the profile.
+*/
+void QQuickWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
+{
+ Q_D(QQuickWebEngineProfile);
+ Q_ASSERT(handler);
+ if (checkInternalScheme(scheme)) {
+ qWarning("Cannot install a URL scheme handler overriding internal scheme: %s", scheme.constData());
+ return;
+ }
+
+ 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;
+ }
+ d->browserContext()->addCustomUrlSchemeHandler(scheme, handler);
+ connect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
+}
+
+/*!
+ Removes the custom URL scheme handler \a handler from the profile.
+
+ \sa removeUrlScheme()
+*/
+void QQuickWebEngineProfile::removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
+{
+ Q_D(QQuickWebEngineProfile);
+ Q_ASSERT(handler);
+ if (!d->browserContext()->removeCustomUrlSchemeHandler(handler))
+ return;
+ disconnect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
+}
+
+/*!
+ Removes the custom URL scheme \a scheme from the profile.
+
+ \sa removeUrlSchemeHandler()
+*/
+void QQuickWebEngineProfile::removeUrlScheme(const QByteArray &scheme)
+{
+ Q_D(QQuickWebEngineProfile);
+ QWebEngineUrlSchemeHandler *handler = d->browserContext()->takeCustomUrlSchemeHandler(scheme);
+ if (!handler)
+ return;
+ disconnect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
+}
+
+/*!
+ Removes all custom URL scheme handlers installed in the profile.
+*/
+void QQuickWebEngineProfile::removeAllUrlSchemeHandlers()
+{
+ Q_D(QQuickWebEngineProfile);
+ d->browserContext()->customUrlSchemeHandlers().clear();
+ d->browserContext()->updateCustomUrlSchemeHandlers();
+}
+
+void QQuickWebEngineProfile::destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler *obj)
+{
+ removeUrlSchemeHandler(obj);
+}
+
QQuickWebEngineSettings *QQuickWebEngineProfile::settings() const
{
const Q_D(QQuickWebEngineProfile);
diff --git a/src/webengine/api/qquickwebengineprofile.h b/src/webengine/api/qquickwebengineprofile.h
new file mode 100644
index 000000000..1850f52fa
--- /dev/null
+++ b/src/webengine/api/qquickwebengineprofile.h
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** 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 QQUICKWEBENGINEPROFILE_H
+#define QQUICKWEBENGINEPROFILE_H
+
+
+#include <QtWebEngine/qtwebengineglobal.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QScopedPointer>
+#include <QtCore/QString>
+
+namespace QtWebEngineCore {
+class BrowserContextAdapter;
+}
+
+QT_BEGIN_NAMESPACE
+
+class QQuickWebEngineDownloadItem;
+class QQuickWebEngineProfilePrivate;
+class QQuickWebEngineSettings;
+class QWebEngineCookieStore;
+class QWebEngineUrlRequestInterceptor;
+class QWebEngineUrlSchemeHandler;
+
+class Q_WEBENGINE_EXPORT QQuickWebEngineProfile : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(QString storageName READ storageName WRITE setStorageName NOTIFY storageNameChanged FINAL)
+ Q_PROPERTY(bool offTheRecord READ isOffTheRecord WRITE setOffTheRecord NOTIFY offTheRecordChanged FINAL)
+ Q_PROPERTY(QString persistentStoragePath READ persistentStoragePath WRITE setPersistentStoragePath NOTIFY persistentStoragePathChanged FINAL)
+ 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:
+ QQuickWebEngineProfile(QObject *parent = Q_NULLPTR);
+ ~QQuickWebEngineProfile();
+
+ enum HttpCacheType {
+ MemoryHttpCache,
+ DiskHttpCache
+ };
+ Q_ENUM(HttpCacheType)
+
+ enum PersistentCookiesPolicy {
+ NoPersistentCookies,
+ AllowPersistentCookies,
+ ForcePersistentCookies
+ };
+ Q_ENUM(PersistentCookiesPolicy)
+
+ QString storageName() const;
+ void setStorageName(const QString &name);
+
+ bool isOffTheRecord() const;
+ void setOffTheRecord(bool offTheRecord);
+
+ QString persistentStoragePath() const;
+ void setPersistentStoragePath(const QString &path);
+
+ QString cachePath() const;
+ void setCachePath(const QString &path);
+
+ QString httpUserAgent() const;
+ void setHttpUserAgent(const QString &userAgent);
+
+ HttpCacheType httpCacheType() const;
+ void setHttpCacheType(QQuickWebEngineProfile::HttpCacheType);
+
+ PersistentCookiesPolicy persistentCookiesPolicy() const;
+ void setPersistentCookiesPolicy(QQuickWebEngineProfile::PersistentCookiesPolicy);
+
+ int httpCacheMaximumSize() const;
+ void setHttpCacheMaximumSize(int maxSize);
+
+ QString httpAcceptLanguage() const;
+ void setHttpAcceptLanguage(const QString &httpAcceptLanguage);
+
+ QWebEngineCookieStore *cookieStore() const;
+
+ void setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
+
+ const QWebEngineUrlSchemeHandler *urlSchemeHandler(const QByteArray &) const;
+ void installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *);
+ void removeUrlScheme(const QByteArray &scheme);
+ void removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *);
+ void removeAllUrlSchemeHandlers();
+
+ static QQuickWebEngineProfile *defaultProfile();
+
+Q_SIGNALS:
+ void storageNameChanged();
+ void offTheRecordChanged();
+ void persistentStoragePathChanged();
+ void cachePathChanged();
+ void httpUserAgentChanged();
+ void httpCacheTypeChanged();
+ void persistentCookiesPolicyChanged();
+ void httpCacheMaximumSizeChanged();
+ Q_REVISION(1) void httpAcceptLanguageChanged();
+
+ void downloadRequested(QQuickWebEngineDownloadItem *download);
+ void downloadFinished(QQuickWebEngineDownloadItem *download);
+
+private Q_SLOTS:
+ void destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler *obj);
+
+private:
+ Q_DECLARE_PRIVATE(QQuickWebEngineProfile)
+ QQuickWebEngineProfile(QQuickWebEngineProfilePrivate *, QObject *parent = 0);
+ QQuickWebEngineSettings *settings() const;
+
+ friend class QQuickWebEngineSettings;
+ friend class QQuickWebEngineSingleton;
+ friend class QQuickWebEngineViewPrivate;
+ friend class QQuickWebEngineDownloadItem;
+ friend class QQuickWebEngineDownloadItemPrivate;
+ QScopedPointer<QQuickWebEngineProfilePrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKWEBENGINEPROFILE_H
diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h
index 323721bd0..8fb56a616 100644
--- a/src/webengine/api/qquickwebengineprofile_p.h
+++ b/src/webengine/api/qquickwebengineprofile_p.h
@@ -48,99 +48,40 @@
// We mean it.
//
-#include <private/qtwebengineglobal_p.h>
+#include "browser_context_adapter_client.h"
+#include "qquickwebengineprofile_p.h"
+#include "browser_context_adapter.h"
-#include <QObject>
-#include <QScopedPointer>
-#include <QString>
-
-namespace QtWebEngineCore {
-class BrowserContextAdapter;
-}
+#include <QExplicitlySharedDataPointer>
+#include <QMap>
+#include <QPointer>
QT_BEGIN_NAMESPACE
class QQuickWebEngineDownloadItem;
-class QQuickWebEngineProfilePrivate;
class QQuickWebEngineSettings;
-class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineProfile : public QObject {
- Q_OBJECT
- Q_ENUMS(HttpCacheType);
- Q_ENUMS(PersistentCookiesPolicy);
- Q_PROPERTY(QString storageName READ storageName WRITE setStorageName NOTIFY storageNameChanged FINAL)
- Q_PROPERTY(bool offTheRecord READ isOffTheRecord WRITE setOffTheRecord NOTIFY offTheRecordChanged FINAL)
- Q_PROPERTY(QString persistentStoragePath READ persistentStoragePath WRITE setPersistentStoragePath NOTIFY persistentStoragePathChanged FINAL)
- 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(PersistentCookiesPolicy persistentCookiesPolicy READ persistentCookiesPolicy WRITE setPersistentCookiesPolicy NOTIFY persistentCookiesPolicyChanged FINAL)
- Q_PROPERTY(int httpCacheMaximumSize READ httpCacheMaximumSize WRITE setHttpCacheMaximumSize NOTIFY httpCacheMaximumSizeChanged FINAL)
+class QQuickWebEngineProfilePrivate : public QtWebEngineCore::BrowserContextAdapterClient {
public:
- QQuickWebEngineProfile();
- ~QQuickWebEngineProfile();
-
- enum HttpCacheType {
- MemoryHttpCache,
- DiskHttpCache
- };
-
- enum PersistentCookiesPolicy {
- NoPersistentCookies,
- AllowPersistentCookies,
- ForcePersistentCookies
- };
-
- QString storageName() const;
- void setStorageName(const QString &name);
-
- bool isOffTheRecord() const;
- void setOffTheRecord(bool offTheRecord);
-
- QString persistentStoragePath() const;
- void setPersistentStoragePath(const QString &path);
+ Q_DECLARE_PUBLIC(QQuickWebEngineProfile)
+ QQuickWebEngineProfilePrivate(QtWebEngineCore::BrowserContextAdapter* browserContext);
+ ~QQuickWebEngineProfilePrivate();
- QString cachePath() const;
- void setCachePath(const QString &path);
+ QtWebEngineCore::BrowserContextAdapter *browserContext() const { return m_browserContextRef.data(); }
+ QQuickWebEngineSettings *settings() const { return m_settings.data(); }
- QString httpUserAgent() const;
- void setHttpUserAgent(const QString &userAgent);
+ void cancelDownload(quint32 downloadId);
+ void downloadDestroyed(quint32 downloadId);
- HttpCacheType httpCacheType() const;
- void setHttpCacheType(QQuickWebEngineProfile::HttpCacheType);
-
- PersistentCookiesPolicy persistentCookiesPolicy() const;
- void setPersistentCookiesPolicy(QQuickWebEngineProfile::PersistentCookiesPolicy);
-
- int httpCacheMaximumSize() const;
- void setHttpCacheMaximumSize(int maxSize);
-
- static QQuickWebEngineProfile *defaultProfile();
-
-signals:
- void storageNameChanged();
- void offTheRecordChanged();
- void persistentStoragePathChanged();
- void cachePathChanged();
- void httpUserAgentChanged();
- void httpCacheTypeChanged();
- void persistentCookiesPolicyChanged();
- void httpCacheMaximumSizeChanged();
-
- void downloadRequested(QQuickWebEngineDownloadItem *download);
- void downloadFinished(QQuickWebEngineDownloadItem *download);
+ void downloadRequested(DownloadItemInfo &info) Q_DECL_OVERRIDE;
+ void downloadUpdated(const DownloadItemInfo &info) Q_DECL_OVERRIDE;
private:
- Q_DECLARE_PRIVATE(QQuickWebEngineProfile)
- QQuickWebEngineProfile(QQuickWebEngineProfilePrivate *, QObject *parent = 0);
- QQuickWebEngineSettings *settings() const;
-
- friend class QQuickWebEngineSettings;
- friend class QQuickWebEngineSingleton;
friend class QQuickWebEngineViewPrivate;
- friend class QQuickWebEngineDownloadItem;
- friend class QQuickWebEngineDownloadItemPrivate;
- QScopedPointer<QQuickWebEngineProfilePrivate> d_ptr;
+ QQuickWebEngineProfile *q_ptr;
+ QScopedPointer<QQuickWebEngineSettings> m_settings;
+ QExplicitlySharedDataPointer<QtWebEngineCore::BrowserContextAdapter> m_browserContextRef;
+ QMap<quint32, QPointer<QQuickWebEngineDownloadItem> > m_ongoingDownloads;
};
QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebenginescript.cpp b/src/webengine/api/qquickwebenginescript.cpp
index 7a545e456..68ea491b3 100644
--- a/src/webengine/api/qquickwebenginescript.cpp
+++ b/src/webengine/api/qquickwebenginescript.cpp
@@ -40,7 +40,6 @@
#include <QQmlFile>
#include <QtCore/QDebug>
#include <QtCore/QFile>
-#include <QtCore/QStringBuilder>
#include <QtCore/QTimerEvent>
#include "user_script_controller_host.h"
diff --git a/src/webengine/api/qquickwebenginescript_p.h b/src/webengine/api/qquickwebenginescript_p.h
index de91134ef..c9d6f5d26 100644
--- a/src/webengine/api/qquickwebenginescript_p.h
+++ b/src/webengine/api/qquickwebenginescript_p.h
@@ -59,8 +59,6 @@ class QQuickWebEngineView;
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineScript : public QObject
{
Q_OBJECT
- Q_ENUMS(InjectionPoint)
- Q_ENUMS(ScriptWorldId)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QUrl sourceUrl READ sourceUrl WRITE setSourceUrl NOTIFY sourceUrlChanged)
Q_PROPERTY(QString sourceCode READ sourceCode WRITE setSourceCode NOTIFY sourceCodeChanged)
@@ -75,12 +73,14 @@ public:
DocumentReady,
DocumentCreation
};
+ Q_ENUM(InjectionPoint)
enum ScriptWorldId {
MainWorld = 0,
ApplicationWorld,
UserWorld
};
+ Q_ENUM(ScriptWorldId)
QQuickWebEngineScript();
~QQuickWebEngineScript();
diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp
index 248713543..fe421993a 100644
--- a/src/webengine/api/qquickwebenginesettings.cpp
+++ b/src/webengine/api/qquickwebenginesettings.cpp
@@ -36,9 +36,9 @@
#include "qquickwebenginesettings_p.h"
-#include "qquickwebengineprofile_p.h"
#include "web_engine_settings.h"
+#include <QtWebEngine/QQuickWebEngineProfile>
#include <QtCore/QList>
QT_BEGIN_NAMESPACE
@@ -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..f0f5969c2 100644
--- a/src/webengine/api/qquickwebenginesingleton.cpp
+++ b/src/webengine/api/qquickwebenginesingleton.cpp
@@ -37,15 +37,51 @@
#include "qquickwebenginesingleton_p.h"
#include "qquickwebenginesettings_p.h"
-#include "qquickwebengineprofile_p.h"
+#include <QtWebEngine/QQuickWebEngineProfile>
QT_BEGIN_NAMESPACE
+/*!
+ \qmltype WebEngine
+ \instantiates QQuickWebEngineSingleton
+ \inqmlmodule QtWebEngine
+ \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.pluginsEnabled = 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 bb66d3db4..0cd356508 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"
@@ -46,7 +48,6 @@
#include "qquickwebenginenavigationrequest_p.h"
#include "qquickwebenginenewviewrequest_p.h"
#include "qquickwebengineprofile_p.h"
-#include "qquickwebengineprofile_p_p.h"
#include "qquickwebenginesettings_p.h"
#include "qquickwebenginescript_p_p.h"
@@ -63,15 +64,19 @@
#include "web_engine_settings.h"
#include "web_engine_visited_links_manager.h"
+#include <QClipboard>
#include <QGuiApplication>
+#include <QLoggingCategory>
+#include <QMimeData>
#include <QQmlComponent>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQmlProperty>
#include <QQmlWebChannel>
+#include <QQuickWebEngineProfile>
#include <QScreen>
-#include <QStringBuilder>
#include <QUrl>
+#include <QTimer>
#ifndef QT_NO_ACCESSIBILITY
#include <private/qquickaccessibleattached_p.h>
#endif // QT_NO_ACCESSIBILITY
@@ -100,10 +105,13 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
#endif
, contextMenuExtraItems(0)
, loadProgress(0)
- , m_isFullScreen(false)
+ , m_fullscreenMode(false)
, isLoading(false)
+ , m_activeFocusOnPress(true)
, devicePixelRatio(QGuiApplication::primaryScreen()->devicePixelRatio())
+ , m_webChannel(0)
, 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.
@@ -171,35 +179,107 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu
{
Q_Q(QQuickWebEngineView);
- QObject *menu = ui()->addMenu(0, QString(), data.pos);
+ // Assign the WebEngineView as the parent of the menu, so mouse events are properly propagated
+ // on OSX.
+ QObject *menu = ui()->addMenu(q, QString(), data.pos);
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 +331,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 +390,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);
@@ -428,25 +513,61 @@ bool QQuickWebEngineViewPrivate::isBeingAdopted()
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;
+ return m_fullscreenMode;
}
void QQuickWebEngineViewPrivate::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID)
{
Q_Q(QQuickWebEngineView);
- Q_EMIT q->javaScriptConsoleMessage(static_cast<QQuickWebEngineView::JavaScriptConsoleMessageLevel>(level), message, lineNumber, sourceID);
+ if (q->receivers(SIGNAL(javaScriptConsoleMessage(JavaScriptConsoleMessageLevel,QString,int,QString))) > 0) {
+ Q_EMIT q->javaScriptConsoleMessage(static_cast<QQuickWebEngineView::JavaScriptConsoleMessageLevel>(level), message, lineNumber, sourceID);
+ return;
+ }
+
+ static QLoggingCategory loggingCategory("js", QtWarningMsg);
+ const QByteArray file = sourceID.toUtf8();
+ QMessageLogger logger(file.constData(), lineNumber, nullptr, loggingCategory.categoryName());
+
+ switch (level) {
+ case JavaScriptConsoleMessageLevel::Info:
+ if (loggingCategory.isInfoEnabled())
+ logger.info().noquote() << message;
+ break;
+ case JavaScriptConsoleMessageLevel::Warning:
+ if (loggingCategory.isWarningEnabled())
+ logger.warning().noquote() << message;
+ break;
+ case JavaScriptConsoleMessageLevel::Error:
+ if (loggingCategory.isCriticalEnabled())
+ logger.critical().noquote() << message;
+ break;
+ }
+}
+
+void QQuickWebEngineViewPrivate::authenticationRequired(QSharedPointer<AuthenticationDialogController> controller)
+{
+ ui()->showDialog(controller);
}
void QQuickWebEngineViewPrivate::runMediaAccessPermissionRequest(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags requestFlags)
@@ -576,11 +697,6 @@ void QQuickWebEngineViewPrivate::adoptWebContents(WebContentsAdapter *webContent
Q_Q(QQuickWebEngineView);
- // memorize what webChannel we had for the previous adapter
- QQmlWebChannel *qmlWebChannel = NULL;
- if (adapter)
- qmlWebChannel = qobject_cast<QQmlWebChannel *>(adapter->webChannel());
-
// This throws away the WebContentsAdapter that has been used until now.
// All its states, particularly the loading URL, are replaced by the adopted WebContentsAdapter.
WebContentsAdapterOwner *adapterOwner = new WebContentsAdapterOwner(adapter);
@@ -589,8 +705,12 @@ void QQuickWebEngineViewPrivate::adoptWebContents(WebContentsAdapter *webContent
adapter->initialize(this);
// associate the webChannel with the new adapter
- if (qmlWebChannel)
- adapter->setWebChannel(qmlWebChannel);
+ if (m_webChannel)
+ adapter->setWebChannel(m_webChannel);
+
+ // set initial background color if non-default
+ if (m_backgroundColor != Qt::white)
+ adapter->backgroundColorChanged();
// re-bind the userscrips to the new adapter
Q_FOREACH (QQuickWebEngineScript *script, m_userScripts)
@@ -614,7 +734,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);
@@ -631,6 +751,10 @@ void QQuickWebEngineViewPrivate::ensureContentsAdapter()
if (!adapter) {
adapter = new WebContentsAdapter();
adapter->initialize(this);
+ if (m_backgroundColor != Qt::white)
+ adapter->backgroundColorChanged();
+ if (m_webChannel)
+ adapter->setWebChannel(m_webChannel);
if (explicitUrl.isValid())
adapter->load(explicitUrl);
// push down the page's user scripts
@@ -639,6 +763,16 @@ void QQuickWebEngineViewPrivate::ensureContentsAdapter()
}
}
+void QQuickWebEngineViewPrivate::setFullScreenMode(bool fullscreen)
+{
+ Q_Q(QQuickWebEngineView);
+ if (m_fullscreenMode != fullscreen) {
+ m_fullscreenMode = fullscreen;
+ adapter->changedFullScreen();
+ Q_EMIT q->isFullScreenChanged();
+ }
+}
+
QUrl QQuickWebEngineView::url() const
{
Q_D(const QQuickWebEngineView);
@@ -654,7 +788,7 @@ void QQuickWebEngineView::setUrl(const QUrl& url)
d->explicitUrl = url;
if (d->adapter)
d->adapter->load(url);
- if (!qmlEngine(this))
+ if (!qmlEngine(this) || isComponentComplete())
d->ensureContentsAdapter();
}
@@ -668,7 +802,7 @@ void QQuickWebEngineView::loadHtml(const QString &html, const QUrl &baseUrl)
{
Q_D(QQuickWebEngineView);
d->explicitUrl = QUrl();
- if (!qmlEngine(this))
+ if (!qmlEngine(this) || isComponentComplete())
d->ensureContentsAdapter();
if (d->adapter)
d->adapter->setContent(html.toUtf8(), QStringLiteral("text/html;charset=UTF-8"), baseUrl);
@@ -768,11 +902,8 @@ void QQuickWebEngineViewPrivate::setProfile(QQuickWebEngineProfile *profile)
if (adapter && adapter->browserContext() != browserContextAdapter()->browserContext()) {
// When the profile changes we need to create a new WebContentAdapter and reload the active URL.
QUrl activeUrl = adapter->activeUrl();
- QQmlWebChannel *qmlWebChannel = qobject_cast<QQmlWebChannel *>(adapter->webChannel());
adapter = 0;
ensureContentsAdapter();
- if (qmlWebChannel)
- adapter->setWebChannel(qmlWebChannel);
if (!explicitUrl.isValid() && activeUrl.isValid())
adapter->load(activeUrl);
@@ -791,8 +922,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);
@@ -811,6 +957,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);
}
@@ -824,6 +975,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);
@@ -863,8 +1022,7 @@ bool QQuickWebEngineView::canGoForward() const
void QQuickWebEngineView::runJavaScript(const QString &script, const QJSValue &callback)
{
Q_D(QQuickWebEngineView);
- if (!d->adapter)
- return;
+ d->ensureContentsAdapter();
if (!callback.isUndefined()) {
quint64 requestId = d_ptr->adapter->runJavaScriptCallbackResult(script);
d->m_callbacks.insert(requestId, callback);
@@ -886,11 +1044,39 @@ 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;
+ if (d->adapter)
+ d->adapter->backgroundColorChanged();
+ emit backgroundColorChanged();
+}
bool QQuickWebEngineView::isFullScreen() const
{
Q_D(const QQuickWebEngineView);
- return d->m_isFullScreen;
+ return d->m_fullscreenMode;
}
void QQuickWebEngineViewExperimental::setExtraContextMenuEntriesComponent(QQmlComponent *contextMenuExtras)
@@ -934,23 +1120,24 @@ QQuickWebEngineHistory *QQuickWebEngineView::navigationHistory() const
QQmlWebChannel *QQuickWebEngineView::webChannel()
{
Q_D(QQuickWebEngineView);
- d->ensureContentsAdapter();
- QQmlWebChannel *qmlWebChannel = qobject_cast<QQmlWebChannel *>(d->adapter->webChannel());
- Q_ASSERT(!d->adapter->webChannel() || qmlWebChannel);
- if (!qmlWebChannel) {
- qmlWebChannel = new QQmlWebChannel(this);
- d->adapter->setWebChannel(qmlWebChannel);
+ if (!d->m_webChannel) {
+ d->m_webChannel = new QQmlWebChannel(this);
+ if (d->adapter)
+ d->adapter->setWebChannel(d->m_webChannel);
}
- return qmlWebChannel;
+
+ return d->m_webChannel;
}
void QQuickWebEngineView::setWebChannel(QQmlWebChannel *webChannel)
{
Q_D(QQuickWebEngineView);
- bool notify = (d->adapter->webChannel() == webChannel);
- d->adapter->setWebChannel(webChannel);
- if (notify)
- Q_EMIT webChannelChanged();
+ if (d->m_webChannel == webChannel)
+ return;
+ d->m_webChannel = webChannel;
+ if (d->adapter)
+ d->adapter->setWebChannel(webChannel);
+ Q_EMIT webChannelChanged();
}
void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineView::Feature feature, bool granted)
@@ -980,6 +1167,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);
@@ -998,10 +1195,7 @@ void QQuickWebEngineView::goBackOrForward(int offset)
void QQuickWebEngineView::fullScreenCancelled()
{
Q_D(QQuickWebEngineView);
- if (d->m_isFullScreen) {
- d->m_isFullScreen = false;
- Q_EMIT isFullScreenChanged();
- }
+ d->adapter->exitFullScreen();
}
void QQuickWebEngineView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
@@ -1025,6 +1219,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);
@@ -1062,29 +1421,39 @@ void QQuickWebEngineViewPrivate::userScripts_clear(QQmlListProperty<QQuickWebEng
void QQuickWebEngineView::componentComplete()
{
- Q_D(QQuickWebEngineView);
QQuickItem::componentComplete();
+ QTimer::singleShot(0, this, &QQuickWebEngineView::lazyInitialize);
+}
+
+void QQuickWebEngineView::lazyInitialize()
+{
+ Q_D(QQuickWebEngineView);
d->ensureContentsAdapter();
}
QQuickWebEngineFullScreenRequest::QQuickWebEngineFullScreenRequest()
- : viewPrivate(0)
+ : m_viewPrivate(0)
, m_toggleOn(false)
{
}
-QQuickWebEngineFullScreenRequest::QQuickWebEngineFullScreenRequest(QQuickWebEngineViewPrivate *viewPrivate, bool toggleOn)
- : viewPrivate(viewPrivate)
+QQuickWebEngineFullScreenRequest::QQuickWebEngineFullScreenRequest(QQuickWebEngineViewPrivate *viewPrivate, const QUrl &origin, bool toggleOn)
+ : m_viewPrivate(viewPrivate)
+ , m_origin(origin)
, m_toggleOn(toggleOn)
{
}
void QQuickWebEngineFullScreenRequest::accept()
{
- if (viewPrivate && viewPrivate->m_isFullScreen != m_toggleOn) {
- viewPrivate->m_isFullScreen = m_toggleOn;
- Q_EMIT viewPrivate->q_ptr->isFullScreenChanged();
- }
+ if (m_viewPrivate)
+ m_viewPrivate->setFullScreenMode(m_toggleOn);
+}
+
+void QQuickWebEngineFullScreenRequest::reject()
+{
+ if (m_viewPrivate)
+ m_viewPrivate->setFullScreenMode(!m_toggleOn);
}
QQuickWebEngineViewExperimental::QQuickWebEngineViewExperimental(QQuickWebEngineViewPrivate *viewPrivate)
@@ -1126,5 +1495,3 @@ void QQuickWebEngineViewport::setDevicePixelRatio(qreal devicePixelRatio)
QT_END_NAMESPACE
-#include "moc_qquickwebengineview_p.cpp"
-#include "moc_qquickwebengineview_p_p.cpp"
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index f85bf64ad..98d0bbc1d 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;
+ QQuickWebEngineViewPrivate *m_viewPrivate;
+ 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,18 +106,13 @@ 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)
#endif
- Q_ENUMS(NavigationRequestAction);
- Q_ENUMS(NavigationType);
- Q_ENUMS(LoadStatus);
- Q_ENUMS(ErrorDomain);
- Q_ENUMS(NewViewDestination);
- Q_ENUMS(Feature);
- Q_ENUMS(JavaScriptConsoleMessageLevel);
Q_FLAGS(FindFlags);
public:
@@ -129,6 +130,8 @@ public:
bool isFullScreen() const;
qreal zoomFactor() const;
void setZoomFactor(qreal arg);
+ QColor backgroundColor() const;
+ void setBackgroundColor(const QColor &color);
QQuickWebEngineViewExperimental *experimental() const;
@@ -139,6 +142,7 @@ public:
// we can expose extra actions in experimental.
IgnoreRequest = 0xFF
};
+ Q_ENUM(NavigationRequestAction)
// must match WebContentsAdapterClient::NavigationType
enum NavigationType {
@@ -149,6 +153,7 @@ public:
ReloadNavigation,
OtherNavigation
};
+ Q_ENUM(NavigationType)
enum LoadStatus {
LoadStartedStatus,
@@ -156,6 +161,7 @@ public:
LoadSucceededStatus,
LoadFailedStatus
};
+ Q_ENUM(LoadStatus)
enum ErrorDomain {
NoErrorDomain,
@@ -166,6 +172,7 @@ public:
FtpErrorDomain,
DnsErrorDomain
};
+ Q_ENUM(ErrorDomain)
enum NewViewDestination {
NewViewInWindow,
@@ -173,6 +180,7 @@ public:
NewViewInDialog,
NewViewInBackgroundTab
};
+ Q_ENUM(NewViewDestination)
enum Feature {
MediaAudioCapture,
@@ -180,6 +188,50 @@ public:
MediaAudioVideoCapture,
Geolocation
};
+ Q_ENUM(Feature)
+
+ 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
+ };
+ Q_ENUM(WebAction)
// must match WebContentsAdapterClient::JavaScriptConsoleMessageLevel
enum JavaScriptConsoleMessageLevel {
@@ -187,6 +239,16 @@ public:
WarningMessageLevel,
ErrorMessageLevel
};
+ Q_ENUM(JavaScriptConsoleMessageLevel)
+
+ // must match WebContentsAdapterClient::RenderProcessTerminationStatus
+ enum RenderProcessTerminationStatus {
+ NormalTerminationStatus = 0,
+ AbnormalTerminationStatus,
+ CrashedTerminationStatus,
+ KilledTerminationStatus
+ };
+ Q_ENUM(RenderProcessTerminationStatus)
enum FindFlag {
FindBackward = 1,
@@ -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,11 @@ 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);
+
+private Q_SLOTS:
+ void lazyInitialize();
Q_SIGNALS:
void titleChanged();
@@ -241,7 +310,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 83a0ea744..dbbbf9168 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;
@@ -143,19 +144,20 @@ public:
virtual void adoptNewWindow(QtWebEngineCore::WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &) Q_DECL_OVERRIDE;
virtual bool isBeingAdopted() 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
@@ -167,6 +169,9 @@ 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 void requestGeometryChange(const QRect &geometry) Q_DECL_OVERRIDE { Q_UNUSED(geometry); }
virtual QtWebEngineCore::BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE;
@@ -174,6 +179,7 @@ public:
void adoptWebContents(QtWebEngineCore::WebContentsAdapter *webContents);
void setProfile(QQuickWebEngineProfile *profile);
void ensureContentsAdapter();
+ void setFullScreenMode(bool);
// QQmlListPropertyHelpers
static void userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script);
@@ -191,19 +197,23 @@ public:
QQuickWebEngineTestSupport *m_testSupport;
#endif
QQmlComponent *contextMenuExtraItems;
+ QtWebEngineCore::WebEngineContextMenuData contextMenuData;
QUrl explicitUrl;
QUrl icon;
int loadProgress;
- bool m_isFullScreen;
+ bool m_fullscreenMode;
bool isLoading;
+ bool m_activeFocusOnPress;
qreal devicePixelRatio;
QMap<quint64, QJSValue> m_callbacks;
QList<QSharedPointer<CertificateErrorController> > m_certificateErrorControllers;
+ QQmlWebChannel *m_webChannel;
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..8efbc3799 100644
--- a/src/webengine/api/qtwebengineglobal.cpp
+++ b/src/webengine/api/qtwebengineglobal.cpp
@@ -36,56 +36,38 @@
#include "qtwebengineglobal.h"
-#include <QGuiApplication>
-#include <QOpenGLContext>
-#include <QThread>
+namespace QtWebEngineCore
+{
+ extern void initialize();
+}
QT_BEGIN_NAMESPACE
-Q_GUI_EXPORT void qt_gl_set_global_share_context(QOpenGLContext *context);
-Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
-
namespace QtWebEngine {
-static QOpenGLContext *shareContext;
-
-static void deleteShareContext()
-{
- delete shareContext;
- shareContext = 0;
-}
+/*!
+ \namespace QtWebEngine
+ \inmodule QtWebEngine
+ \ingroup qtwebengine-namespaces
+ \keyword QtWebEngine Namespace
-// ### Qt 6: unify this logic and Qt::AA_ShareOpenGLContexts.
-// 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.
-void initialize()
-{
-#ifdef Q_OS_WIN32
- qputenv("QT_D3DCREATE_MULTITHREADED", "1");
-#endif
+ \brief Helper functions for the Qt WebEngine (Qt Quick) module
- // No need to override the shared context if QApplication already set one (e.g with Qt::AA_ShareOpenGLContexts).
- if (qt_gl_global_share_context())
- return;
+ The \l[CPP]{QtWebEngine} namespace is part of the Qt WebEngine module.
+*/
- QCoreApplication *app = QCoreApplication::instance();
- if (!app) {
- qFatal("QWebEngine(Widgets)::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.");
- return;
- }
+/*!
+ \fn QtWebEngine::initialize()
- if (shareContext)
- return;
+ 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.
- shareContext = new QOpenGLContext;
- shareContext->create();
- qAddPostRoutine(deleteShareContext);
- qt_gl_set_global_share_context(shareContext);
+ This has the same effect as passing Qt::AA_ShareOpenGLContexts to the QGuiApplication
+ constructor.
+*/
+void initialize()
+{
+ QtWebEngineCore::initialize();
}
} // 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..02f9a9ffd 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,55 @@ 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 \
+ qtnetwork \
+ 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..38d8b637b
--- /dev/null
+++ b/src/webengine/doc/src/external-resources.qdoc
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** 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
+*/
+
+/*!
+ \externalpage https://developers.google.com/web/tools/javascript/console/console-write
+ \title Chrome console API
+*/
+
+/*!
+ \externalpage http://ffmpeg.org/
+ \title FFmpeg
+*/
+
+/*!
+ \externalpage http://www.openh264.org/
+ \title OpenH264
+*/
+
+/*
+ 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-debugging.qdoc b/src/webengine/doc/src/qtwebengine-debugging.qdoc
new file mode 100644
index 000000000..bffcd1669
--- /dev/null
+++ b/src/webengine/doc/src/qtwebengine-debugging.qdoc
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** 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-debugging.html
+ \title Qt WebEngine Debugging and Profiling
+
+ \section1 Console Logging
+
+ JavaScript executed inside Qt WebEngine can use the
+ \l{Chrome console API} to log information to a console. The logging messages
+ are forwarded to Qt's logging facilities inside a \c js
+ \l{QLoggingCategory}{logging category}. However, only warning and fatal
+ messages are printed by default. To change this, you either have to set custom
+ rules for the \c js category, or provide custom message handlers
+ by reimplementing \l{QWebEnginePage::javaScriptConsoleMessage()}, or
+ connecting to \l{WebEngineView::javaScriptConsoleMessage()}.
+
+ All messages can also be accessed through the Qt WebEngine developer
+ tools.
+
+ \section1 Qt WebEngine 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..e30976ef3
--- /dev/null
+++ b/src/webengine/doc/src/qtwebengine-index.qdoc
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** 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 Articles and Guides
+
+ \list
+ \li \l{Qt WebEngine Overview}
+ \li \l{Qt WebEngine Platform Notes}
+ \li \l{Qt WebEngine Debugging and Profiling}
+ \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..451165b26
--- /dev/null
+++ b/src/webengine/doc/src/qtwebengine-modules.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$
+**
+****************************************************************************/
+
+/*!
+ \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}
+
+ \section2 Qt WebEngine Module
+ \generatelist {classesbymodule QtWebEngine}
+*/
diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc
new file mode 100644
index 000000000..53ff4b462
--- /dev/null
+++ b/src/webengine/doc/src/qtwebengine-overview.qdoc
@@ -0,0 +1,211 @@
+/****************************************************************************
+**
+** 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.
+
+ Please note that Qt WebEngine is based on Chromium, but does not contain or use any services
+ or add-ons that might be part of the Chrome browser that is built and delivered by Google.
+ You can find more detailed information about the differences between Chromium and Chrome in this
+ \l{https://chromium.googlesource.com/chromium/src/+/master/docs/chromium_browser_vs_google_chrome.md}{overview}
+ that is part of the documentation in the \l {Chromium Project} upstream source tree.
+
+ 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 Managing Certificates
+
+ Qt WebEngine uses its own network stack, and therefore QSslConfiguration is not used to
+ open SSL connections. Instead, Qt WebEngine uses the root CA certificates from the operating
+ system to validate the peer's certificate.
+
+ The \l{WebEngineCertificateError::error} and \l{QWebEngineCertificateError::Error} enumerations
+ provide information about the types of certificate errors that might occur. The errors can be
+ handled by using the WebEngineView::certificateError QML method or by reimplementing the
+ QWebEnginePage::certificateError function.
+
+ \section1 Proxy Support
+
+ If QNetworkProxy::applicationProxy is set, it will also be used for Qt WebEngine. Otherwise,
+ Qt WebEngine automatically picks up the proxy configuration from OS X and Windows. On Linux,
+ it acknowledges settings from KDE and Gnome.
+
+ If a proxy requires authentication, QWebEnginePage::proxyAuthenticationRequired is emitted.
+ For Qt Quick, a dialog is shown.
+
+ \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 QWebEngineCookieStore 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..3e30e9606
--- /dev/null
+++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** 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 on OS X 10.9 or later
+ \endlist
+
+ \section1 Pepper Plugin API Support
+
+ Qt WebEngine supports loading Pepper Plugin API (PPAPI) plugins. The plugins must be loaded
+ manually using the Chromium command line syntax with the \c --register-pepper-plugins argument.
+ The argument value is a list of entries, separated by commas, that contain the file path and
+ one or several MIME types, separated by semicolons:
+
+ \code
+ <file-path-plugin1>;<mime-type-plugin1>,<file-path-plugin2>;<mime-type1-plugin2>;<mime-type2-plugin2>
+ \endcode
+
+ For example:
+
+ \code
+ --register-pepper-plugins="libppapi_example.so;application/x-ppapi-example"
+ \endcode
+
+ The MIME type is important because it determines which embeds the plugin is used for.
+
+ This process has been automated for the Adobe Flash Player Plugin.
+
+ \section2 Adobe Flash Player Plugin Support
+
+ The Adobe Flash player plugin can be loaded automatically if it is installed in one of the
+ following locations, depending on the platform:
+
+ \list
+ \li Windows
+ \code
+ C:\Windows\SysWOW64\Macromed\Flash\pepflashplayer*.dll
+ C:\Windows\System32\Macromed\Flash\pepflashplayer*.dll
+ \endcode
+ \li OS X
+ \code
+ /Library/Internet Plug-Ins/PepperFlashPlayer/PepperFlashPlayer.plugin
+ \endcode
+ \li Linux
+ \code
+ /usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so
+ /usr/lib/PepperFlash/libpepflashplayer.so
+ /usr/lib64/chromium/PepperFlash/libpepflashplayer.so
+ \endcode
+ \endlist
+
+ You can also load the Flash player from a specific location by using command line arguments:
+
+ \code
+ --ppapi-flash-path=./libpepflashplayer.so
+ \endcode
+
+ \section1 Audio and Video Codec Support
+
+ Qt WebEngine supports the MPEG-4 Part 14 (MP4) file format only if the required proprietary
+ audio and video codecs, such as H.264 and MPEG layer-3 (MP3), have been enabled. Proprietary
+ codecs can be enabled by passing the following option to qmake:
+
+ \code
+ qmake WEBENGINE_CONFIG += use_proprietary_codecs
+ \endcode
+
+ \warning When distributing proprietary codec libraries, you must acquire licenses for them.
+
+ \l FFmpeg is a cross-platform solution to record, convert, and stream audio and video. It can
+ be configured for use with several codecs, which rises licensing issues during distribution
+ with the codec libraries. For some codecs, open source implementations, such as \l {OpenH264},
+ are available.
+*/
diff --git a/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc
new file mode 100644
index 000000000..7fcddb373
--- /dev/null
+++ b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc
@@ -0,0 +1,45 @@
+/*
+ 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.2
+ \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 QtWebEngine 1.2
+ \endcode
+
+ To link against the module, add the following QT variable to your qmake .pro
+ file:
+
+ \badcode
+ QT += webengine
+ \endcode
+*/
diff --git a/src/webengine/doc/src/qquickwebengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview.qdoc
index f9810aafd..9e03e1ed8 100644
--- a/src/webengine/doc/src/qquickwebengineview_lgpl.qdoc
+++ b/src/webengine/doc/src/webengineview.qdoc
@@ -24,57 +24,9 @@
// 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
+ \inqmlmodule QtWebEngine
\since QtWebEngine 1.0
\brief A WebEngineView renders web content within a QML application.
*/
@@ -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.
@@ -271,31 +225,38 @@
/*!
\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.
+
+ \warning Do not execute lengthy routines in the callback function, because it might block the
+ rendering of the web content.
+
+ See WebEngineView::userScripts for an alternative API to inject scripts.
*/
/*!
@@ -338,12 +299,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()
*/
@@ -354,7 +316,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)
@@ -363,30 +325,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
@@ -398,10 +381,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.
@@ -410,13 +390,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
*/
/*!
@@ -428,14 +405,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
*/
@@ -449,19 +426,23 @@
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. If no handler is specified,
+ the view will log the messages into a \c js \l{QLoggingCategory}{logging category}.
+
+ \sa{Console Logging}
*/
/*!
@@ -469,20 +450,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}
*/
/*!
@@ -492,15 +473,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
@@ -520,68 +540,42 @@
/*!
\qmlproperty enumeration WebEngineView::JavaScriptConsoleMessageLevel
- 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.
+ Indicates the severity of a JavaScript console message:
- \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
+ Reflects a page's load status:
- \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.
-
- \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
*/
@@ -589,39 +583,130 @@
/*!
\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()
*/
/*!
\qmltype WebEngineFullScreenRequest
\instantiates QQuickWebEngineFullScreenRequest
- \inqmlmodule QtWebEngine 1.1
+ \inqmlmodule QtWebEngine
\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()
*/
/*!
@@ -631,7 +716,7 @@
Returns \c{true} if the application should toggle fullscreen mode on, \c{false} otherwise.
- \sa WebEngineFullScreenRequest::accept()
+ \sa accept()
*/
/*!
@@ -639,9 +724,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 {
@@ -654,7 +739,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..ca4fb2e74 100644
--- a/src/webengine/plugin/plugin.cpp
+++ b/src/webengine/plugin/plugin.cpp
@@ -35,6 +35,7 @@
****************************************************************************/
#include <QtQml/qqmlextensionplugin.h>
+#include <QtWebEngine/QQuickWebEngineProfile>
#include "qquickwebenginecertificateerror_p.h"
#include "qquickwebenginedownloaditem_p.h"
@@ -42,7 +43,6 @@
#include "qquickwebengineloadrequest_p.h"
#include "qquickwebenginenavigationrequest_p.h"
#include "qquickwebenginenewviewrequest_p.h"
-#include "qquickwebengineprofile_p.h"
#include "qquickwebenginesettings_p.h"
#include "qquickwebenginesingleton_p.h"
#include "qquickwebengineview_p.h"
@@ -65,24 +65,32 @@ 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<QQuickWebEngineDownloadItem, 1>(uri, 1, 2, "WebEngineDownloadItem",
+ 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..4fce34a21 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: []
@@ -488,8 +488,10 @@ Module {
exports: ["QtWebEngine/FullScreenRequest 1.1"]
isCreatable: false
exportMetaObjectRevisions: [0]
+ Property { name: "origin"; type: "QUrl"; isReadonly: true }
Property { name: "toggleOn"; type: "bool"; isReadonly: true }
Method { name: "accept" }
+ Method { name: "reject" }
}
Component {
name: "QQuickWebEngineHistory"
@@ -571,8 +573,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 +599,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 +611,7 @@ Module {
name: "downloadFinished"
Parameter { name: "download"; type: "QQuickWebEngineDownloadItem"; isPointer: true }
}
+ Method { name: "cookieStore"; revision: 1; type: "QWebEngineCookieStore*" }
}
Component {
name: "QQuickWebEngineScript"
@@ -685,9 +693,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 +710,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 +737,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 +799,42 @@ 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,
+ "RequestClose": 28,
+ "WebActionCount": 29
+ }
+ }
+ Enum {
name: "JavaScriptConsoleMessageLevel"
values: {
"InfoMessageLevel": 0,
@@ -792,6 +843,15 @@ Module {
}
}
Enum {
+ name: "RenderProcessTerminationStatus"
+ values: {
+ "NormalTerminationStatus": 0,
+ "AbnormalTerminationStatus": 1,
+ "CrashedTerminationStatus": 2,
+ "KilledTerminationStatus": 3
+ }
+ }
+ Enum {
name: "FindFlags"
values: {
"FindBackward": 1,
@@ -830,6 +890,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 +940,19 @@ 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" }
+ }
+ Signal { name: "windowCloseRequested"; revision: 2 }
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..508420cf8 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);
}
@@ -261,10 +268,15 @@ void RenderWidgetHostViewQtDelegateQuick::itemChange(ItemChange change, const It
if (value.window) {
m_windowConnections.append(connect(value.window, SIGNAL(xChanged(int)), SLOT(onWindowPosChanged())));
m_windowConnections.append(connect(value.window, SIGNAL(yChanged(int)), SLOT(onWindowPosChanged())));
+ if (!m_isPopup)
+ m_windowConnections.append(connect(value.window, SIGNAL(closing(QQuickCloseEvent *)), SLOT(onHide())));
}
if (m_initialized)
m_client->windowChanged();
+ } else if (change == QQuickItem::ItemVisibleHasChanged) {
+ if (!m_isPopup && !value.boolValue)
+ onHide();
}
}
@@ -278,4 +290,10 @@ void RenderWidgetHostViewQtDelegateQuick::onWindowPosChanged()
m_client->windowBoundsChanged();
}
+void RenderWidgetHostViewQtDelegateQuick::onHide()
+{
+ QFocusEvent event(QEvent::FocusOut, Qt::OtherFocusReason);
+ m_client->forwardEvent(&event);
+}
+
} // namespace QtWebEngineCore
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..7c44da9b9 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;
@@ -90,6 +92,7 @@ protected:
private slots:
void onWindowPosChanged();
+ void onHide();
private:
RenderWidgetHostViewQtDelegateClient *m_client;
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..441235980
--- /dev/null
+++ b/src/webengine/ui/AuthenticationDialog.qml
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** 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 2.5
+import QtQuick.Controls 1.4
+import QtQuick.Layouts 1.0
+import QtQuick.Window 2.2
+
+Window {
+ signal accepted(string user, string password);
+ signal rejected;
+ property alias text: message.text
+
+ title: qsTr("Authentication Required")
+ flags: Qt.Dialog
+ modality: Qt.WindowModal
+
+ width: minimumWidth
+ height: minimumHeight
+ minimumWidth: rootLayout.implicitWidth + rootLayout.doubleMargins
+ minimumHeight: rootLayout.implicitHeight + rootLayout.doubleMargins
+
+ SystemPalette { id: palette; colorGroup: SystemPalette.Active }
+ color: palette.window
+
+ function open() {
+ show();
+ }
+
+ function acceptDialog() {
+ accepted(userField.text, passwordField.text);
+ close();
+ }
+
+ ColumnLayout {
+ id: rootLayout
+ anchors.fill: parent
+ anchors.margins: 4
+ property int doubleMargins: anchors.margins * 2
+ Text {
+ id: message;
+ color: palette.windowText
+ }
+ GridLayout {
+ columns: 2
+ Label {
+ text: qsTr("Username:")
+ color: palette.windowText
+ }
+ TextField {
+ id: userField
+ focus: true
+ Layout.fillWidth: true
+ onAccepted: acceptDialog()
+ }
+ Label {
+ text: qsTr("Password:")
+ color: palette.windowText
+ }
+ TextField {
+ id: passwordField
+ Layout.fillWidth: true
+ echoMode: TextInput.Password
+ onAccepted: acceptDialog()
+ }
+ }
+ Item {
+ Layout.fillHeight: true
+ }
+ RowLayout {
+ Layout.alignment: Qt.AlignRight
+ spacing: 8
+ Button {
+ id: cancelButton
+ text: qsTr("&Cancel")
+ onClicked: {
+ rejected();
+ close();
+ }
+ }
+ Button {
+ text: qsTr("&Log In")
+ isDefault: true
+ onClicked: acceptDialog()
+ }
+ }
+ }
+}
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..96b3e3a77 100644
--- a/src/webengine/ui_delegates_manager.cpp
+++ b/src/webengine/ui_delegates_manager.cpp
@@ -37,16 +37,17 @@
#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>
-#include <QStringBuilder>
// Uncomment for QML debugging
//#define UI_DELEGATES_DEBUG
@@ -57,7 +58,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 +108,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)
@@ -234,7 +209,7 @@ QObject *UIDelegatesManager::addMenu(QObject *parentMenu, const QString &title,
return 0;
QQmlContext *context = qmlContext(m_view);
QObject *menu = menuComponent->beginCreate(context);
- // Useful when not using Qt Quick Controls' Menu
+ // set visual parent for non-Window-based menus
if (QQuickItem* item = qobject_cast<QQuickItem*>(menu))
item->setParentItem(m_view);
@@ -272,15 +247,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 = tr("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 = tr("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 = tr("Javascript Prompt - %1").arg(m_view->url().toString());
+ break;
+ case WebContentsAdapterClient::UnloadDialog:
+ dialogComponentType = ConfirmDialog;
+ title = tr("Are you sure you want to leave this page?");
break;
case WebContentsAdapterClient::InternalAuthorizationDialog:
dialogComponentType = ConfirmDialog;
@@ -306,6 +285,9 @@ void UIDelegatesManager::showDialog(QSharedPointer<JavaScriptDialogController> d
QQmlContext *context = qmlContext(m_view);
QObject *dialog = dialogComponent->beginCreate(context);
+ // set visual parent for non-Window-based dialogs
+ if (QQuickItem* item = qobject_cast<QQuickItem*>(dialog))
+ item->setParentItem(m_view);
dialog->setParent(m_view);
QQmlProperty textProp(dialog, QStringLiteral("text"));
textProp.write(dialogController->message());
@@ -341,50 +323,52 @@ 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);
+ // set visual parent for non-Window-based dialogs
+ if (QQuickItem* item = qobject_cast<QQuickItem*>(authenticationDialog))
+ item->setParentItem(m_view);
+ authenticationDialog->setParent(m_view);
+ QString introMessage;
+ if (dialogController->isProxy()) {
+ introMessage = tr("Connect to proxy \"%1\" using:");
+ introMessage = introMessage.arg(dialogController->host().toHtmlEscaped());
+ } else {
+ const QUrl url = dialogController->url();
+ introMessage = tr("Enter username and password for \"%1\" at %2://%3");
+ introMessage = introMessage.arg(dialogController->realm(), url.scheme(), url.host());
+ }
+ 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 +381,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 +449,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..5eeaf6e03 100644
--- a/src/webengine/ui_delegates_manager.h
+++ b/src/webengine/ui_delegates_manager.h
@@ -41,6 +41,7 @@
#include "web_contents_adapter.h"
#include "web_contents_adapter_client.h"
+#include <QCoreApplication>
#include <QExplicitlySharedDataPointer>
#include <QPoint>
#include <QQmlComponent>
@@ -55,7 +56,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 +74,9 @@ class QQuickWebEngineView;
QT_END_NAMESPACE
namespace QtWebEngineCore {
+class AuthenticationDialogController;
class JavaScriptDialogController;
+class FilePickerController;
const char *defaultPropertyName(QObject *obj);
@@ -85,31 +89,9 @@ 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 {
-
+class UIDelegatesManager
+{
+ Q_DECLARE_TR_FUNCTIONS(UIDelegatesManager)
public:
enum ComponentType {
Invalid = -1,
@@ -124,8 +106,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..8f802d5c4 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 \
@@ -37,8 +37,8 @@ HEADERS = \
api/qquickwebengineloadrequest_p.h \
api/qquickwebenginenavigationrequest_p.h \
api/qquickwebenginenewviewrequest_p.h \
+ api/qquickwebengineprofile.h \
api/qquickwebengineprofile_p.h \
- api/qquickwebengineprofile_p_p.h \
api/qquickwebenginescript_p.h \
api/qquickwebenginesettings_p.h \
api/qquickwebenginesingleton_p.h \
diff --git a/src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp b/src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp
index 4feacf748..1ef6386ad 100644
--- a/src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp
+++ b/src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp
@@ -36,13 +36,17 @@
#include "qtwebenginewidgetsglobal.h"
-#include "qtwebengineglobal.h"
#include <QCoreApplication>
+namespace QtWebEngineCore
+{
+ extern void initialize();
+}
+
QT_BEGIN_NAMESPACE
static void initialize()
{
- QtWebEngine::initialize();
+ QtWebEngineCore::initialize();
}
Q_COREAPP_STARTUP_FUNCTION(initialize)
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.cpp b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
index 6c9413280..9fdab3367 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem.cpp
+++ b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
@@ -247,6 +247,18 @@ QUrl QWebEngineDownloadItem::url() const
}
/*!
+ \since 5.6
+
+ Returns the MIME type of the download.
+*/
+
+QString QWebEngineDownloadItem::mimeType() const
+{
+ Q_D(const QWebEngineDownloadItem);
+ return d->mimeType;
+}
+
+/*!
Returns the full target path where data is being downloaded to.
The path includes the file name. The default suggested path is the standard download location
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.h b/src/webenginewidgets/api/qwebenginedownloaditem.h
index 9fbf42ad3..886d9ab9a 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
@@ -59,13 +59,14 @@ public:
DownloadCancelled,
DownloadInterrupted
};
- Q_ENUMS(DownloadState)
+ Q_ENUM(DownloadState)
quint32 id() const;
DownloadState state() const;
qint64 totalBytes() const;
qint64 receivedBytes() const;
QUrl url() const;
+ QString mimeType() const;
QString path() const;
void setPath(QString path);
bool isFinished() const;
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem_p.h b/src/webenginewidgets/api/qwebenginedownloaditem_p.h
index 87dc4114a..2c7bbf985 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem_p.h
+++ b/src/webenginewidgets/api/qwebenginedownloaditem_p.h
@@ -70,6 +70,7 @@ public:
QWebEngineDownloadItem::DownloadState downloadState;
QString downloadPath;
const QUrl downloadUrl;
+ QString mimeType;
qint64 totalBytes;
qint64 receivedBytes;
diff --git a/src/webenginewidgets/api/qwebenginefullscreenrequest.cpp b/src/webenginewidgets/api/qwebenginefullscreenrequest.cpp
new file mode 100644
index 000000000..7db86e6f2
--- /dev/null
+++ b/src/webenginewidgets/api/qwebenginefullscreenrequest.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** 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(QWebEnginePage *page, const QUrl &origin, bool fullscreen)
+ : m_page(page)
+ , m_origin(origin)
+ , m_toggleOn(fullscreen)
+{
+}
+
+void QWebEngineFullScreenRequest::reject()
+{
+ if (!m_page) {
+ qWarning("Cannot reject QWebEngineFullScreenRequest: Originating page is already deleted");
+ return;
+ }
+
+ m_page->d_func()->setFullScreenMode(!m_toggleOn);
+}
+
+void QWebEngineFullScreenRequest::accept()
+{
+ if (!m_page) {
+ qWarning("Cannot accept QWebEngineFullScreenRequest: Originating page is already deleted");
+ return;
+ }
+
+ m_page->d_func()->setFullScreenMode(m_toggleOn);
+}
+
+QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebenginefullscreenrequest.h b/src/webenginewidgets/api/qwebenginefullscreenrequest.h
new file mode 100644
index 000000000..26f7247e0
--- /dev/null
+++ b/src/webenginewidgets/api/qwebenginefullscreenrequest.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** 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 QWEBENGINEFULLSCREENREQUEST_H
+#define QWEBENGINEFULLSCREENREQUEST_H
+
+#include <qtwebenginewidgetsglobal.h>
+#include <qurl.h>
+#include <qpointer.h>
+
+QT_BEGIN_NAMESPACE
+class QWebEnginePage;
+
+class QWEBENGINEWIDGETS_EXPORT QWebEngineFullScreenRequest {
+ Q_GADGET
+ Q_PROPERTY(bool toggleOn READ toggleOn)
+ Q_PROPERTY(QUrl origin READ origin)
+public:
+ Q_INVOKABLE void reject();
+ Q_INVOKABLE void accept();
+ bool toggleOn() const { return m_toggleOn; }
+ const QUrl &origin() const { return m_origin; }
+
+private:
+ QWebEngineFullScreenRequest(QWebEnginePage *page, const QUrl &origin, bool toggleOn);
+ QPointer<QWebEnginePage> m_page;
+ const QUrl m_origin;
+ const bool m_toggleOn;
+ friend class QWebEnginePagePrivate;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/webenginewidgets/api/qwebenginehistory.cpp b/src/webenginewidgets/api/qwebenginehistory.cpp
index b04c81147..05efb131d 100644
--- a/src/webenginewidgets/api/qwebenginehistory.cpp
+++ b/src/webenginewidgets/api/qwebenginehistory.cpp
@@ -42,6 +42,11 @@
QT_BEGIN_NAMESPACE
+/*!
+ \fn QWebEngineHistoryItem::swap(QWebEngineHistoryItem &other)
+ Swaps the history item with the \a other item.
+*/
+
QWebEngineHistoryItemPrivate::QWebEngineHistoryItemPrivate(QWebEnginePagePrivate *page, int index)
: page(page)
, index(index)
@@ -92,6 +97,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/qwebenginehistory.h b/src/webenginewidgets/api/qwebenginehistory.h
index 0471e28e6..3dcea9469 100644
--- a/src/webenginewidgets/api/qwebenginehistory.h
+++ b/src/webenginewidgets/api/qwebenginehistory.h
@@ -65,6 +65,9 @@ public:
QUrl iconUrl() const;
bool isValid() const;
+
+ void swap(QWebEngineHistoryItem &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+
private:
QWebEngineHistoryItem(QWebEngineHistoryItemPrivate *priv);
Q_DECLARE_PRIVATE_D(d.data(), QWebEngineHistoryItem)
@@ -73,6 +76,7 @@ private:
friend class QWebEngineHistoryPrivate;
};
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineHistoryItem)
class QWebEngineHistoryPrivate;
class QWEBENGINEWIDGETS_EXPORT QWebEngineHistory {
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index c89f73724..aacf6c455 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -37,9 +37,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"
@@ -66,8 +69,10 @@
#include <QIcon>
#include <QInputDialog>
#include <QLayout>
+#include <QLoggingCategory>
#include <QMenu>
#include <QMessageBox>
+#include <QMimeData>
#include <QStandardPaths>
#include <QStyle>
#include <QUrl>
@@ -91,106 +96,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)))
@@ -200,6 +105,8 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
, isLoading(false)
, scriptCollection(new QWebEngineScriptCollectionPrivate(browserContextAdapter()->userScriptController(), adapter.data()))
, m_isBeingAdopted(false)
+ , m_backgroundColor(Qt::white)
+ , fullscreenMode(false)
{
memset(actions, 0, sizeof(actions));
}
@@ -262,6 +169,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);
@@ -350,6 +262,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);
@@ -376,18 +293,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)
@@ -487,6 +410,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();
@@ -502,10 +433,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.
+*/
+
+/*!
+ \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(QWebEngineFullScreenRequest request)
- If the profile is not the default profile the caller must ensure the profile is alive for as
- long as the page is.
+ 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
*/
@@ -537,12 +507,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
{
@@ -551,14 +521,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)
@@ -567,6 +537,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);
@@ -579,7 +576,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
@@ -650,6 +647,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;
}
@@ -707,6 +755,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();
}
@@ -717,12 +881,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);
}
}
@@ -734,11 +896,22 @@ bool QWebEnginePage::event(QEvent *e)
return QObject::event(e);
}
+void QWebEnginePagePrivate::wasShown()
+{
+ adapter->wasShown();
+}
+
+void QWebEnginePagePrivate::wasHidden()
+{
+ adapter->wasHidden();
+}
+
bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData &data)
{
if (!view || !view->d_func()->m_pendingContextMenuEvent)
return false;
+ m_menuData = WebEngineContextMenuData();
QContextMenuEvent event(QContextMenuEvent::Mouse, data.pos, view->mapToGlobal(data.pos));
switch (view->contextMenuPolicy()) {
case Qt::PreventContextMenu:
@@ -762,7 +935,6 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData
break;
}
view->d_func()->m_pendingContextMenuEvent = false;
- m_menuData = WebEngineContextMenuData();
return true;
}
@@ -773,6 +945,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(q, origin, fullscreen);
+ Q_EMIT q->fullScreenRequested(request);
+}
+
+bool QWebEnginePagePrivate::isFullScreenMode() const
+{
+ return fullscreenMode;
+}
+
void QWebEnginePagePrivate::javascriptDialog(QSharedPointer<JavaScriptDialogController> controller)
{
Q_Q(QWebEnginePage);
@@ -791,6 +975,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;
@@ -842,34 +1029,18 @@ 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);
+}
+
+void QWebEnginePagePrivate::requestGeometryChange(const QRect &geometry)
+{
+ Q_Q(QWebEnginePage);
+ Q_EMIT q->geometryChangeRequested(geometry);
}
QMenu *QWebEnginePage::createStandardContextMenu()
@@ -878,6 +1049,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);
@@ -893,20 +1070,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;
}
@@ -949,17 +1152,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
@@ -977,14 +1185,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)
@@ -1051,12 +1259,16 @@ 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);
}
/*!
- Returns the script collection used by this page.
- \sa QWebEngineScriptCollection
+ Returns the collection of scripts that are injected into the page.
+
+ In addition, a page might also execute scripts
+ added through QWebEngineProfile::scripts().
+
+ \sa QWebEngineScriptCollection, QWebEngineScript
*/
QWebEngineScriptCollection &QWebEnginePage::scripts()
@@ -1076,8 +1288,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)
{
@@ -1086,23 +1298,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;
@@ -1134,10 +1346,24 @@ bool QWebEnginePage::javaScriptPrompt(const QUrl &securityOrigin, const QString
void QWebEnginePage::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID)
{
- Q_UNUSED(level);
- Q_UNUSED(message);
- Q_UNUSED(lineNumber);
- Q_UNUSED(sourceID);
+ static QLoggingCategory loggingCategory("js", QtWarningMsg);
+ static QByteArray file = sourceID.toUtf8();
+ QMessageLogger logger(file.constData(), lineNumber, nullptr, loggingCategory.categoryName());
+
+ switch (level) {
+ case JavaScriptConsoleMessageLevel::InfoMessageLevel:
+ if (loggingCategory.isInfoEnabled())
+ logger.info().noquote() << message;
+ break;
+ case JavaScriptConsoleMessageLevel::WarningMessageLevel:
+ if (loggingCategory.isWarningEnabled())
+ logger.warning().noquote() << message;
+ break;
+ case JavaScriptConsoleMessageLevel::ErrorMessageLevel:
+ if (loggingCategory.isCriticalEnabled())
+ logger.critical().noquote() << message;
+ break;
+ }
}
bool QWebEnginePage::certificateError(const QWebEngineCertificateError &)
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index b4cf52298..83faaf42e 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(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,12 +276,14 @@ 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
Q_PRIVATE_SLOT(d_func(), void _q_webActionTriggered(bool checked))
#endif
+ friend class QWebEngineFullScreenRequest;
friend class QWebEngineView;
friend class QWebEngineViewPrivate;
#ifndef QT_NO_ACCESSIBILITY
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 55c722f4c..9cc4553d1 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 { }
@@ -138,19 +96,20 @@ public:
virtual void adoptNewWindow(QtWebEngineCore::WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &initialGeometry) Q_DECL_OVERRIDE;
virtual bool isBeingAdopted() 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;
@@ -162,6 +121,9 @@ 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 void requestGeometryChange(const QRect &geometry) Q_DECL_OVERRIDE;
virtual QtWebEngineCore::BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE;
@@ -169,22 +131,28 @@ public:
void updateNavigationActions();
void _q_webActionTriggered(bool checked);
+ void wasShown();
+ void wasHidden();
+
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;
bool m_isBeingAdopted;
+ 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..7f63b312f 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -36,12 +36,12 @@
#include "qwebengineprofile.h"
+#include "qwebenginecookiestore.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
*/
@@ -144,6 +150,7 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
itemPrivate->downloadId = info.id;
itemPrivate->downloadState = QWebEngineDownloadItem::DownloadRequested;
itemPrivate->downloadPath = info.path;
+ itemPrivate->mimeType = info.mimeType;
QWebEngineDownloadItem *download = new QWebEngineDownloadItem(itemPrivate, q);
@@ -183,10 +190,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 +206,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 +249,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 +263,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 +279,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 +292,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 +304,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 +317,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 +341,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 +363,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 +409,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 +422,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 +435,31 @@ void QWebEngineProfile::setHttpCacheMaximumSize(int maxSize)
}
/*!
+ Returns the cookie store singleton, if one has been set.
+*/
+
+QWebEngineCookieStore* QWebEngineProfile::cookieStore()
+{
+ Q_D(QWebEngineProfile);
+ return d->browserContext()->cookieStore();
+}
+
+
+/*!
+ 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 +482,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
{
@@ -435,8 +491,10 @@ bool QWebEngineProfile::visitedLinksContainsUrl(const QUrl &url) const
}
/*!
- Returns the script collection used by this profile.
- \sa QWebEngineScriptCollection
+ Returns the collection of scripts that are injected into all pages that share
+ this profile.
+
+ \sa QWebEngineScriptCollection, QWebEngineScript, QWebEnginePage::scripts()
*/
QWebEngineScriptCollection *QWebEngineProfile::scripts() const
{
@@ -468,10 +526,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 +549,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(_q_destroyedUrlSchemeHandler(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(_q_destroyedUrlSchemeHandler(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(_q_destroyedUrlSchemeHandler(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..416ef23db 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 QWebEngineCookieStore;
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);
+ QWebEngineCookieStore* cookieStore();
+ 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..058f58475 100644
--- a/src/webenginewidgets/api/qwebenginescript.cpp
+++ b/src/webenginewidgets/api/qwebenginescript.cpp
@@ -47,24 +47,30 @@ 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.
+
+ Use QWebEnginePage::scripts() and QWebEngineProfile::scripts() to access
+ the collection of scripts associated with a single page or a
+ number of pages sharing the same profile.
*/
/*!
\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 +78,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 +109,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 +155,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 +165,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 +173,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 +187,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 +197,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 +209,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 +217,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 +227,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 +236,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 +246,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..29126b110 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;
@@ -98,7 +99,7 @@ private:
QSharedDataPointer<QtWebEngineCore::UserScript> d;
};
-Q_DECLARE_SHARED(QWebEngineScript)
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineScript)
#ifndef QT_NO_DEBUG_STREAM
QWEBENGINEWIDGETS_EXPORT QDebug operator<<(QDebug, const QWebEngineScript &);
diff --git a/src/webenginewidgets/api/qwebenginescriptcollection.cpp b/src/webenginewidgets/api/qwebenginescriptcollection.cpp
index 21cb0d05e..9967cde85 100644
--- a/src/webenginewidgets/api/qwebenginescriptcollection.cpp
+++ b/src/webenginewidgets/api/qwebenginescriptcollection.cpp
@@ -47,6 +47,23 @@ using QtWebEngineCore::UserScript;
\since 5.5
\brief The QWebEngineScriptCollection class represents a collection of user scripts.
+ QWebEngineScriptCollection manages a set of user scripts.
+
+ Use QWebEnginePage::scripts() and QWebEngineProfile::scripts() to access
+ the collection of scripts associated with a single page or a
+ number of pages sharing the same profile.
+*/
+
+/*!
+ \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)
@@ -54,13 +71,15 @@ QWebEngineScriptCollection::QWebEngineScriptCollection(QWebEngineScriptCollectio
{
}
+/*!
+ 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 +88,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 +98,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 +111,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 +120,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 +137,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 +148,6 @@ bool QWebEngineScriptCollection::remove(const QWebEngineScript &script)
}
/*!
- * \brief QWebEngineScriptCollection::clear
* Removes all scripts from this collection.
*/
void QWebEngineScriptCollection::clear()
@@ -147,8 +156,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..362849732 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)
@@ -285,6 +294,24 @@ void QWebEngineView::contextMenuEvent(QContextMenuEvent *event)
menu->popup(event->globalPos());
}
+/*!
+ * \reimp
+ */
+void QWebEngineView::showEvent(QShowEvent *event)
+{
+ QWidget::showEvent(event);
+ page()->d_ptr->wasShown();
+}
+
+/*!
+ * \reimp
+ */
+void QWebEngineView::hideEvent(QHideEvent *event)
+{
+ QWidget::hideEvent(event);
+ page()->d_ptr->wasHidden();
+}
+
#ifndef QT_NO_ACCESSIBILITY
int QWebEngineViewAccessible::childCount() const
{
diff --git a/src/webenginewidgets/api/qwebengineview.h b/src/webenginewidgets/api/qwebengineview.h
index 6b37dbf39..e16bbf4af 100644
--- a/src/webenginewidgets/api/qwebengineview.h
+++ b/src/webenginewidgets/api/qwebengineview.h
@@ -113,13 +113,18 @@ 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);
virtual void contextMenuEvent(QContextMenuEvent*) Q_DECL_OVERRIDE;
virtual bool event(QEvent*) Q_DECL_OVERRIDE;
+ virtual void showEvent(QShowEvent *) Q_DECL_OVERRIDE;
+ virtual void hideEvent(QHideEvent *) 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..065e5a18b 100644
--- a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
@@ -28,12 +28,12 @@
/*!
\page qtwebenginewidgets-qtwebkitportingguide.html
\title Porting from Qt WebKit to Qt WebEngine
- \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.
+ \brief Overview of the differences between the Qt WebKit and Qt WebEngine API.
+ The following sections contain information about 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
@@ -92,7 +92,7 @@
\endcode
- \section1 QWebFrame has been Merged into QWebEnginePage
+ \section1 QWebFrame Has Been Merged into QWebEnginePage
It is not possible to access sub-frames. Methods of the main QWebFrame are
now available directly through the QWebEnginePage itself.
@@ -111,12 +111,12 @@
\endcode
- \section1 Some methods now return their result asynchronously
+ \section1 Some Methods Now Return Their Result Asynchronously
- Since Qt WebEngine uses a multi-process architecture, applications needs
- to return to the event loop where the result will be received asynchronously
- from Qt WebEngine's render process. A function pointer, a functor or a lambda
- expression must be provided to handle the result when it is available.
+ Because Qt WebEngine uses a multi-process architecture, calls to some methods from applications
+ will return immediately, while the results should be received asynchronously via a callback
+ mechanism. A function pointer, a functor, or a lambda expression must be provided to handle the
+ results when they become available.
\b {Qt WebKit}
\code
@@ -176,14 +176,14 @@
\endcode
- \section1 Qt WebEngine does not Interact with QNetworkAccessManager
+ \section1 Qt WebEngine Does Not Interact with QNetworkAccessManager
Some classes of Qt Network such as QAuthenticator were reused for their interface
- but, unlike Qt WebKit, Qt WebEngine has its own HTTP implementation and can't
+ but, unlike Qt WebKit, Qt WebEngine has its own HTTP implementation and cannot
go through a QNetworkAccessManager.
- Signals and methods of QNetworkAccessManager that are still supported were
- moved to QWebEnginePage directly.
+ The signals and methods of QNetworkAccessManager that are still supported were
+ moved to the QWebEnginePage class.
\b {Qt WebKit}
\code
@@ -198,12 +198,14 @@
connect(&page, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticate(QNetworkReply*,QAuthenticator*)));
\endcode
+ This also affects the way in which certificates are managed. For more information, see
+ \l {Managing Certificates}.
- \section1 Notes about Individual Methods
+ \section1 Notes About Individual Methods
\section2 evaluateJavaScript
- QWebFrame::evaluateJavaScript was renamed and moved as QWebEnginePage::runJavaScript.
+ QWebFrame::evaluateJavaScript was moved and renamed as QWebEnginePage::runJavaScript.
It is currently only possible to run JavaScript on the main frame of a page and the
result is returned asynchronously to the provided functor.
@@ -241,15 +243,15 @@
\endcode
- \section1 Unavailable Qt WebKit APIs
+ \section1 Unavailable Qt WebKit API
- Qt WebKit classes and methods in this list will not be available in Qt WebEngine.
+ The Qt WebKit classes and methods in this list will not be available in Qt WebEngine.
\table
\row
\li QGraphicsWebView
- \li Qt WebEngine requires hardware acceleration. Since we couldn't support
- a web view class in a QGraphicsView unless it is attached to a QGLWidget
+ \li Qt WebEngine is designed for being used with hardware acceleration. Because we could not
+ support a web view class in a QGraphicsView unless it would be attached to a QGLWidget
viewport, this feature is out of scope.
\row
\li QWebElement
@@ -263,13 +265,26 @@
\li The Web SQL Database feature that this API was wrapping in Qt WebKit
was dropped from the HTML5 standard.
\row
- \li QWebPluginFactory, QWebPage::setPalette, QWebView::setRenderHints
- \li Qt WebEngine renders web pages using Skia and isn't using QPainter
+ \li QWebPluginDatabase, QWebPluginFactory, QWebPluginInfo, QWebPage::setPalette,
+ QWebView::setRenderHints
+ \li Qt WebEngine renders web pages using Skia and is not using QPainter
or Qt for this purpose. The HTML5 standard also now offers much
better alternatives that were not available when native controls
plugins were introduced in Qt WebKit.
\row
\li QWebHistoryInterface
\li Visited links are persisted automatically by Qt WebEngine.
+ \row
+ \li QWebPage::setContentEditable
+ \li In the latest HTML standard, any document element can be made editable through the
+ \c contentEditable attribute. So \c runJavaScript is all that is needed:
+ \c{page->runJavascript("document.documentElement.contentEditable = true")}
+ \row
+ \li QWebPage::setLinkDelegationPolicy
+ \li There is no way to connect a signal to run C++ code when a link is clicked. However,
+ link clicks can be delegated to the Qt application instead of having the HTML handler
+ engine process them by overloading the QWebEnginePage::acceptNavigationRequest()
+ function. This is necessary when an HTML document is used as part of the user interface,
+ and not to display external data, for example, when displaying a list of results.
\endtable
*/
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..aac5228d6 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,45 +245,61 @@
/*!
\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.
+ Since Qt 5.6, the default implementation logs the messages in a \c js
+ \l{QLoggingCategory}{logging category}.
+
+ \sa{Console Logging}
*/
/*!
\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.
+ This function is called for absolute URLs that are prefixed with \c {http://} or \c {https://}
+ and for unrecognized schemes, such as \c {mailto:}, which will be handled by QDesktopServices
+ if accepted. To have this function called also upon receiving navigation requests to local URLs,
+ prefix the URLs with \c {http://}.
+
+ Navigation requests can be delegated to the Qt application instead of having the HTML handler
+ engine process them by overloading this function. This is necessary when an HTML document is
+ used as part of the user interface, and not to display external data, for example, when
+ displaying a list of results.
+*/
/*!
\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 +309,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 +388,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 +408,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 +417,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 +457,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 +497,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 +531,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 +542,18 @@
/*!
\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 that was originally requested to be loaded by the frame
+ that is 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.
+ \note The URL may differ from the one returned by url(), which is the actual
+ URL that results from DNS resolution or redirection.
\sa url(), setUrl()
*/
@@ -500,7 +562,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 +578,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 +596,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 +615,30 @@
/*!
\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
+
+ \warning Do not execute lengthy routines in the callback function, because it might block the
+ rendering of the web engine page.
- \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 +646,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..397b9f51b 100644
--- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
@@ -33,45 +33,42 @@
\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}.
@@ -79,19 +76,13 @@
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.
-
+ \sa {WebEngine Demo Browser Example}, {WebEngine Content Manipulation Example}, {Markdown Editor Example}
*/
-// FIXME: reintroduce the following when we have proper names for the examples.
-// \sa {WebEngine Tab Browser Example}, {WebEngine Fancy Browser Example}
/*!
\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 3d7237367..9871ecfb1 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);
@@ -138,14 +139,12 @@ void RenderWidgetHostViewQtDelegateWidget::show()
// want to show anything else than popups as top-level.
if (parent() || m_isPopup) {
QOpenGLWidget::show();
- m_client->notifyShown();
}
}
void RenderWidgetHostViewQtDelegateWidget::hide()
{
QOpenGLWidget::hide();
- m_client->notifyHidden();
}
bool RenderWidgetHostViewQtDelegateWidget::isVisible() const
@@ -218,6 +217,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);
@@ -243,6 +255,13 @@ void RenderWidgetHostViewQtDelegateWidget::showEvent(QShowEvent *event)
m_windowConnections.append(connect(w, SIGNAL(yChanged(int)), SLOT(onWindowPosChanged())));
}
m_client->windowChanged();
+ m_client->notifyShown();
+}
+
+void RenderWidgetHostViewQtDelegateWidget::hideEvent(QHideEvent *event)
+{
+ QOpenGLWidget::hideEvent(event);
+ m_client->notifyHidden();
}
bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event)
@@ -270,7 +289,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);
// When RenderWidgetHostViewQt::GetScreenInfo is called for the first time, the associated
// QWindow is NULL, and the screen device pixel ratio can not be queried.
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..fddc79c2f 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -78,11 +78,13 @@ 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;
void resizeEvent(QResizeEvent *resizeEvent) Q_DECL_OVERRIDE;
void showEvent(QShowEvent *) Q_DECL_OVERRIDE;
+ void hideEvent(QHideEvent *) Q_DECL_OVERRIDE;
void initializeGL() Q_DECL_OVERRIDE;
void paintGL() Q_DECL_OVERRIDE;
@@ -98,6 +100,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..5687bffaf 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 += 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..09b0dd69d
--- /dev/null
+++ b/tests/auto/core/core.pro
@@ -0,0 +1,5 @@
+TEMPLATE = subdirs
+
+SUBDIRS += \
+ qwebenginecookiestore \
+ qwebengineurlrequestinterceptor \
diff --git a/tests/auto/core/qwebenginecookiestore/qwebenginecookiestore.pro b/tests/auto/core/qwebenginecookiestore/qwebenginecookiestore.pro
new file mode 100644
index 000000000..e99c7f493
--- /dev/null
+++ b/tests/auto/core/qwebenginecookiestore/qwebenginecookiestore.pro
@@ -0,0 +1 @@
+include(../tests.pri)
diff --git a/tests/auto/core/qwebenginecookiestore/resources/content.html b/tests/auto/core/qwebenginecookiestore/resources/content.html
new file mode 100644
index 000000000..360ad65ef
--- /dev/null
+++ b/tests/auto/core/qwebenginecookiestore/resources/content.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<a>This is test content</a>
+</body>
+</html>
diff --git a/tests/auto/core/qwebenginecookiestore/resources/index.html b/tests/auto/core/qwebenginecookiestore/resources/index.html
new file mode 100644
index 000000000..d41866712
--- /dev/null
+++ b/tests/auto/core/qwebenginecookiestore/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/qwebenginecookiestore/tst_qwebenginecookiestore.cpp b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
new file mode 100644
index 000000000..7cf55427e
--- /dev/null
+++ b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** 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/qwebenginecookiestore.h>
+#include <QtWebEngineWidgets/qwebenginepage.h>
+#include <QtWebEngineWidgets/qwebengineprofile.h>
+#include <QtWebEngineWidgets/qwebengineview.h>
+
+class tst_QWebEngineCookieStore : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QWebEngineCookieStore();
+ ~tst_QWebEngineCookieStore();
+
+public Q_SLOTS:
+ void init();
+ void cleanup();
+
+private Q_SLOTS:
+ void initTestCase();
+ void cleanupTestCase();
+ void cookieSignals();
+ void setAndDeleteCookie();
+ void batchCookieTasks();
+};
+
+tst_QWebEngineCookieStore::tst_QWebEngineCookieStore()
+{
+}
+
+tst_QWebEngineCookieStore::~tst_QWebEngineCookieStore()
+{
+}
+
+void tst_QWebEngineCookieStore::init()
+{
+}
+
+void tst_QWebEngineCookieStore::cleanup()
+{
+}
+
+void tst_QWebEngineCookieStore::initTestCase()
+{
+}
+
+void tst_QWebEngineCookieStore::cleanupTestCase()
+{
+}
+
+void tst_QWebEngineCookieStore::cookieSignals()
+{
+ QWebEngineView view;
+ QWebEngineCookieStore *client = view.page()->profile()->cookieStore();
+ client->deleteAllCookies();
+
+ 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_QWebEngineCookieStore::setAndDeleteCookie()
+{
+ QWebEngineView view;
+ QWebEngineCookieStore *client = view.page()->profile()->cookieStore();
+ client->deleteAllCookies();
+
+ 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->setCookie(cookie1);
+ QTRY_COMPARE(cookieAddedSpy.count(),1);
+ client->setCookie(cookie2);
+ QTRY_COMPARE(cookieAddedSpy.count(),2);
+ 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->setCookie(cookie3);
+ QTRY_COMPARE(cookieAddedSpy.count(), 1);
+ // updating a cookie with an expired 'expires' field should remove the cookie with the same name
+ client->setCookie(expiredCookie3);
+ client->deleteCookie(cookie2);
+ QTRY_COMPARE(cookieAddedSpy.count(), 1);
+ QTRY_COMPARE(cookieRemovedSpy.count(), 2);
+}
+
+void tst_QWebEngineCookieStore::batchCookieTasks()
+{
+ QWebEngineView view;
+ QWebEngineCookieStore *client = view.page()->profile()->cookieStore();
+ client->deleteAllCookies();
+
+ 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());
+
+ client->setCookie(cookie1);
+ QTRY_COMPARE(cookieAddedSpy.count(), 1);
+ client->setCookie(cookie2);
+ QTRY_COMPARE(cookieAddedSpy.count(), 2);
+
+ 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);
+
+ cookieAddedSpy.clear();
+ cookieRemovedSpy.clear();
+
+ client->deleteSessionCookies();
+ QTRY_COMPARE(cookieRemovedSpy.count(), 3);
+
+ client->deleteAllCookies();
+ QTRY_COMPARE(cookieRemovedSpy.count(), 4);
+}
+
+QTEST_MAIN(tst_QWebEngineCookieStore)
+#include "tst_qwebenginecookiestore.moc"
diff --git a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.qrc b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.qrc
new file mode 100644
index 000000000..afeae268b
--- /dev/null
+++ b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.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..c4461f1c1
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -0,0 +1,274 @@
+/****************************************************************************
+**
+** 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;
+
+ void interceptRequest(QWebEngineUrlRequestInfo &info) override
+ {
+ info.block(info.requestMethod() != QByteArrayLiteral("GET"));
+ if (shouldIntercept && info.requestUrl().toString().endsWith(QLatin1String("__placeholder__")))
+ info.redirect(QUrl("qrc:///resources/content.html"));
+
+ observedUrls.append(info.requestUrl());
+ firstPartyUrls.append(info.firstPartyUrl());
+ }
+ 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() { }
+
+ void interceptRequest(QWebEngineUrlRequestInfo &info) override
+ {
+ requestedUrls.append(info.requestUrl());
+ info.redirect(QUrl("data:text/html,<p>hello"));
+ }
+
+ 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..606ed2a8c
--- /dev/null
+++ b/tests/auto/core/tests.pri
@@ -0,0 +1,15 @@
+TEMPLATE = app
+
+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..face62352 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -46,6 +46,7 @@
#include <QMetaType>
#include <QQmlListProperty>
#include <QtTest/QtTest>
+#include <QtWebEngine/QQuickWebEngineProfile>
#include <private/qquickwebengineview_p.h>
#include <private/qquickwebenginecertificateerror_p.h>
#include <private/qquickwebenginedownloaditem_p.h>
@@ -53,9 +54,9 @@
#include <private/qquickwebengineloadrequest_p.h>
#include <private/qquickwebenginenavigationrequest_p.h>
#include <private/qquickwebenginenewviewrequest_p.h>
-#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*"
+ << "QWebEngineCookieStore*"
;
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,83 @@ 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.RequestClose --> 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.windowCloseRequested() --> void"
<< "QQuickWebEngineView.runJavaScript(QString,QJSValue) --> void"
<< "QQuickWebEngineView.runJavaScript(QString) --> void"
<< "QQuickWebEngineView.loadHtml(QString,QUrl) --> void"
@@ -164,37 +204,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 +277,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 +288,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.cookieStore() --> QWebEngineCookieStore*"
<< "QQuickWebEngineScript.Deferred --> InjectionPoint"
<< "QQuickWebEngineScript.DocumentReady --> InjectionPoint"
<< "QQuickWebEngineScript.DocumentCreation --> InjectionPoint"
@@ -292,8 +317,40 @@ 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.origin --> QUrl"
<< "QQuickWebEngineFullScreenRequest.toggleOn --> bool"
<< "QQuickWebEngineFullScreenRequest.accept() --> void"
+ << "QQuickWebEngineFullScreenRequest.reject() --> 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/examples/webenginewidgets/browser/main.cpp b/tests/auto/quick/qmltests/data/titleupdate.js
index 86859f741..cfcc52c60 100644
--- a/examples/webenginewidgets/browser/main.cpp
+++ b/tests/auto/quick/qmltests/data/titleupdate.js
@@ -3,7 +3,7 @@
** 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.
+** This file is part of the QtWebEngine module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,17 +39,17 @@
**
****************************************************************************/
-#include "browserapplication.h"
-
-#include <qtwebenginewidgetsglobal.h>
-
-int main(int argc, char **argv)
+function updateTitle()
{
- Q_INIT_RESOURCE(data);
- BrowserApplication application(argc, argv);
- if (!application.isTheOnlyBrowser())
- return 0;
-
- application.newMainWindow();
- return application.exec();
+ 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/examples/webenginewidgets/browser/featurepermissionbar.h b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
index 1bfe1b483..eaca8822b 100644
--- a/examples/webenginewidgets/browser/featurepermissionbar.h
+++ b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
@@ -39,36 +39,44 @@
**
****************************************************************************/
-#ifndef FEATUREPERMISSIONBAR_H
-#define FEATUREPERMISSIONBAR_H
+import QtQuick 2.5
+import QtTest 1.0
-#include <QWidget>
-#include <QWebEnginePage>
+Item {
+ id: root
+ width: 300
+ height: 400
+ TextInput {
+ id: textInput
+ anchors {
+ top: parent.top
+ left: parent.left
+ right: parent.right
+ }
+ focus: true
+ text: "foo"
+ }
-QT_BEGIN_NAMESPACE
-class QLabel;
-class QPushButton;
-QT_END_NAMESPACE
+ TestWebEngineView {
+ id: webEngineView
+ activeFocusOnPress: false
+ anchors {
+ top: textInput.bottom
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ }
-class FeaturePermissionBar : public QWidget {
-Q_OBJECT
+ TestCase {
+ name: "ActiveFocusOnPress"
+ when:windowShown
-public:
- FeaturePermissionBar(QWidget*);
- void requestPermission(const QUrl &, QWebEnginePage::Feature feature);
-
-signals:
- void featurePermissionProvided(const QUrl &securityOrigin, QWebEnginePage::Feature, QWebEnginePage::PermissionPolicy);
-
-private slots:
- void permissionDenied();
- void permissionGranted();
- void permissionUnknown();
-
-private:
- QWebEnginePage::Feature m_feature;
- QLabel *m_messageLabel;
- QUrl m_securityOrigin;
-};
-
-#endif // FEATUREPERMISSIONBAR_H
+ 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_download.qml b/tests/auto/quick/qmltests/data/tst_download.qml
index ffd7041e3..415318ed7 100644
--- a/tests/auto/quick/qmltests/data/tst_download.qml
+++ b/tests/auto/quick/qmltests/data/tst_download.qml
@@ -66,23 +66,26 @@ TestWebEngineView {
signalName: "downloadFinished"
}
+ Connections {
+ id: downloadItemConnections
+ onStateChanged: downloadState.push(target.state)
+ }
+
WebEngineProfile {
id: testDownloadProfile
onDownloadRequested: {
downloadState.push(download.state)
+ downloadItemConnections.target = download
if (cancelDownload) {
download.cancel()
- downloadState.push(download.state)
} else {
totalBytes = download.totalBytes
download.path = "testfile.zip"
download.accept()
- downloadState.push(download.state)
}
}
onDownloadFinished: {
- downloadState.push(download.state)
receivedBytes = download.receivedBytes;
}
}
@@ -96,6 +99,7 @@ TestWebEngineView {
totalBytes = 0
receivedBytes = 0
cancelDownload = false
+ downloadItemConnections.target = null
downloadState = []
}
@@ -133,7 +137,7 @@ TestWebEngineView {
downLoadRequestedSpy.wait()
compare(downLoadRequestedSpy.count, 1)
compare(downloadFinishedSpy.count, 1)
- compare(downloadState[2], WebEngineDownloadItem.DownloadCancelled)
+ compare(downloadState[1], WebEngineDownloadItem.DownloadCancelled)
}
}
}
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..31296f45c 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 {
@@ -144,6 +144,8 @@ TestWebEngineView {
var dataUrl = "data:text/html,foo"
webEngineView.url = dataUrl
compare(webEngineView.url, dataUrl)
+ verify(webEngineView.waitForLoadSucceeded()) // data:text/html,foo is loaded
+ compare(webEngineView.url, dataUrl)
var redirectUrl = Qt.resolvedUrl("redirect.html")
webEngineView.url = redirectUrl
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/examples/webenginewidgets/browser/edittreeview.h b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/FilePicker.qml
index 1cf87d54f..5ee231c19 100644
--- a/examples/webenginewidgets/browser/edittreeview.h
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/FilePicker.qml
@@ -3,7 +3,7 @@
** 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.
+** This file is part of the QtWebEngine module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,22 +39,22 @@
**
****************************************************************************/
-#ifndef EDITTREEVIEW_H
-#define EDITTREEVIEW_H
+import QtQuick 2.2
+import "../../TestParams" 1.0
-#include <QtWidgets/QTreeView>
+QtObject {
+ property bool selectMultiple: false;
+ property bool selectExisting: false;
+ property bool selectFolder: false;
-class EditTreeView : public QTreeView
-{
- Q_OBJECT
+ signal filesSelected(var fileList);
+ signal rejected();
-public:
- EditTreeView(QWidget *parent = 0);
- void keyPressEvent(QKeyEvent *event);
-
-public slots:
- void removeOne();
- void removeAll();
-};
-
-#endif // EDITTREEVIEW_H
+ 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/examples/webenginewidgets/browser/squeezelabel.h b/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml
index 628b7350a..f0f2d9368 100644
--- a/examples/webenginewidgets/browser/squeezelabel.h
+++ b/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml
@@ -3,7 +3,7 @@
** 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.
+** This file is part of the QtWebEngine module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,21 +39,11 @@
**
****************************************************************************/
-#ifndef SQUEEZELABEL_H
-#define SQUEEZELABEL_H
+pragma Singleton
+import QtQuick 2.0
-#include <QtWidgets/QLabel>
-
-class SqueezeLabel : public QLabel
-{
- Q_OBJECT
-
-public:
- SqueezeLabel(QWidget *parent = 0);
-
-protected:
- void paintEvent(QPaintEvent *event);
-
-};
-
-#endif // SQUEEZELABEL_H
+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..a1900a77d 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -21,10 +21,13 @@
#include "util.h"
#include <QScopedPointer>
+#include <QtCore/qelapsedtimer.h>
#include <QtQml/QQmlEngine>
#include <QtTest/QtTest>
#include <private/qquickwebengineview_p.h>
+#include <functional>
+
class tst_QQuickWebEngineView : public QObject {
Q_OBJECT
public:
@@ -61,7 +64,9 @@ private Q_SLOTS:
private:
inline QQuickWebEngineView *newWebEngineView();
inline QQuickWebEngineView *webEngineView() const;
+ QUrl urlFromTestPath(const char *localFilePath);
void runJavaScript(const QString &script);
+ QString m_testSourceDirPath;
QScopedPointer<TestWindow> m_window;
QScopedPointer<QQmlComponent> m_component;
};
@@ -70,10 +75,14 @@ tst_QQuickWebEngineView::tst_QQuickWebEngineView()
{
QtWebEngine::initialize();
+ m_testSourceDirPath = QString::fromLocal8Bit(TESTS_SOURCE_DIR);
+ if (!m_testSourceDirPath.endsWith(QLatin1Char('/')))
+ m_testSourceDirPath.append(QLatin1Char('/'));
+
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());
}
@@ -100,6 +109,11 @@ inline QQuickWebEngineView *tst_QQuickWebEngineView::webEngineView() const
return static_cast<QQuickWebEngineView*>(m_window->webEngineView.data());
}
+QUrl tst_QQuickWebEngineView::urlFromTestPath(const char *localFilePath)
+{
+ return QUrl::fromLocalFile(m_testSourceDirPath + QString::fromUtf8(localFilePath));
+}
+
void tst_QQuickWebEngineView::runJavaScript(const QString &script)
{
webEngineView()->runJavaScript(script);
@@ -119,7 +133,7 @@ void tst_QQuickWebEngineView::stopEnabledAfterLoadStarted()
QCOMPARE(webEngineView()->isLoading(), false);
LoadStartedCatcher catcher(webEngineView());
- webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")));
+ webEngineView()->setUrl(urlFromTestPath("html/basic_page.html"));
waitForSignal(&catcher, SIGNAL(finished()));
QCOMPARE(webEngineView()->isLoading(), true);
@@ -149,7 +163,7 @@ void tst_QQuickWebEngineView::loadEmptyPageViewHidden()
{
QSignalSpy loadSpy(webEngineView(), SIGNAL(loadingChanged(QQuickWebEngineLoadRequest*)));
- webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html")));
+ webEngineView()->setUrl(urlFromTestPath("html/basic_page.html"));
QVERIFY(waitForLoadSucceeded(webEngineView()));
QCOMPARE(loadSpy.size(), 2);
@@ -159,7 +173,7 @@ void tst_QQuickWebEngineView::loadNonexistentFileUrl()
{
QSignalSpy loadSpy(webEngineView(), SIGNAL(loadingChanged(QQuickWebEngineLoadRequest*)));
- webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/file_that_does_not_exist.html")));
+ webEngineView()->setUrl(urlFromTestPath("html/file_that_does_not_exist.html"));
QVERIFY(waitForLoadFailed(webEngineView()));
QCOMPARE(loadSpy.size(), 2);
@@ -167,46 +181,46 @@ void tst_QQuickWebEngineView::loadNonexistentFileUrl()
void tst_QQuickWebEngineView::backAndForward()
{
- webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html")));
+ webEngineView()->setUrl(urlFromTestPath("html/basic_page.html"));
QVERIFY(waitForLoadSucceeded(webEngineView()));
- QCOMPARE(webEngineView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html"));
+ QCOMPARE(webEngineView()->url(), urlFromTestPath("html/basic_page.html"));
- webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page2.html")));
+ webEngineView()->setUrl(urlFromTestPath("html/basic_page2.html"));
QVERIFY(waitForLoadSucceeded(webEngineView()));
- QCOMPARE(webEngineView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "html/basic_page2.html"));
+ QCOMPARE(webEngineView()->url(), urlFromTestPath("html/basic_page2.html"));
webEngineView()->goBack();
QVERIFY(waitForLoadSucceeded(webEngineView()));
- QCOMPARE(webEngineView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html"));
+ QCOMPARE(webEngineView()->url(), urlFromTestPath("html/basic_page.html"));
webEngineView()->goForward();
QVERIFY(waitForLoadSucceeded(webEngineView()));
- QCOMPARE(webEngineView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "html/basic_page2.html"));
+ QCOMPARE(webEngineView()->url(), urlFromTestPath("html/basic_page2.html"));
}
void tst_QQuickWebEngineView::reload()
{
- webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html")));
+ webEngineView()->setUrl(urlFromTestPath("html/basic_page.html"));
QVERIFY(waitForLoadSucceeded(webEngineView()));
- QCOMPARE(webEngineView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html"));
+ QCOMPARE(webEngineView()->url(), urlFromTestPath("html/basic_page.html"));
webEngineView()->reload();
QVERIFY(waitForLoadSucceeded(webEngineView()));
- QCOMPARE(webEngineView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html"));
+ QCOMPARE(webEngineView()->url(), urlFromTestPath("html/basic_page.html"));
}
void tst_QQuickWebEngineView::stop()
{
- webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html")));
+ webEngineView()->setUrl(urlFromTestPath("html/basic_page.html"));
QVERIFY(waitForLoadSucceeded(webEngineView()));
- QCOMPARE(webEngineView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html"));
+ QCOMPARE(webEngineView()->url(), urlFromTestPath("html/basic_page.html"));
webEngineView()->stop();
}
@@ -215,7 +229,7 @@ void tst_QQuickWebEngineView::loadProgress()
{
QCOMPARE(webEngineView()->loadProgress(), 0);
- webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html")));
+ webEngineView()->setUrl(urlFromTestPath("html/basic_page.html"));
QSignalSpy loadProgressChangedSpy(webEngineView(), SIGNAL(loadProgressChanged()));
QVERIFY(waitForLoadSucceeded(webEngineView()));
@@ -234,7 +248,7 @@ void tst_QQuickWebEngineView::show()
void tst_QQuickWebEngineView::showWebEngineView()
{
- webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/direct-image-compositing.html")));
+ webEngineView()->setUrl(urlFromTestPath("html/direct-image-compositing.html"));
QVERIFY(waitForLoadSucceeded(webEngineView()));
m_window->show();
// This should not crash.
@@ -268,12 +282,12 @@ void tst_QQuickWebEngineView::multipleWebEngineViewWindows()
QQuickWebEngineView *webEngineView2 = newWebEngineView();
QScopedPointer<TestWindow> window2(new TestWindow(webEngineView2));
- webEngineView1->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/scroll.html")));
+ webEngineView1->setUrl(urlFromTestPath("html/scroll.html"));
QVERIFY(waitForLoadSucceeded(webEngineView1));
window1->show();
webEngineView1->setVisible(true);
- webEngineView2->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html")));
+ webEngineView2->setUrl(urlFromTestPath("html/basic_page.html"));
QVERIFY(waitForLoadSucceeded(webEngineView2));
window2->show();
webEngineView2->setVisible(true);
@@ -291,17 +305,32 @@ void tst_QQuickWebEngineView::multipleWebEngineViews()
webEngineView2->setParentItem(m_window->contentItem());
webEngineView1->setSize(QSizeF(300, 400));
- webEngineView1->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/scroll.html")));
+ webEngineView1->setUrl(urlFromTestPath("html/scroll.html"));
QVERIFY(waitForLoadSucceeded(webEngineView1.data()));
webEngineView1->setVisible(true);
webEngineView2->setSize(QSizeF(300, 400));
- webEngineView2->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page.html")));
+ webEngineView2->setUrl(urlFromTestPath("html/basic_page.html"));
QVERIFY(waitForLoadSucceeded(webEngineView2.data()));
webEngineView2->setVisible(true);
QTest::qWait(200);
}
+QImage tryToGrabWindowUntil(QQuickWindow *window, std::function<bool(const QImage &)> checkImage,
+ int timeout = 5000)
+{
+ QImage grabbed;
+ QElapsedTimer t;
+ t.start();
+ do {
+ QTest::qWait(200);
+ grabbed = window->grabWindow();
+ if (checkImage(grabbed))
+ break;
+ } while (!t.hasExpired(timeout));
+ return grabbed;
+}
+
void tst_QQuickWebEngineView::basicRenderingSanity()
{
showWebEngineView();
@@ -311,9 +340,12 @@ void tst_QQuickWebEngineView::basicRenderingSanity()
// This should not crash.
webEngineView()->setVisible(true);
- QTest::qWait(200);
- QImage grabbedWindow = m_window->grabWindow();
+
QRgb testColor = qRgba(0, 0xff, 0, 0xff);
+ const QImage grabbedWindow = tryToGrabWindowUntil(m_window.data(),
+ [testColor] (const QImage &image) {
+ return image.pixel(10, 10) == testColor;
+ });
QVERIFY(grabbedWindow.pixel(10, 10) == testColor);
QVERIFY(grabbedWindow.pixel(100, 10) == testColor);
QVERIFY(grabbedWindow.pixel(10, 100) == testColor);
@@ -325,22 +357,20 @@ void tst_QQuickWebEngineView::titleUpdate()
QSignalSpy titleSpy(webEngineView(), SIGNAL(titleChanged()));
// Load page with no title
- webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/basic_page2.html")));
+ webEngineView()->setUrl(urlFromTestPath("html/basic_page2.html"));
QVERIFY(waitForLoadSucceeded(webEngineView()));
QCOMPARE(titleSpy.size(), 1);
titleSpy.clear();
// No titleChanged signal for failed load
- webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/file_that_does_not_exist.html")));
+ webEngineView()->setUrl(urlFromTestPath("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 +378,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>");
@@ -362,12 +389,28 @@ void tst_QQuickWebEngineView::transparentWebEngineViews()
webEngineView1->setVisible(true);
webEngineView2->setSize(QSizeF(300, 400));
- webEngineView2->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")));
+ webEngineView2->setUrl(urlFromTestPath("/html/basic_page.html"));
QVERIFY(waitForLoadSucceeded(webEngineView2.data()));
- 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.
+ const QImage grabbedWindow = tryToGrabWindowUntil(m_window.data(), [] (const QImage &image) {
+ return image.pixelColor(0, 0) == QColor(Qt::red);
+ });
+
+ 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()
@@ -376,7 +419,7 @@ void tst_QQuickWebEngineView::inputMethod()
QSKIP("QQUICKWEBENGINEVIEW_ITEMACCEPTSINPUTMETHOD");
#else
QQuickWebEngineView *view = webEngineView();
- view->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/inputmethod.html")));
+ view->setUrl(urlFromTestPath("html/inputmethod.html"));
QVERIFY(waitForLoadSucceeded(view));
QVERIFY(!view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
@@ -394,7 +437,7 @@ void tst_QQuickWebEngineView::inputMethodHints()
#else
QQuickWebEngineView *view = webEngineView();
- view->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/inputmethod.html")));
+ view->setUrl(urlFromTestPath("html/inputmethod.html"));
QVERIFY(waitForLoadSucceeded(view));
// Setting focus on an input element results in an element in its shadow tree becoming the focus node.
diff --git a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
index 5d15537b3..eacd1f87e 100644
--- a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
+++ b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
@@ -52,12 +52,19 @@
class TestView : public QQuickView {
Q_OBJECT
public:
+ TestView()
+ {
+ connect(this, &TestView::_q_exposeChanged, this, &TestView::exposeChanged,
+ Qt::QueuedConnection);
+ }
+
virtual void exposeEvent(QExposeEvent *e) Q_DECL_OVERRIDE {
QQuickView::exposeEvent(e);
- emit exposeChanged();
+ emit _q_exposeChanged();
}
Q_SIGNALS:
+ void _q_exposeChanged();
void exposeChanged();
};
@@ -154,13 +161,13 @@ void tst_QQuickWebEngineViewGraphics::showHideShow()
setHtml(greenSquare);
QSignalSpy exposeSpy(m_view.data(), SIGNAL(exposeChanged()));
m_view->show();
- QVERIFY(exposeSpy.wait(500));
+ QVERIFY(exposeSpy.wait());
QCOMPARE(m_view->grabWindow(), get150x150GreenReferenceImage());
m_view->hide();
- QVERIFY(exposeSpy.wait(500));
+ QVERIFY(exposeSpy.wait());
m_view->show();
- QVERIFY(exposeSpy.wait(500));
+ QVERIFY(exposeSpy.wait());
QCOMPARE(m_view->grabWindow(), get150x150GreenReferenceImage());
}
@@ -184,7 +191,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/quick/quick.pro b/tests/auto/quick/quick.pro
index 71bc61b9e..33821e20b 100644
--- a/tests/auto/quick/quick.pro
+++ b/tests/auto/quick/quick.pro
@@ -3,6 +3,7 @@ TEMPLATE = subdirs
SUBDIRS += \
inspectorserver \
publicapi \
- qmltests \
qquickwebengineview \
qquickwebengineviewgraphics
+
+isQMLTestSupportApiEnabled(): SUBDIRS += qmltests
diff --git a/tests/auto/widgets/positionplugin/plugin.cpp b/tests/auto/widgets/positionplugin/plugin.cpp
new file mode 100644
index 000000000..74d30469d
--- /dev/null
+++ b/tests/auto/widgets/positionplugin/plugin.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtPositioning/qgeopositioninfosource.h>
+#include <QtPositioning/qgeopositioninfosourcefactory.h>
+#include <QObject>
+#include <QtPlugin>
+
+class DummySource : public QGeoPositionInfoSource
+{
+ Q_OBJECT
+
+public:
+ DummySource(QObject *parent=0);
+
+ void startUpdates() {}
+ void stopUpdates() {}
+ void requestUpdate(int) {}
+
+ QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const;
+ PositioningMethods supportedPositioningMethods() const;
+
+ int minimumUpdateInterval() const;
+ Error error() const;
+};
+
+DummySource::DummySource(QObject *parent) :
+ QGeoPositionInfoSource(parent)
+{
+}
+
+QGeoPositionInfoSource::Error DummySource::error() const
+{
+ return QGeoPositionInfoSource::NoError;
+}
+
+int DummySource::minimumUpdateInterval() const
+{
+ return 1000;
+}
+
+QGeoPositionInfo DummySource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
+{
+ Q_UNUSED(fromSatellitePositioningMethodsOnly);
+ return QGeoPositionInfo(QGeoCoordinate(54.186824, 12.087262), QDateTime::currentDateTime());
+}
+
+QGeoPositionInfoSource::PositioningMethods DummySource::supportedPositioningMethods() const
+{
+ return QGeoPositionInfoSource::AllPositioningMethods;
+}
+
+
+class QGeoPositionInfoSourceFactoryTest : public QObject, public QGeoPositionInfoSourceFactory
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/5.0"
+ FILE "plugin.json")
+ Q_INTERFACES(QGeoPositionInfoSourceFactory)
+
+public:
+ QGeoPositionInfoSource *positionInfoSource(QObject *parent);
+ QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent);
+ QGeoAreaMonitorSource *areaMonitor(QObject *parent);
+};
+
+QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryTest::positionInfoSource(QObject *parent)
+{
+ return new DummySource(parent);
+}
+
+QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryTest::satelliteInfoSource(QObject *)
+{
+ return 0;
+}
+
+QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryTest::areaMonitor(QObject* )
+{
+ return 0;
+}
+
+#include "plugin.moc"
diff --git a/tests/auto/widgets/positionplugin/plugin.json b/tests/auto/widgets/positionplugin/plugin.json
new file mode 100644
index 000000000..68acaded3
--- /dev/null
+++ b/tests/auto/widgets/positionplugin/plugin.json
@@ -0,0 +1,9 @@
+{
+ "Keys": ["test.source"],
+ "Provider": "test.source",
+ "Position": true,
+ "Satellite": false,
+ "Monitor": false,
+ "Priority": 0,
+ "Testable": true
+}
diff --git a/tests/auto/widgets/positionplugin/positionplugin.pro b/tests/auto/widgets/positionplugin/positionplugin.pro
new file mode 100644
index 000000000..bca3e5756
--- /dev/null
+++ b/tests/auto/widgets/positionplugin/positionplugin.pro
@@ -0,0 +1,12 @@
+TARGET = qtwebengine_positioning_testplugin
+QT += positioning
+
+PLUGIN_TYPE = position
+PLUGIN_CLASS_NAME = TestPositionPlugin
+PLUGIN_EXTENDS = -
+load(qt_plugin)
+
+SOURCES += plugin.cpp
+
+OTHER_FILES += \
+ plugin.json
diff --git a/tests/auto/widgets/qwebengineaccessibility/BLACKLIST b/tests/auto/widgets/qwebengineaccessibility/BLACKLIST
new file mode 100644
index 000000000..0450f8c1c
--- /dev/null
+++ b/tests/auto/widgets/qwebengineaccessibility/BLACKLIST
@@ -0,0 +1,6 @@
+[hierarchy]
+windows
+[text]
+windows
+[value]
+windows
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/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST
new file mode 100644
index 000000000..91858f299
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/BLACKLIST
@@ -0,0 +1,5 @@
+[geolocationRequestJS]
+*
+
+[macCopyUnicodeToClipboard]
+osx
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..8fd71c701 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()
@@ -231,6 +288,15 @@ void tst_QWebEnginePage::cleanupFiles()
void tst_QWebEnginePage::initTestCase()
{
cleanupFiles(); // In case there are old files from previous runs
+
+ // Set custom path since the CI doesn't install test plugins.
+ // Stolen from qtlocation/tests/auto/positionplugintest.
+ QString searchPath = QCoreApplication::applicationDirPath();
+#ifdef Q_OS_WIN
+ searchPath += QStringLiteral("/..");
+#endif
+ searchPath += QStringLiteral("/../../../plugins");
+ QCoreApplication::addLibraryPath(searchPath);
}
void tst_QWebEnginePage::cleanupTestCase()
@@ -278,7 +344,6 @@ void tst_QWebEnginePage::acceptNavigationRequest()
m_view->setPage(0);
}
-#if defined(QWEBENGINEPAGE_SETFEATUREPERMISSION)
class JSTestPage : public QWebEnginePage
{
Q_OBJECT
@@ -291,12 +356,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 +373,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 +387,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 +1238,10 @@ public:
int isSelectionCollapsed() {
return evaluateJavaScriptSync(this, "window.getSelection().getRangeAt(0).collapsed").toBool();
}
+ bool hasSelection()
+ {
+ return !selectedText().isEmpty();
+ }
};
void tst_QWebEnginePage::cursorMovements()
@@ -1380,17 +1446,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 +1486,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 +1501,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 +1545,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 +1693,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 +2765,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 +2798,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 +2915,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 +3014,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 +3037,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());
@@ -3570,16 +3479,16 @@ void tst_QWebEnginePage::getUserMediaRequest()
QVERIFY(evaluateJavaScriptSync(page, QStringLiteral("!!navigator.webkitGetUserMedia")).toBool());
evaluateJavaScriptSync(page, QStringLiteral("navigator.webkitGetUserMedia({audio: true}, function() {}, function(){})"));
- QTRY_VERIFY_WITH_TIMEOUT(page->gotFeatureRequest(QWebEnginePage::MediaAudioCapture), 100);
+ QTRY_VERIFY(page->gotFeatureRequest(QWebEnginePage::MediaAudioCapture));
// Might end up failing due to the lack of physical media devices deeper in the content layer, so the JS callback is not guaranteed to be called,
// but at least we go through that code path, potentially uncovering failing assertions.
page->acceptPendingRequest();
page->runJavaScript(QStringLiteral("errorCallbackCalled = false;"));
evaluateJavaScriptSync(page, QStringLiteral("navigator.webkitGetUserMedia({audio: true, video: true}, function() {}, function(){errorCallbackCalled = true;})"));
- QTRY_VERIFY_WITH_TIMEOUT(page->gotFeatureRequest(QWebEnginePage::MediaAudioVideoCapture), 100);
+ QTRY_VERIFY(page->gotFeatureRequest(QWebEnginePage::MediaAudioVideoCapture));
page->rejectPendingRequest(); // Should always end up calling the error callback in JS.
- QTRY_VERIFY_WITH_TIMEOUT(evaluateJavaScriptSync(page, QStringLiteral("errorCallbackCalled;")).toBool(), 100);
+ QTRY_VERIFY(evaluateJavaScriptSync(page, QStringLiteral("errorCallbackCalled;")).toBool());
delete page;
}
@@ -3674,41 +3583,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 +3717,1366 @@ 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](QWebEngineFullScreenRequest request) {
+ if (acceptRequest) request.accept(); else request.reject();
+ });
+
+ QTest::keyPress(qApp->focusWindow(), Qt::Key_Space);
+ QTRY_VERIFY(evaluateJavaScriptSync(page, "document.webkitIsFullScreen").toBool());
+ 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);
+
+ // setUrl(dataUrl3) might override the pending load for dataUrl2. Or not.
+ QTRY_VERIFY(loadFinishedSpy.count() >= 2);
+ QTRY_VERIFY(loadFinishedSpy.count() <= 3);
+
+ // setUrl(dataUrl3) might stop Chromium from adding a navigation entry for dataUrl2,
+ // depending on whether the load of dataUrl2 could be completed in time.
+ QVERIFY(view.history()->count() >= 2);
+ QVERIFY(view.history()->count() <= 3);
+
+ 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)));
+
+ 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)));
+ 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)));
+ 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()));
+ 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/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 09929d33f..0ad460634 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -35,7 +35,11 @@
****************************************************************************/
#include "../util.h"
+#include <QtCore/qbuffer.h>
#include <QtTest/QtTest>
+#include <QtWebEngineCore/qwebengineurlrequestjob.h>
+#include <QtWebEngineCore/qwebengineurlschemehandler.h>
+#include <QtWebEngineWidgets/qwebengineview.h>
#include <qwebengineprofile.h>
class tst_QWebEngineProfile : public QObject
@@ -45,6 +49,8 @@ class tst_QWebEngineProfile : public QObject
private Q_SLOTS:
void defaultProfile();
void profileConstructors();
+ void urlSchemeHandlers();
+ void urlSchemeHandlerFailRequest();
};
void tst_QWebEngineProfile::defaultProfile()
@@ -72,5 +78,97 @@ void tst_QWebEngineProfile::profileConstructors()
}
+class RedirectingUrlSchemeHandler : public QWebEngineUrlSchemeHandler
+{
+public:
+ void requestStarted(QWebEngineUrlRequestJob *job)
+ {
+ job->redirect(QUrl(QStringLiteral("data:text/plain;charset=utf-8,")
+ + job->requestUrl().fileName()));
+ }
+};
+
+class ReplyingUrlSchemeHandler : public QWebEngineUrlSchemeHandler
+{
+ QBuffer m_buffer;
+ QByteArray m_bufferData;
+public:
+ ReplyingUrlSchemeHandler(QObject *parent = nullptr)
+ : QWebEngineUrlSchemeHandler(parent)
+ {
+ m_buffer.setBuffer(&m_bufferData);
+ }
+
+ void requestStarted(QWebEngineUrlRequestJob *job)
+ {
+ m_bufferData = job->requestUrl().toString().toUtf8();
+ job->reply("text/plain;charset=utf-8", &m_buffer);
+ }
+};
+
+void tst_QWebEngineProfile::urlSchemeHandlers()
+{
+ RedirectingUrlSchemeHandler mailtoHandler;
+ QWebEngineProfile profile(QStringLiteral("urlSchemeHandlers"));
+ profile.installUrlSchemeHandler("mailto", &mailtoHandler);
+ QWebEngineView view;
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ view.setPage(new QWebEnginePage(&profile, &view));
+ QString emailAddress = QStringLiteral("egon@olsen-banden.dk");
+ view.load(QUrl(QStringLiteral("mailto:") + emailAddress));
+ QVERIFY(loadFinishedSpy.wait());
+ QCOMPARE(toPlainTextSync(view.page()), emailAddress);
+
+ // Install a gopher handler after the view has been fully initialized.
+ ReplyingUrlSchemeHandler gopherHandler;
+ profile.installUrlSchemeHandler("gopher", &gopherHandler);
+ QUrl url = QUrl(QStringLiteral("gopher://olsen-banden.dk/benny"));
+ view.load(url);
+ QVERIFY(loadFinishedSpy.wait());
+ QCOMPARE(toPlainTextSync(view.page()), url.toString());
+
+ // Remove the mailto scheme, and check whether it is not handled anymore.
+ profile.removeUrlScheme("mailto");
+ emailAddress = QStringLiteral("kjeld@olsen-banden.dk");
+ view.load(QUrl(QStringLiteral("mailto:") + emailAddress));
+ QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(toPlainTextSync(view.page()) != emailAddress);
+
+ // Check if gopher is still working after removing mailto.
+ url = QUrl(QStringLiteral("gopher://olsen-banden.dk/yvonne"));
+ view.load(url);
+ QVERIFY(loadFinishedSpy.wait());
+ QCOMPARE(toPlainTextSync(view.page()), url.toString());
+
+ // Does removeAll work?
+ profile.removeAllUrlSchemeHandlers();
+ url = QUrl(QStringLiteral("gopher://olsen-banden.dk/harry"));
+ view.load(url);
+ QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(toPlainTextSync(view.page()) != url.toString());
+}
+
+class FailingUrlSchemeHandler : public QWebEngineUrlSchemeHandler
+{
+public:
+ void requestStarted(QWebEngineUrlRequestJob *job) override
+ {
+ job->fail(QWebEngineUrlRequestJob::RequestFailed);
+ }
+};
+
+void tst_QWebEngineProfile::urlSchemeHandlerFailRequest()
+{
+ FailingUrlSchemeHandler handler;
+ QWebEngineProfile profile;
+ profile.installUrlSchemeHandler("foo", &handler);
+ QWebEngineView view;
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ view.setPage(new QWebEnginePage(&profile, &view));
+ view.load(QUrl(QStringLiteral("foo://bar")));
+ QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(toPlainTextSync(view.page()).isEmpty());
+}
+
QTEST_MAIN(tst_QWebEngineProfile)
#include "tst_qwebengineprofile.moc"
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/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
index b29d8fae6..53762f54c 100644
--- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
@@ -25,18 +25,6 @@
#include <qwebengineview.h>
#include "../util.h"
-//#define DEBUG_SCRIPT_MESSAGES
-#ifdef DEBUG_SCRIPT_MESSAGES
-class WebEnginePage : public QWebEnginePage {
- void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID) {
- qDebug() << level << message << lineNumber << sourceID;
- }
-
-};
-#else
-typedef QWebEnginePage WebEnginePage;
-#endif
-
class tst_QWebEngineScript: public QObject {
Q_OBJECT
@@ -49,10 +37,9 @@ private Q_SLOTS:
};
-
void tst_QWebEngineScript::domEditing()
{
- WebEnginePage page;
+ QWebEnginePage page;
QWebEngineView view;
view.setPage(&page);
QWebEngineScript s;
@@ -88,7 +75,7 @@ void tst_QWebEngineScript::injectionPoint()
s.setSourceCode("var foo = \"foobar\";");
s.setInjectionPoint(static_cast<QWebEngineScript::InjectionPoint>(injectionPoint));
s.setWorldId(QWebEngineScript::MainWorld);
- WebEnginePage page;
+ QWebEnginePage page;
page.scripts().insert(s);
page.setHtml(QStringLiteral("<html><head><script> var contents;") + testScript
+ QStringLiteral("document.addEventListener(\"load\", setTimeout(function(event) {\
@@ -96,8 +83,7 @@ void tst_QWebEngineScript::injectionPoint()
}, 550));\
</script></head><body></body></html>"));
waitForSignal(&page, SIGNAL(loadFinished(bool)));
- QTest::qWait(550);
- QCOMPARE(evaluateJavaScriptSync(&page, "document.body.innerText"), QVariant::fromValue(QStringLiteral("SUCCESS")));
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, "document.body.innerText"), QVariant::fromValue(QStringLiteral("SUCCESS")));
}
void tst_QWebEngineScript::injectionPoint_data()
@@ -108,9 +94,10 @@ void tst_QWebEngineScript::injectionPoint_data()
<< QStringLiteral("var contents = (typeof(foo) == \"undefined\")? \"FAILURE\" : \"SUCCESS\";");
QTest::newRow("DocumentReady") << static_cast<int>(QWebEngineScript::DocumentReady)
// use a zero timeout to make sure the user script got a chance to run as the order is undefined.
- << QStringLiteral("document.addEventListener(\"DOMContentLoaded\", setTimeout(function(event) {\
+ << QStringLiteral("document.addEventListener(\"DOMContentLoaded\", function() {\
+ setTimeout(function() {\
contents = (typeof(foo) == \"undefined\")? \"FAILURE\" : \"SUCCESS\";\
- }, 0));");
+ }, 0)});");
QTest::newRow("Deferred") << static_cast<int>(QWebEngineScript::Deferred)
<< QStringLiteral("document.addEventListener(\"load\", setTimeout(function(event) {\
contents = (typeof(foo) == \"undefined\")? \"FAILURE\" : \"SUCCESS\";\
@@ -119,7 +106,7 @@ void tst_QWebEngineScript::injectionPoint_data()
void tst_QWebEngineScript::scriptWorld()
{
- WebEnginePage page;
+ QWebEnginePage page;
QWebEngineScript script;
script.setInjectionPoint(QWebEngineScript::DocumentCreation);
script.setWorldId(QWebEngineScript::MainWorld);
@@ -138,7 +125,7 @@ void tst_QWebEngineScript::scriptWorld()
void tst_QWebEngineScript::scriptModifications()
{
- WebEnginePage page;
+ QWebEnginePage page;
QWebEngineScript script;
script.setName(QStringLiteral("String1"));
script.setInjectionPoint(QWebEngineScript::DocumentCreation);
diff --git a/tests/auto/widgets/qwebenginesettings/qwebenginesettings.pro b/tests/auto/widgets/qwebenginesettings/qwebenginesettings.pro
new file mode 100644
index 000000000..70786e70f
--- /dev/null
+++ b/tests/auto/widgets/qwebenginesettings/qwebenginesettings.pro
@@ -0,0 +1,2 @@
+include(../tests.pri)
+QT *= core-private gui-private
diff --git a/tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp b/tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp
new file mode 100644
index 000000000..0f6a6062e
--- /dev/null
+++ b/tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2015 The Qt Company Ltd.
+
+ 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 <qwebengineprofile.h>
+#include <qwebenginesettings.h>
+
+class tst_QWebEngineSettings: public QObject {
+ Q_OBJECT
+
+private Q_SLOTS:
+ void resetAttributes();
+};
+
+void tst_QWebEngineSettings::resetAttributes()
+{
+ QWebEngineProfile profile;
+ QWebEngineSettings *settings = profile.settings();
+
+ // Attribute
+ bool defaultValue = settings->testAttribute(QWebEngineSettings::FullScreenSupportEnabled);
+ settings->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, !defaultValue);
+ QCOMPARE(!defaultValue, settings->testAttribute(QWebEngineSettings::FullScreenSupportEnabled));
+ settings->resetAttribute(QWebEngineSettings::FullScreenSupportEnabled);
+ QCOMPARE(defaultValue, settings->testAttribute(QWebEngineSettings::FullScreenSupportEnabled));
+
+ // Font family
+ QString defaultFamily = settings->fontFamily(QWebEngineSettings::StandardFont);
+ QString newFontFamily("PugDog");
+ settings->setFontFamily(QWebEngineSettings::StandardFont, newFontFamily);
+ QCOMPARE(newFontFamily, settings->fontFamily(QWebEngineSettings::StandardFont));
+ settings->resetFontFamily(QWebEngineSettings::StandardFont);
+ QCOMPARE(defaultFamily, settings->fontFamily(QWebEngineSettings::StandardFont));
+
+ // Font size
+ int defaultSize = settings->fontSize(QWebEngineSettings::MinimumFontSize);
+ int newSize = defaultSize + 10;
+ settings->setFontSize(QWebEngineSettings::MinimumFontSize, newSize);
+ QCOMPARE(newSize, settings->fontSize(QWebEngineSettings::MinimumFontSize));
+ settings->resetFontSize(QWebEngineSettings::MinimumFontSize);
+ QCOMPARE(defaultSize, settings->fontSize(QWebEngineSettings::MinimumFontSize));
+}
+
+QTEST_MAIN(tst_QWebEngineSettings)
+
+#include "tst_qwebenginesettings.moc"
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..8a62ce2a6 100644
--- a/tests/auto/widgets/tests.pri
+++ b/tests/auto/widgets/tests.pri
@@ -1,8 +1,6 @@
TEMPLATE = app
-# FIXME: Re-enable once we want to run tests on the CI
-# CONFIG += testcase
-
+CONFIG += testcase
CONFIG += c++11
VPATH += $$_PRO_FILE_PWD_
@@ -11,6 +9,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..986d5bbee 100644
--- a/tests/auto/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets.pro
@@ -1,14 +1,17 @@
TEMPLATE = subdirs
-CONFIG += ordered
-
SUBDIRS += \
qwebengineaccessibility \
- qwebengineframe \
qwebenginepage \
qwebenginehistory \
qwebenginehistoryinterface \
qwebengineinspector \
qwebengineprofile \
qwebenginescript \
+ qwebenginesettings \
qwebengineview
+
+qtHaveModule(positioning) {
+ SUBDIRS += positionplugin
+ qwebenginepage.depends = positionplugin
+}
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..cf583c60d 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,7 @@ ApplicationWindow {
property alias autoLoadImages: loadImages.checked;
property alias javaScriptEnabled: javaScriptEnabled.checked;
property alias errorPageEnabled: errorPageEnabled.checked;
+ property alias pluginsEnabled: pluginsEnabled.checked;
}
// Make sure the Qt.WindowFullscreenButtonHint is set on OS X.
@@ -245,6 +248,12 @@ ApplicationWindow {
checked: true
}
MenuItem {
+ id: pluginsEnabled
+ text: "Plugins On"
+ checkable: true
+ checked: true
+ }
+ MenuItem {
id: offTheRecordEnabled
text: "Off The Record"
checkable: true
@@ -347,6 +356,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 +391,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 +498,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..85a02ab34 100644
--- a/tests/quicktestbrowser/main.cpp
+++ b/tests/quicktestbrowser/main.cpp
@@ -50,7 +50,10 @@ typedef QGuiApplication Application;
#endif
#include <QtQml/QQmlApplicationEngine>
#include <QtQml/QQmlContext>
+#include <QtQml/QQmlComponent>
#include <QtWebEngine/qtwebengineglobal.h>
+#include <QtWebEngine/QQuickWebEngineProfile>
+#include <QtWebEngineCore/qwebenginecookiestore.h>
static QUrl startupUrl()
{
@@ -80,7 +83,17 @@ 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();
+
+ QQuickWebEngineProfile *profile = new QQuickWebEngineProfile(rootObject);
+
+ const QMetaObject *rootMeta = rootObject->metaObject();
+ int 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..c8e849973 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
@@ -128,6 +133,14 @@ if __name__ == '__main__':
if sys.platform not in ('darwin',) or 'GYP_CROSSCOMPILE' in os.environ:
args.append('--no-circular-check')
+ # libtool on Mac warns about duplicate basenames in static libraries, so
+ # they're disallowed in general by gyp. We are lax on this point, so disable
+ # this check other than on Mac. GN does not use static libraries as heavily,
+ # so over time this restriction will mostly go away anyway, even on Mac.
+ # https://code.google.com/p/gyp/issues/detail?id=384
+ if sys.platform != 'darwin':
+ args.append('--no-duplicate-basename-check')
+
args.extend(['-D', 'webkit_src_dir=' + chrome_src + '/third_party/WebKit'])
# the top_level source directory is the first common ancestor of our module and the chromium source tree for the build to be sane.
# commonprefix works on a character basis, so it might return a phony common prefix (not the common parent directory we expect),
@@ -140,12 +153,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..4be9fac20 100644
--- a/tools/qmake/mkspecs/features/configure.prf
+++ b/tools/qmake/mkspecs/features/configure.prf
@@ -19,14 +19,93 @@ 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}")
+
+ !cross_compile {
+ 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 40532f709..2447d8372 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..a4fafe83e 100644
--- a/tools/scripts/version_resolver.py
+++ b/tools/scripts/version_resolver.py
@@ -51,9 +51,9 @@ import json
import urllib2
import git_submodule as GitSubmodule
-chromium_version = '40.0.2214.115'
-chromium_branch = '2214'
-ninja_version = 'v1.5.3'
+chromium_version = '45.0.2454.101'
+chromium_branch = '2454'
+ninja_version = 'v1.6.0'
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)